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

# Authentication

> Learn how to authenticate with the Migma.ai API

## API Keys

Migma.ai uses API keys to authenticate requests. Your API keys carry many privileges, so be sure to keep them secure! Do not share your API keys in publicly accessible areas such as GitHub, client-side code, etc.

## Creating an API Key

<Steps>
  <Step title="Navigate to Settings">
    Log in to [migma.ai](https://migma.ai) and go to **Settings → Developers → API Keys**
  </Step>

  <Step title="Create New Key">
    Click **Create API Key** in the API Keys tab
  </Step>

  <Step title="Configure Permissions">
    Give your key a name and select the permissions it needs
  </Step>

  <Step title="Save Securely">
    Copy the key immediately - it won't be shown again!
  </Step>
</Steps>

<Warning>
  API keys are shown only once at creation. Store them securely in a password manager or environment variables.
</Warning>

<Tip>
  Working with an AI agent? It can register itself and receive its own scoped key after you approve it with a code. See [Agent registration](/agent-registration).
</Tip>

## Using Your API Key

Include your API key in the `Authorization` header of every request:

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

### Example Request

```typescript Node.js SDK theme={null}
import Migma from 'migma';

// The SDK handles the Authorization header automatically
const migma = new Migma('YOUR_MIGMA_API_KEY');
const { data, error } = await migma.projects.list();
```

```bash cURL theme={null}
curl https://api.migma.ai/v1/projects \
  -H "Authorization: Bearer YOUR_MIGMA_API_KEY"
```

```javascript JavaScript theme={null}
const response = await fetch('https://api.migma.ai/v1/projects', {
  headers: {
    'Authorization': 'Bearer YOUR_MIGMA_API_KEY'
  }
});
```

```python Python theme={null}
import requests

headers = {
    'Authorization': 'Bearer YOUR_MIGMA_API_KEY'
}

response = requests.get(
    'https://api.migma.ai/v1/projects',
    headers=headers
)
```

## API Key Permissions

When creating an API key, you can grant specific permissions to limit what the key can access.

### Audience Permissions

| Permission       | Description                                                       |
| ---------------- | ----------------------------------------------------------------- |
| `audience:read`  | View subscribers, tags, and audience segments                     |
| `audience:write` | Add, update subscribers, manage tags, create segments             |
| `email:read`     | View email templates and sending history                          |
| `email:write`    | Create and edit generated emails                                  |
| `email:send`     | Send test and live emails                                         |
| `email:validate` | Test email compatibility, check links, and analyze deliverability |
| `email:preview`  | Generate email previews across multiple devices and email clients |
| `domain:read`    | View sending domains and their verification status                |
| `domain:write`   | Add, verify, update, and remove sending domains                   |
| `campaign:read`  | View campaigns, stats, and delivery logs                          |
| `campaign:write` | Create, send, schedule, cancel, archive, and unarchive campaigns  |
| `project:write`  | Import projects and manage project resources                      |
| `webhook:read`   | List and view webhook configurations                              |
| `webhook:write`  | Create, update, and delete webhooks for real-time notifications   |

<Tip>
  Follow the principle of least privilege: only grant the permissions your application needs.
</Tip>

## Environment-Specific Keys

Use different API keys for different environments:

```bash Development theme={null}
MIGMA_API_KEY=sk_test_...
```

```bash Production theme={null}
MIGMA_API_KEY=sk_live_...
```

<Info>
  Test keys start with `sk_test_` and production keys start with `sk_live_`
</Info>

## Security best practices

* **Never hardcode keys** — use environment variables: `const migma = new Migma(process.env.MIGMA_API_KEY)`
* **Least privilege** — only grant the permissions your integration actually needs
* **Rotate periodically** — create a new key, update your app, then revoke the old one
* **Monitor usage** — check last-used dates in **Settings → Developers → API Keys** and revoke anything unexpected

## Key Management

### Viewing Your Keys

Navigate to **Settings → Developers → API Keys** to see:

* Key name and ID (first 8 characters)
* Permissions granted
* Creation date
* Last used date
* Usage statistics

### Revoking a Key

If a key is compromised or no longer needed:

<Steps>
  <Step title="Find the Key">
    Go to **Settings → Developers → API Keys**
  </Step>

  <Step title="Delete">
    Click the delete icon next to the key
  </Step>

  <Step title="Confirm">
    Confirm the deletion - this action cannot be undone
  </Step>
</Steps>

<Warning>
  Revoking a key will immediately invalidate it. Any applications using that key will receive 401 Unauthorized errors.
</Warning>

## Error Responses

### 401 Unauthorized

Your API key is invalid or missing:

```json theme={null}
{
  "success": false,
  "error": "Invalid or missing API key"
}
```

**Common causes:**

* API key not included in Authorization header
* Wrong format (must be `Bearer YOUR_KEY`)
* Key has been revoked
* Using test key in production environment

### 403 Forbidden

Your API key doesn't have permission for this action:

```json theme={null}
{
  "success": false,
  "error": "Insufficient permissions"
}
```

**Solution:** Create a new key with the required permissions or update the existing key's permissions.

## Rate Limiting

API keys are subject to rate limits based on your plan:

| Plan       | Requests / minute | Requests / day |
| ---------- | ----------------- | -------------- |
| Standard   | 500               | 10,000         |
| Enterprise | 1,000             | 50,000         |

Rate limit headers are included in every response:

```http theme={null}
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1609459200
```

When you exceed the rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "success": false,
  "error": "Rate limit exceeded",
  "retryAfter": 60
}
```

<Tip>
  Implement exponential backoff when you receive 429 responses to avoid further rate limiting.
</Tip>

## Need help?

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Get started with your first API call
  </Card>

  <Card title="Node.js SDK" icon="npm" href="/sdk">
    SDK handles authentication automatically
  </Card>

  <Card title="CLI" icon="terminal" href="/cli">
    `migma login` to authenticate the CLI
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Full endpoint documentation
  </Card>
</CardGroup>
