# Authentication

API key authentication for ACP checkout operations.

---

ACP uses Bearer token authentication for checkout operations. Product discovery endpoints are public and need no authentication.

## Get your ACP API key

1. Log into [app.avcodex.com](https://app.avcodex.com).
2. Navigate to your agent.
3. Click **Publish** in the sidebar, then **Catalog**.
4. In the API Keys section, click **Create API Key**.
5. Copy the key immediately. It is only shown once.

> **Note:** ACP API keys are separate from Chat API keys. They use the `acp_` prefix and are scoped to the ACP checkout endpoints.

## Use your API key

Include your ACP API key in the `Authorization` header:

```bash
Authorization: Bearer acp_xxxxx
```

### Example

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions \
  -H "Authorization: Bearer acp_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "line_items": [
      { "product_id": "550e8400-e29b-41d4-a716-446655440000", "quantity": 1 }
    ]
  }'
```

## Which endpoints need auth?

| Endpoint                                       | Auth required |
|------------------------------------------------|---------------|
| `GET /.well-known/agent.json`                  | No.           |
| `GET /products`                                | No.           |
| `POST /checkout_sessions`                      | Yes.          |
| `GET /checkout_sessions/{id}`                  | Yes.          |
| `POST /checkout_sessions/{id}`                 | Yes.          |
| `POST /checkout_sessions/{id}/complete`        | Yes.          |
| `POST /checkout_sessions/{id}/cancel`          | Yes.          |

## Key format

ACP API keys always start with the `acp_` prefix, followed by 32 random characters:

```
acp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
```

Keys are stored as SHA-256 hashes. The raw key is returned only once at creation time. If you lose it, revoke the key and create a new one.

## App scoping

Each API key is bound to a specific agent. The `appId` in the URL must match the agent the key was created for. If they don't match, you'll receive a `403` error.

## Error responses

### 401 Unauthorized

Missing or invalid token:

```json
{ "error": { "code": "unauthorized", "message": "Missing or invalid Authorization header" } }
```

Invalid key format (missing `acp_` prefix):

```json
{ "error": { "code": "unauthorized", "message": "Invalid API key format" } }
```

Key not found or revoked:

```json
{ "error": { "code": "unauthorized", "message": "Invalid API key" } }
```

API key has expired:

```json
{ "error": { "code": "expired", "message": "API key has expired" } }
```

### 403 Forbidden

API key doesn't belong to the agent in the URL:

```json
{ "error": { "code": "forbidden", "message": "API key does not match application" } }
```

## Rate limits

ACP endpoints are rate-limited per time window (1 minute):

| Route type                | Limit                | Keyed by    |
|---------------------------|----------------------|-------------|
| Public (discovery)        | 200 requests/min.    | Client IP.  |
| Authenticated (checkout)  | 60 requests/min.     | API key.    |

When a rate limit is exceeded, the API returns a `429` response with a `Retry-After` header indicating how many seconds to wait:

```json
{ "error": "Rate limit exceeded" }
```

```
HTTP/1.1 429 Too Many Requests
Retry-After: 12
```

*AVCodex · Your AV expertise. Amplified by AI.*