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

# Authentication

> Secure your API requests with Partner API Keys

## Overview

The Unleeshed Partner API uses **API Key authentication** for all server-to-server requests. API keys are issued to licensed partners and provide secure access to your licensed personas and commentary generation.

## Getting Your API Key

1. Log into the [Partner Dashboard](https://app.unleeshed.ai/partner)
2. Navigate to **Developer → API Keys**
3. Click **Create API Key**
4. Select the required scopes (permissions)
5. Copy and securely store the key

<Warning>
  API keys are only shown once when created. Store them securely in your environment variables or secrets manager.
</Warning>

## Using Your API Key

Include the API key in the `X-Api-Key` header for all requests:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://prod.api.unleeshed.ai/partner/v1/personas" \
    -H "X-Api-Key: pk_live_abc123..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://prod.api.unleeshed.ai/partner/v1/personas', {
    headers: {
      'X-Api-Key': process.env.UNLEESHED_API_KEY
    }
  });
  ```

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

  response = requests.get(
      "https://prod.api.unleeshed.ai/partner/v1/personas",
      headers={"X-Api-Key": os.environ["UNLEESHED_API_KEY"]}
  )
  ```
</CodeGroup>

## API Key Scopes

API keys have granular scopes that control what actions they can perform:

| Scope           | Description                   | Endpoints                            |
| --------------- | ----------------------------- | ------------------------------------ |
| `personas:read` | View licensed personas        | `GET /personas`, `GET /personas/:id` |
| `topics:submit` | Create topics for commentary  | `POST /topics`                       |
| `topics:read`   | View topic status and results | `GET /topics`, `GET /topics/:id`     |
| `usage:read`    | View usage statistics         | `GET /usage`                         |

<Tip>
  Follow the principle of least privilege. Only grant the scopes your integration actually needs.
</Tip>

## Key Format

API keys follow this format:

```
pk_[environment]_[random_string]

Examples:
- pk_live_abc123...  (Production)
- pk_test_xyz789...  (Sandbox/Testing)
```

## Security Best Practices

<AccordionGroup>
  <Accordion title="Never expose keys in client-side code">
    API keys should only be used in server-side code. Never include them in:

    * JavaScript bundles served to browsers
    * Mobile app source code
    * Public repositories
    * Client-side environment variables
  </Accordion>

  <Accordion title="Use environment variables">
    Store API keys in environment variables or a secrets manager:

    ```bash theme={null}
    # .env (never commit this file!)
    UNLEESHED_API_KEY=pk_live_abc123...
    ```

    ```javascript theme={null}
    // Access in your code
    const apiKey = process.env.UNLEESHED_API_KEY;
    ```
  </Accordion>

  <Accordion title="Rotate keys periodically">
    Rotate your API keys every 90 days or immediately if you suspect compromise:

    1. Create a new API key in the dashboard
    2. Update your application to use the new key
    3. Verify the new key works
    4. Revoke the old key
  </Accordion>

  <Accordion title="Use IP restrictions (optional)">
    For additional security, restrict your API key to specific IP addresses:

    1. Go to **Developer → API Keys**
    2. Click on your key
    3. Add allowed IP addresses

    Requests from non-whitelisted IPs will be rejected.
  </Accordion>
</AccordionGroup>

## Error Responses

Authentication errors return a `401` status code:

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

Common authentication errors:

| Error Code      | Description                     | Solution                                           |
| --------------- | ------------------------------- | -------------------------------------------------- |
| `unauthorized`  | Missing or invalid API key      | Check that you're including the `X-Api-Key` header |
| `key_revoked`   | API key has been revoked        | Create a new API key in the dashboard              |
| `key_expired`   | API key has expired             | Create a new API key or contact support            |
| `ip_restricted` | Request from non-whitelisted IP | Add your IP to the allowed list                    |
| `scope_denied`  | Key lacks required scope        | Create a new key with the needed scopes            |

## Rate Limiting

API keys are subject to rate limits:

| Tier     | Rate Limit          | Burst               |
| -------- | ------------------- | ------------------- |
| Standard | 1,000 requests/hour | 100 requests/minute |
| Premium  | 5,000 requests/hour | 500 requests/minute |

When rate limited, you'll receive a `429` response with a `Retry-After` header.

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Your First Topic" icon="plus" href="/guides/generate-commentary">
    Learn how to generate commentary with your API key.
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Explore all available endpoints.
  </Card>
</CardGroup>
