> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Metaculus/metaculus/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate with the Metaculus API using token-based authentication

## Authentication Overview

The Metaculus API uses **token-based authentication** for all API requests. You must include a valid API token in the `Authorization` header of every request.

<Warning>
  All API requests require valid authentication credentials. Unauthenticated requests will be rejected with a 401 Unauthorized error.
</Warning>

## Getting Your API Token

To obtain your API token:

1. Log in to your Metaculus account
2. Navigate to your [Account Settings](https://www.metaculus.com/accounts/settings/account/#api-access)
3. Scroll to the **"API Access"** section
4. Click to generate a new token or view your existing token

<Warning>
  **Keep your API token secret!** Anyone with your token can make API requests on your behalf. Never commit tokens to version control or share them publicly.
</Warning>

## Token Format

API tokens are 40-character hexadecimal strings, for example:

```
9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
```

## Making Authenticated Requests

Include your token in the `Authorization` header with the `Token` prefix:

```
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
```

The format is: `Token` (literal string) + single space + your API token.

### Example Requests

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://www.metaculus.com/api/posts/" \
    -H "Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
  ```

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

  API_TOKEN = '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'

  headers = {
      'Authorization': f'Token {API_TOKEN}'
  }

  response = requests.get(
      'https://www.metaculus.com/api/posts/',
      headers=headers
  )

  if response.status_code == 200:
      data = response.json()
      print(f"Retrieved {len(data['results'])} posts")
  elif response.status_code == 401:
      print("Authentication failed - check your token")
  ```

  ```javascript JavaScript theme={null}
  const API_TOKEN = '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b';

  const response = await fetch(
    'https://www.metaculus.com/api/posts/',
    {
      headers: {
        'Authorization': `Token ${API_TOKEN}`
      }
    }
  );

  if (response.ok) {
    const data = await response.json();
    console.log(`Retrieved ${data.results.length} posts`);
  } else if (response.status === 401) {
    console.error('Authentication failed - check your token');
  }
  ```

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

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

  func main() {
      apiToken := "9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
      
      client := &http.Client{}
      req, _ := http.NewRequest("GET", "https://www.metaculus.com/api/posts/", nil)
      req.Header.Add("Authorization", fmt.Sprintf("Token %s", apiToken))
      
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()
      
      if resp.StatusCode == 200 {
          body, _ := io.ReadAll(resp.Body)
          fmt.Println(string(body))
      }
  }
  ```
</CodeGroup>

## Authentication Errors

Common authentication error responses:

### 401 Unauthorized - Missing Token

```json theme={null}
{
  "detail": "Authentication credentials were not provided."
}
```

**Solution:** Ensure you've included the `Authorization` header in your request.

### 401 Unauthorized - Invalid Token

```json theme={null}
{
  "detail": "Invalid token."
}
```

**Solution:** Verify your token is correct. Generate a new token from your account settings if needed.

### 403 Forbidden

```json theme={null}
{
  "detail": "You do not have permission to perform this action."
}
```

**Solution:** You're authenticated but don't have permission to access this resource. Check if the resource requires special permissions or if you're accessing a private tournament.

## Token Security Best Practices

<Warning>
  Follow these security practices to protect your API token:
</Warning>

### Use Environment Variables

Never hardcode tokens in your source code. Use environment variables instead:

<CodeGroup>
  ```python Python theme={null}
  import os

  API_TOKEN = os.environ.get('METACULUS_API_TOKEN')

  if not API_TOKEN:
      raise ValueError("METACULUS_API_TOKEN environment variable not set")

  headers = {'Authorization': f'Token {API_TOKEN}'}
  ```

  ```javascript JavaScript (Node.js) theme={null}
  const API_TOKEN = process.env.METACULUS_API_TOKEN;

  if (!API_TOKEN) {
    throw new Error('METACULUS_API_TOKEN environment variable not set');
  }

  const headers = {
    'Authorization': `Token ${API_TOKEN}`
  };
  ```

  ```bash Shell theme={null}
  # Set the environment variable
  export METACULUS_API_TOKEN="your_token_here"

  # Use in curl
  curl "https://www.metaculus.com/api/posts/" \
    -H "Authorization: Token $METACULUS_API_TOKEN"
  ```
</CodeGroup>

### Rotate Tokens Regularly

For production applications, consider rotating your API tokens periodically:

1. Generate a new token from your account settings
2. Update your application to use the new token
3. Revoke the old token once migration is complete

You can also rotate your API token programmatically using the API:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/auth/api-key/rotate/" \
    -H "Authorization: Token YOUR_CURRENT_TOKEN"
  ```

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

  response = requests.post(
      'https://www.metaculus.com/api/auth/api-key/rotate/',
      headers={'Authorization': f'Token {current_token}'}
  )

  new_token = response.json()['token']
  print(f"New token: {new_token}")
  ```
</CodeGroup>

<Warning>
  After rotating your token, your old token will be immediately invalidated. Make sure to update your application with the new token before the rotation completes.
</Warning>

### Limit Token Exposure

* Don't log tokens in application logs
* Don't commit tokens to version control (.env files should be in .gitignore)
* Don't share tokens in public channels or forums
* Use separate tokens for different applications or environments

## Token Usage for Bots

<Note>
  API tokens are the recommended authentication method for automated bots and integrations. Session-based authentication is primarily for web users.
</Note>

If you're building a forecasting bot or automated system:

1. Generate a dedicated API token for your bot
2. Consider creating a separate Metaculus account for your bot
3. Clearly indicate in your bot's profile that it's automated
4. Respect rate limits to avoid disrupting the service

## Testing Authentication

Test your authentication setup with this simple request:

```bash theme={null}
curl -i "https://www.metaculus.com/api/posts/?limit=1" \
  -H "Authorization: Token YOUR_API_TOKEN"
```

Successful authentication returns a 200 status code:

```
HTTP/2 200
content-type: application/json
...
```

Failed authentication returns a 401 status code:

```
HTTP/2 401
content-type: application/json

{"detail":"Authentication credentials were not provided."}
```
