> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onsomble.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API overview

> Create an API key and connect your first integration to Onsomble.

Use the Onsomble API to pull discoverability results into your own reporting tools or start a Scan from another system. The API is served at `https://api.onsomble.ai/v1`.

## Before you begin

Your account needs a plan that includes API access. If it does not, requests return a `feature_not_in_plan` error with a link to the available plans.

## Create an API key

1. In Onsomble, open **Settings → Account**.
2. In **API Keys**, select **Create key**.
3. Give the key a name that identifies the integration.
4. Agency accounts can choose **Account** scope or restrict the key to one **Client**. Business accounts use account scope.
5. Copy the key when it is shown, then store it in your integration's secret manager. Onsomble does not show the full key again.

<Warning>
  Treat an API key like a password. Do not put it in browser code, source
  control, logs, or a client-side application.
</Warning>

## Make your first call

List the Sites visible to the key. Replace `ons_your_api_key` with the key you copied.

```bash theme={null}
curl --request GET \
  --url https://api.onsomble.ai/v1/sites \
  --header "Authorization: Bearer ons_your_api_key"
```

The response contains Sites in newest-first order. Use `nextCursor` as the `cursor` query parameter on the next request until it is `null`.

```json theme={null}
{
  "data": [
    {
      "id": "07d8f5e2-b122-4ae7-8a9b-cd6cd8bea3b7",
      "name": "Acme Retail",
      "url": "https://acme.example",
      "clientId": null,
      "createdAt": "2026-07-01T09:30:00.000Z",
      "updatedAt": "2026-07-10T17:12:00.000Z"
    }
  ],
  "nextCursor": null
}
```

## Authenticate requests

Send the key with every request using the HTTP `Authorization` header:

```text theme={null}
Authorization: Bearer ons_your_api_key
```

An account-scoped key can access the account's data. A client-scoped key can access only the selected Client and its Sites. Revoking a key immediately prevents it from being used.

## Filter reports by platform

Report endpoints use stable platform IDs. Each ID tells you which AI product answered and whether Onsomble collected that answer from the web or an API. Provider implementation details stay internal.

For example, `chatgpt_app` means ChatGPT on the web, while `chatgpt_api` means ChatGPT through its API. Repeat the `platform` query parameter to include more than one:

```bash theme={null}
curl --request GET \
  --url "https://api.onsomble.ai/v1/sites/{siteId}/reports/prompt-results?platform=chatgpt_app&platform=chatgpt_api" \
  --header "Authorization: Bearer ons_your_api_key"
```

Each Prompt Result names the platform directly:

```json theme={null}
{
  "platform": {
    "id": "chatgpt_app",
    "name": "ChatGPT",
    "method": "web"
  }
}
```

The API reference lists every accepted platform ID.

## Work within rate limits

Rate limits apply to the account, not to an individual key. Keys belonging to the same account share one request bucket. Every response includes these headers:

| Header                  | Meaning                                         |
| ----------------------- | ----------------------------------------------- |
| `X-RateLimit-Limit`     | Requests allowed in the current window.         |
| `X-RateLimit-Remaining` | Requests still available in the current window. |
| `X-RateLimit-Reset`     | Unix timestamp when the current window resets.  |

When a request returns `429`, wait until `X-RateLimit-Reset` before retrying. Do not create extra keys to increase throughput: they share the same account limit.

## Handle errors by code

Every non-success response has a stable JSON envelope with `statusCode`, `code`, and `message`. Your integration should branch on `code`, not on the message text.

```json theme={null}
{
  "statusCode": 401,
  "code": "invalid_api_key",
  "message": "This API key is not recognised."
}
```

| Code                       | Meaning                                                                           |
| -------------------------- | --------------------------------------------------------------------------------- |
| `missing_api_key`          | The request did not contain a Bearer API key.                                     |
| `invalid_api_key`          | The key is unknown or malformed.                                                  |
| `revoked_api_key`          | The key has been revoked.                                                         |
| `expired_api_key`          | The key has expired.                                                              |
| `feature_not_in_plan`      | The account's plan does not include API access. The response includes `plansUrl`. |
| `validation_failed`        | A path or query parameter is invalid.                                             |
| `not_found`                | The requested resource does not exist or is not visible to the key.               |
| `forbidden`                | The request is not permitted for the key.                                         |
| `scan_allowance_exhausted` | The account cannot start another Scan under its current allowance.                |
| `scan_not_ready`           | The requested Scan data is not available yet.                                     |
| `rate_limited`             | The account has used the current request window.                                  |
| `internal_error`           | Onsomble could not complete the request. Retry later.                             |

## Explore the reference

Open Sites, Clients, Scans, or Reports in the sidebar for every endpoint, query parameter, and response field. Check the [API changelog](/developers/changelog) before moving an integration to a new major version.
