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

# Authentication

> OAuth 2.1 and team-scoped API keys for the AdStellar MCP server and public API.

The AdStellar MCP server and REST API support two credentials:

1. **OAuth 2.1** (recommended for interactive MCP clients like Claude and ChatGPT)
2. **API keys** (recommended for your own agents and scripts)

Both resolve to the same team + scopes; every tool runs as your team with full tenant isolation.

## OAuth 2.1

MCP-aware clients walk the flow automatically the first time they connect to `https://app.adstellar.ai/api/mcp`:

1. The server answers `401` with a `WWW-Authenticate` header pointing at the discovery metadata (`/.well-known/oauth-protected-resource`).
2. The client registers itself via Dynamic Client Registration (RFC 7591) at `/api/oauth/register`.
3. You're redirected to the AdStellar consent screen: pick the **team** and the **scopes** to grant.
4. The client exchanges the resulting code for an access + refresh token pair (PKCE, S256-only) at `/api/oauth/token`.

Access tokens live 1 hour; refresh tokens 30 days and rotate on every use. Nothing needs to be configured by hand — just paste the MCP URL into your client.

Endpoints:

| Endpoint                                      | Purpose                                   |
| --------------------------------------------- | ----------------------------------------- |
| `GET /.well-known/oauth-authorization-server` | Discovery metadata (RFC 8414)             |
| `POST /api/oauth/register`                    | Dynamic client registration (RFC 7591)    |
| `GET /api/oauth/authorize`                    | Consent screen (requires AdStellar login) |
| `POST /api/oauth/token`                       | Code exchange + refresh rotation (PKCE)   |

## API keys

For unattended agents, create a team-scoped key (`ast_live_...`) in Settings → Developers or via the management API (owner/admin):

```bash theme={null}
curl -X POST https://app.adstellar.ai/api/settings/api-keys \
  -H "Content-Type: application/json" \
  -H "Cookie: <your session>" \
  -d '{
    "teamId": "<your team id>",
    "name": "my-agent",
    "scopes": ["org:read", "models:read", "analytics:read", "assets:read", "campaigns:read", "copy:write", "creatives:write", "videos:write"]
  }'
```

The plaintext key is returned **exactly once** — only its SHA-256 hash is stored.

## Scopes

| Scope             | Unlocks                                                                                                      |
| ----------------- | ------------------------------------------------------------------------------------------------------------ |
| `org:read`        | `get_team_info`, `get_credit_balance`, `get_brand_kit`, `list_products`, `list_projects`, `list_ad_accounts` |
| `models:read`     | `list_models`, `list_avatars`, `list_voices`                                                                 |
| `analytics:read`  | `query_performance`                                                                                          |
| `assets:read`     | `search_assets`, `lookup_asset`, `get_generation_status`                                                     |
| `campaigns:read`  | `list_campaigns`, `get_launch_status`, `list_launch_drafts`, `get_launch_draft`                              |
| `copy:write`      | `generate_ad_copy`                                                                                           |
| `creatives:write` | `generate_image`                                                                                             |
| `videos:write`    | `generate_video`                                                                                             |
| `launches:write`  | `create_launch_draft`, `delete_launch_draft`                                                                 |

Tools you don't have the scope for are hidden from `tools/list` and rejected with a clear error.

## Use the credential

```
Authorization: Bearer ast_live_...   # API key
Authorization: Bearer ast_at_...     # OAuth access token
```

## Rate limits

120 requests per minute per credential, per endpoint. `429` responses include a `Retry-After` header.

## Security notes

* Keys and tokens are never logged; only hashes are stored.
* Generation tools deduct credits from your team's balance exactly as if you'd run them in the app.
* `create_launch_draft` never publishes ads — launching real campaigns (spend) stays a human action in the dashboard.
* Revoke API keys anytime (`DELETE /api/settings/api-keys/<id>?teamId=...`); OAuth grants expire with their refresh tokens.
