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

# API Authentication — OTP.ID Bearer Key Setup Guide

> Learn how to get your OTP.ID API key, add the Authorization: Bearer header to every request, and handle all three types of authentication errors.

Every request you make to the OTP.ID API must be authenticated with an API key. OTP.ID uses the standard HTTP Bearer token scheme — you include your key in the `Authorization` header, and OTP.ID validates it before processing the request. There are no cookies, sessions, or OAuth flows to configure. If the key is valid, the request proceeds; if not, you receive a clear error response telling you exactly what went wrong.

<Warning>
  Keep your API key secret. Never expose it in client-side code, browser JavaScript, mobile app binaries, or public repositories. If a key is compromised, rotate it immediately from your dashboard.
</Warning>

## Get Your API Key

Your API key lives in the OTP.ID dashboard:

1. Log in at [https://otp.id](https://otp.id).
2. Go to **Settings → API Keys**.
3. Copy your active key.

API keys are prefixed with `otpid_live_` for production environments. Keep a secure copy — the dashboard only shows the full key once at creation time.

<Note>
  API keys are scoped per merchant account. All balance deductions, rate limits, and transaction records are tracked per key. If you manage multiple projects or environments, create a separate key for each.
</Note>

## Include the Key in Every Request

Pass your API key as a Bearer token in the `Authorization` header on every request to any `/v3/*` endpoint:

```
Authorization: Bearer YOUR_API_KEY
```

Here's a minimal example with `curl`:

```bash theme={null}
curl -X POST https://api.otp.id/v3/request \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "number": "6281234567890",
    "brand": "MyApp"
  }'
```

## Code Examples

The following examples show how to attach the `Authorization` header when making requests from common environments.

<CodeGroup>
  ```js JavaScript (fetch) theme={null}
  const response = await fetch('https://api.otp.id/v3/request', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      channel: 'whatsapp',
      number: '6281234567890',
      brand: 'MyApp'
    })
  });

  const result = await response.json();

  if (result.success) {
    console.log('OTP sent:', result.data.otp_id);
  } else {
    console.error('Error:', result.error.code, result.error.message);
  }
  ```

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

  response = requests.post(
      'https://api.otp.id/v3/request',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'channel': 'whatsapp',
          'number': '6281234567890',
          'brand': 'MyApp'
      }
  )

  result = response.json()

  if result['success']:
      print('OTP sent:', result['data']['otp_id'])
  else:
      print('Error:', result['error']['code'], result['error']['message'])
  ```

  ```bash curl theme={null}
  curl -X POST https://api.otp.id/v3/request \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "channel": "whatsapp",
      "number": "6281234567890",
      "brand": "MyApp"
    }'
  ```
</CodeGroup>

## Authentication Errors

All authentication failures return HTTP `401` with `success: false`. The `error.code` is always `"UNAUTHORIZED"`, and `error.message` describes the specific problem.

### Missing Authorization Header

If you omit the `Authorization` header entirely:

```json theme={null}
{
  "success": false,
  "data": null,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authorization header is missing"
  }
}
```

### Empty API Key

If you include the header but provide an empty string as the token:

```json theme={null}
{
  "success": false,
  "data": null,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "API key must not be empty"
  }
}
```

### Unknown or Invalid API Key

If the key is present but does not match any active key in OTP.ID's system:

```json theme={null}
{
  "success": false,
  "data": null,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Unknown API key"
  }
}
```

This error also occurs if a key has been revoked. If you receive it unexpectedly, verify the key in your dashboard and confirm you're not accidentally including extra whitespace or a newline character in the header value.

## Best Practices

* **Use environment variables** to store your API key rather than hardcoding it in source files. Reference it as `process.env.OTPID_API_KEY` (Node.js) or `os.environ["OTPID_API_KEY"]` (Python).
* **Rotate keys periodically** and immediately if you suspect exposure.
* **Use separate keys per environment** (development, staging, production) so a leaked development key never touches production data or balance.
* **Monitor `last_balance`** in send responses to detect unexpected usage spikes that could indicate a leaked key.
