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

# API conventions

> Reference for the rules that every SiteGPT API v2 endpoint follows: base URL, response envelope, pagination, errors, and deletes.

These rules apply to every endpoint in SiteGPT API v2.

## Base URL

```text theme={null}
https://sitegpt.ai/api/v2
```

* Send and receive JSON. Set `Content-Type: application/json` on requests with a body.
* Send your API token in the `Authorization: Bearer` header. See [API v2 authentication](/docs/api-reference/v2/authentication).
* `GET /api/v2/health` needs no token. Use it to check that the API is reachable.
* The OpenAPI document is at `https://sitegpt.ai/api/v2/openapi.json`.

## Response envelope

Every response uses the same envelope.

Success:

```json theme={null}
{
  "ok": true,
  "data": { },
  "meta": {
    "requestId": "YOUR_REQUEST_ID"
  }
}
```

Error:

```json theme={null}
{
  "ok": false,
  "error": {
    "code": "TOKEN_SCOPE_NOT_ALLOWED",
    "message": "Token does not have the required scope",
    "hint": "..."
  },
  "meta": {
    "requestId": "YOUR_REQUEST_ID"
  }
}
```

| Field             | Description                                                                                                                                                                  |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ok`              | `true` on success, `false` on error.                                                                                                                                         |
| `data`            | The result. Its shape depends on the endpoint.                                                                                                                               |
| `meta.requestId`  | The ID of the request. Give it to support when you report a problem. If you send an `x-request-id` header with 1 to 64 letters, digits, `_`, or `-`, SiteGPT uses its value. |
| `meta.warnings`   | Optional. Messages about the request that did not stop it, for example a deprecated credential.                                                                              |
| `meta.nextCursor` | On list endpoints. The cursor for the next page. See [Pagination](#pagination).                                                                                              |
| `error.code`      | A stable code in capital letters. Use it in your code.                                                                                                                       |
| `error.message`   | A readable message. It can change. Do not match on it.                                                                                                                       |
| `error.hint`      | Optional. A suggested next step.                                                                                                                                             |
| `error.details`   | Optional. More detail, for example the fields that failed validation, or `requiredScopes` for `TOKEN_SCOPE_NOT_ALLOWED`.                                                     |

<Note>
  The OpenAPI error schema does not list `error.hint`, but the API sends it. Allow extra fields in your error parser.
</Note>

## Pagination

List endpoints that can return many items use cursor pagination.

| Query parameter | Description                                                         |
| --------------- | ------------------------------------------------------------------- |
| `limit`         | The maximum number of items to return. At least `1`.                |
| `cursor`        | The cursor from the previous page. Leave it out for the first page. |

The response has the cursor in two places:

* `meta.nextCursor`
* `data.pagination`, which has `limit`, `hasNextPage`, and `nextCursor`

`nextCursor` is `null` on the last page.

```bash theme={null}
# First page
curl "https://sitegpt.ai/api/v2/chatbots/YOUR_CHATBOT_ID/conversations?limit=50" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Next page
curl "https://sitegpt.ai/api/v2/chatbots/YOUR_CHATBOT_ID/conversations?limit=50&cursor=YOUR_NEXT_CURSOR" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

These endpoints use cursor pagination:

| Endpoint                                                                                                                | Default `limit` | Maximum `limit` |
| ----------------------------------------------------------------------------------------------------------------------- | --------------- | --------------- |
| Conversations: `GET /chatbots/{chatbotId}/conversations`                                                                | 50              | 100             |
| Messages in a conversation: `GET /chatbots/{chatbotId}/conversations/{threadId}/messages`                               | 100             | 500             |
| Leads: `GET /chatbots/{chatbotId}/leads`                                                                                | 50              | 100             |
| Content documents: `GET /chatbots/{chatbotId}/documents`                                                                | 50              | 100             |
| Sync jobs: `GET /chatbots/{chatbotId}/ingest-jobs`                                                                      | 50              | 100             |
| Documents of a connected source: `GET /chatbots/{chatbotId}/knowledge/sources/{connectionId}/documents`                 | 50              | 100             |
| Confluence spaces and pages: `GET /chatbots/{chatbotId}/knowledge/sources/confluence/spaces` and `.../confluence/pages` | 20              | 100             |

A `limit` outside the allowed range returns `400 VALIDATION_FAILED`.

## Errors

The HTTP status tells you the kind of error. `error.code` tells you the exact cause.

| Status | Meaning                                                                                      | Common codes                                                                                                                                                    |
| ------ | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | The request is not valid.                                                                    | `INVALID_JSON`, `VALIDATION_FAILED`, `CONFIRMATION_REQUIRED`                                                                                                    |
| 401    | The request has no valid credential.                                                         | `AUTHORIZATION_HEADER_REQUIRED`, `AUTHORIZATION_HEADER_NOT_VALID`, `TOKEN_NOT_VALID`                                                                            |
| 403    | The credential cannot do this, or your plan does not include it.                             | `TOKEN_SCOPE_NOT_ALLOWED`, `PLAN_UPGRADE_REQUIRED`, `HUMAN_TAKEOVER`, `CHATBOT_LIMIT_REACHED`, `ACCOUNT_INACTIVE`, `ANALYTICS_LOCKED`, `WEBHOOKS_NOT_AVAILABLE` |
| 404    | The item does not exist, or the token cannot access it. Unknown API paths also return `404`. | `CHATBOT_NOT_FOUND`, `NOT_FOUND`                                                                                                                                |
| 405    | The endpoint does not support this HTTP method.                                              | `METHOD_NOT_ALLOWED`                                                                                                                                            |
| 409    | The conversation state does not allow the action.                                            | `CONVERSATION_CLOSED`                                                                                                                                           |
| 429    | A plan quota is used up.                                                                     | `CHATBOT_PAGES_LIMIT_REACHED`                                                                                                                                   |
| 500    | An error on the SiteGPT side.                                                                | `INTERNAL_SERVER_ERROR`                                                                                                                                         |

A `401` response includes a `WWW-Authenticate` header that points to the OAuth metadata at `https://sitegpt.ai/.well-known/oauth-protected-resource/api/v2`.

Some errors come with a `hint`. For example, `CHATBOT_LIMIT_REACHED` and `CHATBOT_PAGES_LIMIT_REACHED` suggest how to free space or where to see plans.

## Conversation state conflicts

A conversation can be resolved (closed), or a person on your team can take it over. The API checks these states at the moment it saves your change. If the state changes while your request runs, the new state wins. See [Conversations and handoff](/docs/concepts/conversations-and-handoff).

| Situation                            | Operation                                                        | Result                                                                             |
| ------------------------------------ | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| The conversation is resolved         | Send a message (`POST .../conversations/{threadId}/messages`)    | `409 CONVERSATION_CLOSED`                                                          |
| The conversation is resolved         | Escalate (`POST .../conversations/{threadId}/escalate`)          | `409 CONVERSATION_CLOSED`                                                          |
| The conversation is resolved         | Release to AI (`POST .../conversations/{threadId}/switch-to-ai`) | `409 CONVERSATION_CLOSED`                                                          |
| The conversation is resolved         | Take over (`POST .../conversations/{threadId}/take-over`)        | `409 CONVERSATION_CLOSED`                                                          |
| A person on your team has taken over | Send a message                                                   | Success. SiteGPT saves the visitor's message, but the AI does not answer.          |
| A person on your team has taken over | Escalate                                                         | `403 HUMAN_TAKEOVER`. If the conversation is already escalated, the call succeeds. |
| A person on your team has taken over | Release to AI                                                    | Success. The AI answers the conversation again.                                    |

The OpenAPI document marks each operation that can return `409`. This includes `POST /chatbots/{chatbotId}/messages`, which starts a new conversation.

## Deletes need confirmation

Delete endpoints that remove account or chatbot data need `confirm=true` in the query string. The endpoint pages show a `confirm` parameter where it applies.

Example:

```bash theme={null}
curl -X DELETE "https://sitegpt.ai/api/v2/chatbots/YOUR_CHATBOT_ID/leads/YOUR_LEAD_ID?confirm=true" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Without it, the API returns `400 CONFIRMATION_REQUIRED` and deletes nothing. Bulk deletes also need confirmation. Send `"confirm": true` in the request body of `POST /chatbots/{chatbotId}/documents/delete`, and with the `delete` action of `POST /chatbots/{chatbotId}/conversations/bulk` and `POST /chatbots/{chatbotId}/leads/actions`. The documents endpoint also accepts `confirm=true` in the query string.

## Rate limits and quotas

* The API sends no rate-limit headers, and there is no published per-request rate limit.
* `429` means that a plan quota is used up, for example the pages quota for content. Do not retry a `429` in a loop. Remove content or change your plan. See [Plans and limits](/docs/reference/plans-and-limits).

## Model names

API v2 uses the public model names `gpt-4.1` and `gpt-4.1-mini` in requests and responses.
