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

# Authentication

> Learn how to authenticate your API requests with Hooked

## API Key Authentication

All API requests must be authenticated using an API key passed in the request headers.

### Getting Your API Key

<Steps>
  <Step title="Access your dashboard">
    Log in to [hooked.so](https://hooked.so)
  </Step>

  <Step title="Navigate to API settings">
    Go to **Settings** → **API Keys**
  </Step>

  <Step title="Generate a new key">
    Click "Generate New API Key" and give it a descriptive name
  </Step>

  <Step title="Save your key">
    Copy and store your API key securely - you won't be able to see it again
  </Step>
</Steps>

## Try It in the Playground

<Info>
  **You can test all API endpoints directly in this documentation!**

  Click on any endpoint (like [List Avatars](/api-reference/avatar/list)) and you'll see an **Authorization** field where you can enter your API key to make real requests.
</Info>

### How to Use the API Playground:

1. Navigate to any API endpoint page
2. Look for the **Authorization** or **x-api-key** field at the top
3. Enter your API key
4. Modify the request parameters if needed
5. Click **"Send"** to see the real response

Your API key is securely stored in your browser's localStorage, so you only need to enter it once per browser.

<Tip>
  Start with [List Avatars](/api-reference/avatar/list) - it's a simple GET request perfect for testing!
</Tip>

## Using Your API Key in Code

Include your API key in the `x-api-key` header of every request:

```bash theme={null}
curl -X GET "https://api.hooked.so/v1/avatar/list" \
  -H "x-api-key: your_api_key_here"
```

<CodeGroup>
  ```javascript Node.js theme={null}
  const axios = require('axios');

  const api = axios.create({
    baseURL: 'https://api.hooked.so/v1',
    headers: {
      'x-api-key': 'your_api_key_here',
      'Content-Type': 'application/json'
    }
  });

  // Example request
  const response = await api.get('/avatar/list');
  console.log(response.data);
  ```

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

  API_KEY = "your_api_key_here"
  BASE_URL = "https://api.hooked.so/v1"

  headers = {
      "x-api-key": API_KEY,
      "Content-Type": "application/json"
  }

  # Example request
  response = requests.get(f"{BASE_URL}/avatar/list", headers=headers)
  print(response.json())
  ```

  ```php PHP theme={null}
  <?php

  $apiKey = "your_api_key_here";
  $baseUrl = "https://api.hooked.so/v1";

  $headers = [
      "x-api-key: {$apiKey}",
      "Content-Type: application/json"
  ];

  $ch = curl_init("{$baseUrl}/avatar/list");
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  curl_close($ch);

  echo $response;
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      apiKey := "your_api_key_here"
      baseURL := "https://api.hooked.so/v1"

      client := &http.Client{}
      req, _ := http.NewRequest("GET", baseURL+"/avatar/list", nil)
      req.Header.Set("x-api-key", apiKey)
      req.Header.Set("Content-Type", "application/json")

      resp, _ := client.Do(req)
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```
</CodeGroup>

## Security Best Practices

<Warning>
  **Never expose your API key in client-side code or public repositories.**
</Warning>

### Environment Variables

Store your API key in environment variables:

<CodeGroup>
  ```bash .env theme={null}
  HOOKED_API_KEY=your_api_key_here
  ```

  ```javascript Node.js theme={null}
  require('dotenv').config();

  const API_KEY = process.env.HOOKED_API_KEY;
  ```

  ```python Python theme={null}
  import os
  from dotenv import load_dotenv

  load_dotenv()
  API_KEY = os.getenv('HOOKED_API_KEY')
  ```
</CodeGroup>

### API Key Management

<AccordionGroup>
  <Accordion title="Rotate keys regularly" icon="rotate">
    For production applications, rotate your API keys every 90 days. Create a new key before deleting the old one to avoid downtime.
  </Accordion>

  <Accordion title="Use different keys for environments" icon="server">
    Create separate API keys for development, staging, and production environments.
  </Accordion>

  <Accordion title="Restrict IP addresses (coming soon)" icon="shield">
    We're adding support for IP whitelisting to further secure your API keys.
  </Accordion>

  <Accordion title="Monitor usage" icon="chart-line">
    Check your API usage in the dashboard to detect any unusual activity.
  </Accordion>
</AccordionGroup>

## Error Responses

If authentication fails, you'll receive a `401 Unauthorized` response:

```json theme={null}
{
  "success": false,
  "message": "Authentication required. Please provide a valid API key in the x-api-key header."
}
```

### Common Authentication Errors

| Error                   | Cause                                     | Solution                                               |
| ----------------------- | ----------------------------------------- | ------------------------------------------------------ |
| `401 Unauthorized`      | Missing or invalid API key                | Check that your key is correct and included in headers |
| `403 Forbidden`         | API key doesn't have required permissions | Verify your subscription plan includes API access      |
| `429 Too Many Requests` | Rate limit exceeded                       | Wait before making more requests or upgrade your plan  |

## Rate Limiting

API requests are rate-limited based on your subscription plan:

| Plan    | Rate Limit           | Burst Limit   |
| ------- | -------------------- | ------------- |
| Free    | 10 requests/minute   | 20 requests   |
| Starter | 60 requests/minute   | 100 requests  |
| Pro     | 300 requests/minute  | 500 requests  |
| Premium | 1000 requests/minute | 2000 requests |

### Rate Limit Headers

Each response includes rate limit information in the headers:

```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1642416000
```

### Handling Rate Limits

Implement exponential backoff when you receive a `429` response:

```javascript theme={null}
async function makeRequestWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }
      
      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
```

## Testing Your Authentication

Test your API key with a simple request:

```bash theme={null}
curl -X GET "https://api.hooked.so/v1/avatar/list?type=library" \
  -H "x-api-key: your_api_key_here"
```

<Check>
  If you receive a successful response with avatar data, your authentication is working correctly!
</Check>

## Need Help?

<CardGroup cols={2}>
  <Card title="Dashboard" icon="browser" href="https://hooked.so/settings/api">
    Manage your API keys
  </Card>

  <Card title="Support" icon="envelope" href="mailto:support@hooked.so">
    Contact our support team
  </Card>
</CardGroup>
