# Authentication

Learn how to authenticate your requests to the Cosmic API.

## Get your API keys

Cosmic uses API keys to authenticate requests. For the following examples, you will need your:

1. Bucket slug
2. Bucket read key
3. Bucket write key

You can get your API access keys by going to Bucket Settings > API Access in [the Cosmic dashboard](https://app.cosmicjs.com/login).

## Use your API keys

Use the methods below to use your Cosmic API keys.

Before you can make requests to the Cosmic API, you will need to grab your
Bucket slug and API keys from your dashboard. Find them in [Bucket Settings
&raquo; API Access](https://app.cosmicjs.com/login).
```js
// Import
import { createBucketClient } from '@cosmicjs/sdk';

// Authenticate
const cosmic = createBucketClient({
  bucketSlug: 'BUCKET_SLUG',
  readKey: 'BUCKET_READ_KEY',
  writeKey: 'BUCKET_WRITE_KEY',
});

// Fetch content
await cosmic.objects
  .find({
    type: 'posts',
  })
  .limit(1);

// Write content
await cosmic.objects.insertOne({
  title: 'Blog Post Title',
  type: 'posts',
  metadata: {
    content: 'Here is the blog post content...',
    seo_description: 'This is the blog post SEO description.',
    featured_post: true,
  },
});

```
```bash {{ title: 'cURL' }}
# Fetch content
curl https://api.cosmicjs.com/v3/buckets/${BUCKET_SLUG}/objects \
  -d read_key=${BUCKET_READ_KEY} \
  --data-urlencode query='{"type": "posts"}' \
  -d limit=1 \
  -G

# Write content
curl https://api.cosmicjs.com/v3/buckets/${BUCKET_SLUG}/objects \
  -d '{"title":"Blog Post Title","type":"posts","metadata":{"seo_description":"This is the blog post SEO description.","featured_post": true}}' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer {BUCKET_WRITE_KEY}"
```

```swift {{ title: 'Swift' }}
// Import
import CosmicSDK

// Authenticate
let cosmic = CosmicSDKSwift(
    .createBucketClient(
        bucketSlug: BUCKET,
        readKey: READ_KEY,
        writeKey: WRITE_KEY
    )
)

// Fetch content
@State var posts: [Object] = []

cosmic.find(type: posts) { results in
    switch results {
    case .success(let result):
        self.posts = result.objects
    case .failure(let error):
        print(error)
    }
}

// Write content
@State private var post: Object?

cosmic.insertOne(
    type: posts,
    title: post.title
    ) { results in
    switch results {
    case .success(_):
        print("Updated \(post.id)")
    case .failure(let error):
        print(error)
    }
}
```
Never expose your Bucket write key in any client-side code.

## Personal Access Tokens

For dashboard-level API access (managing agents, workflows, account settings, etc.), use a Personal Access Token (PAT) instead of a session JWT. PATs are ideal for scripts, CI/CD pipelines, CLI tools, and MCP servers.

Create a token at [Account Settings > API Tokens](https://app.cosmicjs.com/account/api-tokens). Tokens use the `cos_` prefix and carry your full account permissions. Learn more in the [API Tokens documentation](/docs/dashboard/account#api-tokens).

Include your token in the Authorization header:

```bash
curl https://dapi.cosmicjs.com/v3/users/get \
  -H "Authorization: Bearer cos_YOUR_TOKEN"
```
PATs are the recommended authentication method for the [Agent Messaging API](/docs/dashboard/ai/agents#agent-messaging-api-reference). For example, to send a message to a Communication agent:

```bash
curl -X POST https://dapi.cosmicjs.com/v3/ai/agents/AGENT_ID/messages \
  -H "Authorization: Bearer cos_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "Hello, agent!"}'
```
Never expose your Personal Access Token in client-side code. PATs carry your full account permissions.

## Agent key

An **agent key** (`agk_` prefix) is a short-lived bearer token issued by [`POST /v3/agents/sign-up`](/docs/api/agents#sign-up). It is the auth mechanism used when an AI agent provisions a Cosmic project on behalf of a human, before the human has a Cosmic account of their own.

Agent keys have a very narrow scope: they authenticate only the agent-flow endpoints.

| Endpoint | Auth |
|---|---|
| `POST /v3/agents/verify` | `Authorization: Bearer agk_...` |
| `GET /v3/agents/status` | `Authorization: Bearer agk_...` |

For everything else (objects, media, AI generation), use the **bucket read key and write key** that are returned in the same sign-up response. Those work with the standard [bucket API](/docs/api/objects), the [JavaScript SDK](https://www.npmjs.com/package/@cosmicjs/sdk), and every other Cosmic interface:

```bash
# Use the agent_key to call the agent-flow endpoints
curl https://dapi.cosmicjs.com/v3/agents/status \
  -H "Authorization: Bearer agk_..."

# Use the bucket write_key (returned by /v3/agents/sign-up) for content
curl -X POST https://api.cosmicjs.com/v3/buckets/${BUCKET_SLUG}/objects \
  -H "Authorization: Bearer ${BUCKET_WRITE_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"title":"First post","type":"posts"}'

```
The bucket starts in restricted "unclaimed" mode until the human verifies the OTP from the claim email. AI generation is blocked while unclaimed; create/read/update of up to 50 objects and 5 MB of media still works. See the full [Agents API reference](/docs/api/agents) for the lifecycle, limits, and error codes.

Treat agent keys like any other secret. They identify the agent and grant access to the bucket keys, the human's email, and the verify flow. Persist them per-agent; do not embed in shared client code.