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

# API Authentication — Bearer Tokens and Key Management

> Generate and manage API keys in the VInfer dashboard, then pass your key in the Authorization header on every request to the VInfer AI API.

Every request to the VInfer AI API must be authenticated using an API key. VInfer uses the industry-standard **Bearer token** scheme — you generate a key in the dashboard, store it securely in your application, and include it in the `Authorization` header of each HTTP request. There are no session tokens, OAuth flows, or cookies required for server-to-server integrations.

<Warning>
  Treat your API keys exactly like passwords. If a key is exposed in a public repository, log file, or error message, revoke it immediately from the VInfer dashboard and generate a replacement. Leaked keys can be used by anyone to access your workspace data and trigger calls on your behalf.
</Warning>

## Generating an API Key

To create a new API key:

1. Log in to the VInfer dashboard at [app.vinfer.ai](https://app.vinfer.ai).
2. Navigate to **Settings → API Keys**.
3. Click **Create New Key**.
4. Enter a descriptive name (e.g., `production-backend`, `analytics-pipeline`).
5. Select the appropriate **scope** (see [Key Scopes](#key-scopes) below).
6. Click **Create** — the key is shown **once**. Copy it immediately and store it somewhere safe.

<Note>
  API keys are workspace-scoped. Each workspace (for example, your production environment and staging environment) has its own separate set of keys. Make sure you are in the correct workspace before generating a key.
</Note>

## Making Authenticated Requests

Include your API key as a Bearer token in the `Authorization` header on every request. Replace `YOUR_API_KEY` with the key you generated.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.vinfer.ai/v1/campaigns \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

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

  headers = {"Authorization": "Bearer YOUR_API_KEY"}
  response = requests.get("https://api.vinfer.ai/v1/campaigns", headers=headers)
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.vinfer.ai/v1/campaigns', {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  });
  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

<Tip>
  Store your API key in an environment variable (e.g., `VINFER_API_KEY`) rather than hardcoding it in your source files. Access it at runtime with `process.env.VINFER_API_KEY` in Node.js or `os.environ["VINFER_API_KEY"]` in Python. This keeps keys out of version control and makes rotating them painless.
</Tip>

## Key Scopes

When creating a key, you assign it one of three scopes. Always use the least-privileged scope that your integration actually requires.

| Scope          | Permissions                                                                                                                                               |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Read-Only**  | `GET` requests only — list and retrieve resources. Suitable for dashboards, monitoring, and analytics pipelines.                                          |
| **Read-Write** | All `GET`, `POST`, `PATCH`, and `DELETE` requests. Suitable for backend services that create campaigns, initiate calls, or submit transcription jobs.     |
| **Admin**      | All read-write permissions plus the ability to create, list, and revoke API keys. Suitable for internal tooling that manages API access programmatically. |

## Rotating Keys

Rotate keys periodically and immediately after any suspected exposure. The recommended process to rotate without downtime:

1. Generate a **new key** with the same scope as the key you are replacing.
2. Update your application configuration or secret manager to use the new key.
3. Deploy and verify that requests are succeeding with the new key.
4. Return to **Settings → API Keys** in the dashboard and click **Revoke** next to the old key.

Revoking a key is instant and irreversible — any request using the revoked key immediately receives a `401 Unauthorized` response.

## Security Best Practices

<Accordion title="Full list of API key security best practices">
  * **Use environment variables.** Never hardcode keys in source code, configuration files checked into version control, or build artifacts.
  * **Use read-only keys for read-only integrations.** If a service only needs to query analytics or list campaigns, give it a read-only key. A compromised read-only key cannot launch calls or modify data.
  * **Never include keys in URLs.** Query string parameters appear in server logs, browser history, and referrer headers. Always pass keys in the `Authorization` header.
  * **Audit key usage.** The VInfer dashboard shows the last-used timestamp for each key. If you see activity on a key that shouldn't be active, revoke it immediately.
  * **Rotate keys on a schedule.** Even without a known exposure, rotating production keys every 90 days reduces the window of risk from undetected leaks.
  * **Use separate keys per environment.** Never share a production API key with a staging or development environment — use workspace isolation and environment-specific keys.
</Accordion>

## Authentication Errors

If your request is rejected due to an authentication issue, the API returns one of the following errors:

**401 Unauthorized** — returned when the `Authorization` header is missing, the token is malformed, or the key has been revoked.

```json theme={null}
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key. Include a valid Bearer token in the Authorization header.",
    "details": {}
  }
}
```

**403 Forbidden** — returned when the key is valid but its scope does not permit the requested action. For example, using a read-only key to create a campaign.

```json theme={null}
{
  "error": {
    "code": "forbidden",
    "message": "Your API key does not have permission to perform this action. A read-write or admin key is required.",
    "details": {
      "required_scope": "read-write",
      "current_scope": "read-only"
    }
  }
}
```
