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

# API Authentication

> Create an API key and secret, scope its permissions to an agent, and authenticate Open API requests.

Every Open API request authenticates with an **API key** and a matching **secret**,
sent as request headers. Keys are created and managed in the dashboard, scoped to a
single agent, and granted only the permissions you choose. This page covers creating
a key, the scopes you can grant, and how to send credentials on each request.

Open **Settings → API Permissions** in the dashboard to manage keys.

## Prerequisites

* **Owner** or **Admin** role — only Owners and Admins can create or change API keys.
* The agent you want the key to act on, already created.

## Create an API key

<Steps>
  <Step title="Open API Permissions">
    Go to [**Settings → API Permissions**](/settings/api-keys) and select
    **Add API Key**.
  </Step>

  <Step title="Name the key and pick the agent">
    Give the key a recognizable name (for example, "Production sync") and choose
    the agent it should act on. A key is scoped to one agent.
  </Step>

  <Step title="Grant permissions">
    Select which operations the key may perform. See
    [Permission scopes](#permission-scopes) below.
  </Step>

  <Step title="Save and copy the secret">
    Save the key. Copy the **API key** and **secret** immediately and store them
    securely — treat the secret like a password.
  </Step>
</Steps>

<Warning>
  Store the API key and secret in a secure secret manager or environment variable.
  Never commit them to source control or expose them in client-side (browser) code —
  the Open API is a server-to-server interface. If a key is exposed, delete it in
  **Settings → API Permissions** and create a new one. Deleting a key immediately
  revokes access for any application using it.
</Warning>

## Authenticate a request

Send both the key and the secret as headers on every request:

```http theme={null}
X-API-Key: your-api-key
X-API-Secret: your-api-secret
Content-Type: application/json
```

If either header is missing, the request is rejected with a message asking for the
`x-api-key` and `x-api-secret` headers.

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://api.a2v2.ai/v1/open/contacts/chatbots/<AGENT_ID>" \
      -H "X-API-Key: your-api-key" \
      -H "X-API-Secret: your-api-secret"
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    import axios from "axios";

    const a2v2 = axios.create({
      baseURL: "https://api.a2v2.ai/v1/open",
      headers: {
        "X-API-Key": process.env.A2V2_API_KEY,
        "X-API-Secret": process.env.A2V2_API_SECRET,
        "Content-Type": "application/json",
      },
    });

    const { data } = await a2v2.get(`/contacts/chatbots/${agentId}`);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os, requests

    BASE = "https://api.a2v2.ai/v1/open"
    headers = {
        "X-API-Key": os.environ["A2V2_API_KEY"],
        "X-API-Secret": os.environ["A2V2_API_SECRET"],
        "Content-Type": "application/json",
    }

    resp = requests.get(f"{BASE}/contacts/chatbots/{agent_id}", headers=headers)
    resp.raise_for_status()
    data = resp.json()
    ```
  </Tab>
</Tabs>

<Note>
  `https://api.a2v2.ai` is the production API base URL
  (see [API Overview](/api/overview#base-url)). Replace `<AGENT_ID>` with the ID of the
  agent the key is scoped to.
</Note>

## Permission scopes

Each key is granted permissions per resource, with separate **create**, **read**,
**update**, and **delete** actions. A request that needs a permission the key
doesn't have is rejected.

| Scope                                                  | Covers                                                   | Actions                      |
| ------------------------------------------------------ | -------------------------------------------------------- | ---------------------------- |
| **Contact Access** (`contacts`)                        | CRM contacts and contact files for the agent             | create, read, update, delete |
| **Document Extraction Access** (`document-extraction`) | AI extraction of structured data from uploaded documents | create, read                 |

<Note>
  Grant the narrowest set of actions a key actually needs. A read-only reporting
  integration, for example, only needs **read** on Contact Access.
</Note>

## Key settings

When you create or edit a key, you can also configure:

| Setting         | What it controls                                       | Notes                                                                        |
| --------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------- |
| **Name**        | A label to identify the key                            | Required                                                                     |
| **Description** | Free-text note on the key's purpose                    | Optional                                                                     |
| **Permissions** | The scopes and actions above                           | At least one required                                                        |
| **Rate limits** | Requests per minute / per hour                         | Defaults 60/min and 1,000/hour; configurable up to 1,000/min and 10,000/hour |
| **Allowed IPs** | Restrict use to specific IPv4 addresses or CIDR ranges | Optional; leave unset to allow any IP                                        |
| **Expiry**      | A date after which the key stops working               | Optional                                                                     |

## Scoping and isolation

* A key only works for the agent it's scoped to. Calling another agent's endpoint
  with the wrong key is rejected.
* Keys are scoped to your organization's data only — there is no cross-tenant
  access.
* Usage is tracked per key, so you can review activity in the dashboard.

## Troubleshooting

<AccordionGroup>
  <Accordion title="401 / 'API key and secret are required'">
    Both `X-API-Key` and `X-API-Secret` headers must be present and spelled exactly.
    Confirm your client isn't dropping custom headers on redirects.
  </Accordion>

  <Accordion title="403 / permission denied">
    The key lacks the required scope or action. Edit the key in **Settings → API
    Permissions** and grant the needed permission (for example, **create** on
    Contact Access to create contacts).
  </Accordion>

  <Accordion title="Requests work from one server but not another">
    The key may have an **Allowed IPs** restriction. Add the new server's IP, or
    remove the restriction.
  </Accordion>

  <Accordion title="A key suddenly stopped working">
    Check whether it reached its **expiry** date or was deleted. Create a new key
    and update your integration's stored credentials.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="API Overview" icon="circle-info" href="/api/overview">
    Base URL, response format, and rate limits.
  </Card>

  <Card title="Endpoints" icon="list" href="/api/endpoints">
    Every Open API endpoint, grouped by domain.
  </Card>

  <Card title="API keys in Settings" icon="key" href="/settings/api-keys">
    Manage keys from the dashboard.
  </Card>

  <Card title="CRM Contacts" icon="address-book" href="/crm/contacts">
    Understand the contact data your API reads and writes.
  </Card>
</CardGroup>
