# The essentials

This page covers the core concepts you need before building an integration: authentication, response format, and rate limits.

## Base URL

All API requests use this base URL:

```
https://api.forms.app
```

## Authentication

Every request must be authenticated with **exactly one** of the two methods below. Sending both in the same request returns `401 Unauthorized`.

### Option 1: API key

Pass your API key in the `X-Api-Key` header:

```
X-Api-Key: <your_api_key>
```

This is the simplest option for server-to-server integrations. See [Quick start](/guides/quickstart) for how to create a key.

### Option 2: OAuth 2.0 bearer token

Obtain a JWT through the forms.app OAuth 2.0 flow and pass it in the `Authorization` header:

```
Authorization: Bearer <your_token>
```

Use OAuth when your integration acts on behalf of a user through a third-party app.

Use one method per request
Never send both `X-Api-Key` and `Authorization: Bearer` in the same request. The API rejects the call with `401 Unauthorized`.

## Response envelope

All endpoints return a consistent JSON envelope.

### Success (`2xx`)

```json
{
  "success": true,
  "data": { },
  "errors": []
}
```

The `data` field holds the endpoint payload, an array, object, or paginated result depending on the route.

### Error (`4xx` / `5xx`)

```json
{
  "success": false,
  "data": null,
  "errors": [
    {
      "errorCode": 1001,
      "errorMessage": "Unauthorized"
    }
  ]
}
```

Each entry in `errors` includes:

| Field | Description |
|  --- | --- |
| `errorCode` | Machine-readable code identifying the failure |
| `errorMessage` | Human-readable description |


Always check `success` before reading `data`. When `success` is `false`, inspect `errors` for details.

## Common HTTP status codes

| Status | Meaning |
|  --- | --- |
| `200` | Request succeeded |
| `400` | Bad request, check your parameters |
| `401` | Unauthorized, missing or invalid credentials, or both auth methods supplied |
| `404` | Not found, the form does not exist or belongs to another account |
| `429` | Too many requests, rate limit exceeded |
| `500` | Internal server error |


## Rate limiting

Requests are rate-limited per API key or token. When you exceed the limit, the API returns `429 Too Many Requests`.

If you receive a `429`:

1. Wait briefly before retrying.
2. Avoid tight retry loops, space out requests or use exponential backoff.
3. Cache form structure when possible instead of re-fetching on every sync.


## Read-only access

The API provides read-only access to your forms and submissions. You can:

- List forms in your account
- Fetch a form's full structure (questions, design, settings)
- Page through submitted answers


You cannot create, update, or delete forms or submissions through the API.

## What's next?

- [Fetching forms](/guides/tutorials/fetching-forms): list forms and retrieve full structure
- [Fetching submissions](/guides/tutorials/fetching-submissions): page through answers
- [Frequently asked questions](/guides/faq): common integration questions
- [API reference](/apis): full endpoint and schema documentation