> ## 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.

# Authentication

> Reference for SiteGPT API tokens, access levels, scopes, OAuth device login, and the legacy API key.

This page is the one reference for SiteGPT credentials. It covers API tokens for API v2, the SDKs, and the CLI. It also covers OAuth device login and the legacy API key. For MCP connections, see [MCP server](/docs/developers/mcp).

## Credential types

| Credential       | Looks like                                                 | Where you get it                                | Works with                                                     |
| ---------------- | ---------------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------- |
| API token        | `sgpt_...`                                                 | The **Agents** page, or device login            | API v2, TypeScript, Python, and Go SDKs, CLI, local MCP server |
| OAuth connection | Managed by your AI app                                     | Approval in the browser when an AI app connects | Remote MCP server                                              |
| Legacy API key   | A UUID, for example `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` | The **Billing** page                            | Legacy API v0 and v1, widget identity verification             |

Send API tokens and the legacy API key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer YOUR_TOKEN
```

## API tokens

API tokens authenticate API v2 requests. Treat each token as an opaque secret. Do not check for a fixed token format in your code.

API access is available on the Growth plan and above. See [Plans and limits](/docs/reference/plans-and-limits). This applies to API tokens, CLI logins, and MCP. On a lower plan, you cannot create or rotate a token. Requests with an existing token fail with `403 PLAN_UPGRADE_REQUIRED`. If you downgrade, your tokens stop working until you upgrade again. The [SiteGPT iPhone app](/docs/guides/human-support/iphone-app) is not affected.

### Create a token

1. In the top navigation, select **Agents**.
2. In **Create API token**, enter a **Token name**. Name it after the tool that uses it.
3. Choose when the token **Expires**: 30, 90, 180, or 365 days. The default is 90 days.
4. Choose an **Access** level. See [Access levels](#access-levels).
5. Under **Chatbot access**, choose **All accessible chatbots** or **Specific chatbots**.
6. Select **Create token**.
7. Copy the token and store it in a safe place. SiteGPT shows it only once. Then select **I saved this token**.

### Access levels

| Access level  | What the token can do                                                                                                       |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Standard**  | Everything except creating or changing tokens, changing billing, and reading or changing integrations. This is the default. |
| **Read only** | Every read permission. No writes and no deletes.                                                                            |
| **Full**      | Every permission that your dashboard role can give.                                                                         |
| **Custom**    | Only the permissions that you select in a Read, Write, and Delete table.                                                    |

A token never gets more access than you have. SiteGPT gives only the scopes that your dashboard role allows on the chatbots you select. If your role does not allow some permissions, the **Agents** page tells you.

* Billing scopes need an account owner.
* `chatbots:write` for all chatbots needs an account owner.

### Chatbot access

| Option                      | Meaning                                                                           |
| --------------------------- | --------------------------------------------------------------------------------- |
| **All accessible chatbots** | The token follows your role on all chatbots you can access now and in the future. |
| **Specific chatbots**       | The token works only on the chatbots that you select.                             |

Use **Specific chatbots** for tools that work on one chatbot.

### Manage tokens

The **API Tokens** list on the **Agents** page shows each token, its source, its scopes, and its status. The source is **Manual token**, **Device login**, or **Onboarding token**.

* **Rotate** creates a new token value with the same settings. The old value stops working.
* **Revoke** stops the token at once.
* Select **Show revoked** to see revoked tokens. This option shows only when you have revoked tokens.

You can also manage tokens with the API: `GET` and `POST /api/v2/tokens`, `DELETE /api/v2/tokens/{tokenId}`, and `POST /api/v2/tokens/{tokenId}/rotate`. These need the `tokens:read` and `tokens:write` scopes.

### Scopes

A scope allows one kind of action on one area. `read` lets the token view data. `write` lets it create and change data. `delete` lets it delete data.

| Area                  | What it covers                                          | Read                 | Write                 | Delete                 |
| --------------------- | ------------------------------------------------------- | -------------------- | --------------------- | ---------------------- |
| Account profile       | Account details and profile picture                     | `account:read`       | `account:write`       |                        |
| Billing               | Subscription and invoices                               | `billing:read`       | `billing:write`       |                        |
| API tokens            | Create, rotate, list, and revoke tokens                 | `tokens:read`        | `tokens:write`        |                        |
| Chatbots              | Create, edit, and delete chatbots                       | `chatbots:read`      | `chatbots:write`      | `chatbots:delete`      |
| Knowledge             | Content: documents, links, files, text, and source sync | `knowledge:read`     | `knowledge:write`     | `knowledge:delete`     |
| Personas              | Persona presets                                         | `personas:read`      | `personas:write`      | `personas:delete`      |
| Instructions          | Instructions and the active instruction                 | `instructions:read`  | `instructions:write`  | `instructions:delete`  |
| Settings              | Chatbot settings sections                               | `settings:read`      | `settings:write`      |                        |
| Conversation starters | Starter questions shown before the chat                 | `starters:read`      | `starters:write`      | `starters:delete`      |
| Follow-up suggestions | Follow-up buttons and links                             | `followups:read`     | `followups:write`     | `followups:delete`     |
| Conversations         | Conversations, messages, and tags                       | `conversations:read` | `conversations:write` | `conversations:delete` |
| Leads                 | Leads and lead status                                   | `leads:read`         | `leads:write`         | `leads:delete`         |
| Members               | Team members and invites                                | `members:read`       | `members:write`       | `members:delete`       |
| Integrations          | Connected support and automation integrations           | `integrations:read`  | `integrations:write`  |                        |

Each API v2 operation lists the scopes it needs in the [API reference](/docs/api-reference/v2/getting-started). A request with a token that lacks a needed scope fails with `403` and the code `TOKEN_SCOPE_NOT_ALLOWED`.

## OAuth device login

Device login lets a CLI, script, or local AI agent get an API token after you approve it in the browser. You do not paste a token into the tool. `sitegpt login` uses this flow. See [Install and log in](/docs/cli/install-login).

Use the endpoints below only if you build your own tool. Otherwise use `sitegpt login`.

### How it works

1. The tool sends a request to `POST https://sitegpt.ai/oauth/device_authorization`.
2. SiteGPT returns a device code, a login code, and a link.
3. You open the link and sign in. The **Approve device login** page shows the tool name and the access it asks for.
4. You can narrow the access. Under **Grant**, choose **Everything requested**, **Read only** (shown when the request includes read scopes), or **Choose specific**. Then choose **All chatbots** or **Specific chatbots**.
5. Under **Token lifetime**, keep the default **As requested**, or choose a shorter lifetime. Then select **Approve** or **Deny**.
6. The tool polls `POST https://sitegpt.ai/oauth/token` until you approve. It then gets an API token.

The token shows on the **Agents** page with the source **Device login**. You can rotate or revoke it there.

If your plan does not include API access, the approval page shows "API access needs the Growth plan or above." instead of the **Approve** and **Deny** buttons. The request stays pending. You can approve it after you upgrade, if the code has not expired.

### Token lifetime

The tool asks for a token lifetime in days. The CLI asks for 90 days by default. A tool can ask for up to 365 days.

On the approval page, **Token lifetime** shows these choices:

* **As requested**, with the requested number of days, for example **As requested (90d)**. This is the default.
* **90 days**, **30 days**, and **7 days**. Only the choices that are shorter than the request show.

You can only make the lifetime shorter. You cannot make it longer than the tool asked for. For a default CLI login, you see **As requested (90d)**, **30 days**, and **7 days**.

### Start the request

Send a form-encoded request:

```bash theme={null}
curl -s -X POST https://sitegpt.ai/oauth/device_authorization \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=sitegpt-cli" \
  -d "token_name=My script" \
  -d "scope=account:read chatbots:read knowledge:write"
```

| Field                  | Required | Description                                                                            |
| ---------------------- | -------- | -------------------------------------------------------------------------------------- |
| `client_id`            | Yes      | The ID of the tool. It is public, not a secret. The SiteGPT CLI uses `sitegpt-cli`.    |
| `scope`                | No       | Scopes separated by spaces. If you leave it out, SiteGPT asks for the Standard scopes. |
| `full_access`          | No       | `true` asks for every scope that the approving user can give. It replaces `scope`.     |
| `token_name` or `name` | No       | The token name on the **Agents** page.                                                 |
| `expires_in_days`      | No       | Token lifetime in days, from `1` to `365`. The default is `90`.                        |
| `chatbot_id`           | No       | Limits the token to one chatbot. Repeat the field for more chatbots.                   |
| `chatbot_ids`          | No       | Chatbot IDs separated by commas.                                                       |

Response:

```json theme={null}
{
  "device_code": "YOUR_DEVICE_CODE",
  "user_code": "ABCD-EFGH",
  "verification_uri": "https://sitegpt.ai/device",
  "verification_uri_complete": "https://sitegpt.ai/device?user_code=ABCD-EFGH",
  "expires_in": 900,
  "interval": 2
}
```

Open `verification_uri_complete` in a browser. The device code expires after 15 minutes.

### Poll for the token

```bash theme={null}
curl -s -X POST https://sitegpt.ai/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  -d "client_id=sitegpt-cli" \
  -d "device_code=YOUR_DEVICE_CODE"
```

| Field         | Required | Description                                              |
| ------------- | -------- | -------------------------------------------------------- |
| `grant_type`  | Yes      | `urn:ietf:params:oauth:grant-type:device_code`           |
| `client_id`   | Yes      | The same `client_id` that you used to start the request. |
| `device_code` | Yes      | The `device_code` from the first response.               |

Wait at least `interval` seconds (2 seconds) between polls. After approval, the response has the token:

```json theme={null}
{
  "access_token": "sgpt_YOUR_TOKEN",
  "token_type": "Bearer",
  "expires_in": 7776000,
  "scope": "account:read chatbots:read knowledge:write",
  "sitegpt_token": {
    "id": "YOUR_TOKEN_ID",
    "name": "My script",
    "tokenPrefix": "YOUR_TOKEN_PREFIX",
    "scopes": ["account:read", "chatbots:read", "knowledge:write"],
    "chatbotIds": [],
    "expiresAt": "2026-12-21T00:00:00.000Z"
  }
}
```

Use `access_token` as a bearer token for API v2.

### Device login errors

Errors come back as `{ "error": "...", "error_description": "..." }`.

| Error                    | Meaning                                                               |
| ------------------------ | --------------------------------------------------------------------- |
| `authorization_pending`  | You have not approved the request yet. Poll again after the interval. |
| `slow_down`              | The tool polls too fast. Wait longer between polls.                   |
| `access_denied`          | You selected **Deny**. Stop polling.                                  |
| `expired_token`          | The device code expired. Start again.                                 |
| `invalid_grant`          | The device code is not valid or was already used.                     |
| `invalid_scope`          | A requested scope does not exist or cannot be issued.                 |
| `invalid_request`        | A required field is missing or the body is not form-encoded.          |
| `unsupported_grant_type` | The `grant_type` is wrong.                                            |

### Discovery

Tools can find the device login endpoints in the OAuth metadata:

```text theme={null}
https://sitegpt.ai/.well-known/oauth-authorization-server
https://sitegpt.ai/.well-known/oauth-protected-resource/api/v2
```

The metadata also describes agent sign-up without an account. See [Agent-first onboarding](/docs/cli/onboarding).

## Legacy API key

The legacy API key works with the legacy API v0 and v1 and with [widget identity verification](/docs/developers/widget-sdk#identity-verification). It does not work with API v2, except for `GET /api/v2/me`, which returns a warning. For new work, use an API token.

* **Plan:** Growth plan and above. See [Plans and limits](/docs/reference/plans-and-limits).
* **Where to find it:** Open the **Billing** page. The key shows in the line "Your API Key is ...". It shows only when your plan includes API access.
* **Creation:** SiteGPT creates the key for you when your plan includes API access. The key does not change on its own. You cannot create or rotate it yourself.
* **Access:** The key acts as your user in the legacy API. It has no scopes, and you cannot limit it to some chatbots.

If your plan includes API access but you do not see a key, contact support.

## Security

* Store tokens and keys in environment variables or a secret manager. Do not put them in source code, chat prompts, or logs.
* Give each tool its own token, with the smallest access that works.
* Use **Specific chatbots** for tools that work on one chatbot.
* Revoke tokens after a demo or when someone leaves your team.
* Never use the legacy API key in browser code.

## Errors

| Status | Code                             | Meaning                                                                     |
| ------ | -------------------------------- | --------------------------------------------------------------------------- |
| 401    | `AUTHORIZATION_HEADER_REQUIRED`  | The request has no `Authorization` header.                                  |
| 401    | `AUTHORIZATION_HEADER_NOT_VALID` | The header is not in the form `Bearer YOUR_TOKEN`.                          |
| 401    | `TOKEN_NOT_VALID`                | The token is wrong, expired, or revoked.                                    |
| 403    | `TOKEN_SCOPE_NOT_ALLOWED`        | The token does not have a scope that the operation needs.                   |
| 403    | `PLAN_UPGRADE_REQUIRED`          | Your plan does not include API access. Upgrade to the Growth plan or above. |
| 404    | `CHATBOT_NOT_FOUND`              | The chatbot does not exist, or the token cannot access it.                  |

A `401` response from API v2 includes a `WWW-Authenticate` header that points to the OAuth metadata. For all API v2 error codes, see [API conventions](/docs/api-reference/v2/conventions#errors).
