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

# Authentication

> How to authenticate with the Answering Agent Partner API using API keys.

## Overview

The Answering Agent Partner API uses **API keys** for authentication. API keys are simple, secure tokens that identify your partner account and authorize access to manage customer organizations, users, and locations.

Use `https://answeringagent.com/api/v1` as the permanent production base URL. Existing integrations that still call the legacy `api.answeringagent.com` hostname are redirected for compatibility, but new integrations should call the permanent URL directly.

<Note>
  This documentation covers the **Partner API** for building integrations. If you're looking to embed the Answering Agent dashboard in your application, see the [Embed Guide](/advanced/embed) after completing initial setup.
</Note>

***

## How Authentication Works

1. **Generate an API Key** from your Answering Agent partner dashboard
2. **Include the key** in the `X-API-KEY` header for every API request
3. **Access granted** - The API key identifies your partner account and provides access to your customer organizations

That's it! No complex signing, no HMAC calculations, no timestamps. Just a simple API key in the request header.

***

## Obtaining Your API Key

<Steps>
  <Step title="Sign in to your partner dashboard">
    Log in to the Answering Agent dashboard with your partner account credentials.
  </Step>

  <Step title="Navigate to API Keys settings">
    Go to **Settings → API Keys** in the dashboard navigation.
  </Step>

  <Step title="Generate a new key">
    Click **Generate New Key**. The key is displayed **once**—copy it immediately.
  </Step>

  <Step title="Store securely">
    Save the key in your backend environment variables or secrets manager. Never expose it in client-side code.
  </Step>
</Steps>

<Warning>
  API keys are shown only once when created. If you lose a key, you'll need to generate a new one and update your integration.
</Warning>

<img src="https://mintcdn.com/answeringagent/r3cbDc_5SaGGF_HO/images/api-keys.png?fit=max&auto=format&n=r3cbDc_5SaGGF_HO&q=85&s=f19b2c64a12a520a944c00adabd6219f" alt="API Keys" width="3488" height="2002" data-path="images/api-keys.png" />

***

## Using Your API Key

Include your API key in the `X-API-KEY` header for every request to the Partner API:

```bash theme={null}
curl -X GET "https://answeringagent.com/api/v1/organizations" \
  -H "X-API-KEY: sk_live_AbCdEfGhIjKlMnOpQrSt" \
  -H "Content-Type: application/json"
```

### Required Header

<ParamField header="X-API-KEY" type="string" required>
  Your API key from the partner dashboard. All partner API endpoints require this header.
</ParamField>

***

## Response Codes

| Status  | Meaning          | Typical Cause                                                    |
| ------- | ---------------- | ---------------------------------------------------------------- |
| 200/201 | Success          | Request completed successfully                                   |
| 401     | Unauthorized     | Missing or invalid `X-API-KEY` header                            |
| 403     | Forbidden        | API key valid but lacks permission for this resource             |
| 404     | Not Found        | Resource doesn't exist or doesn't belong to your partner account |
| 422     | Validation Error | Request data is invalid or incomplete                            |
| 500     | Server Error     | Unexpected error on our side - contact support                   |

***

## Understanding Token Types

Answering Agent uses different authentication methods for different purposes. As a partner integrator, you only need to worry about **API Keys**.

| Token Type      | You Need This For                               | How to Get It                                          |
| --------------- | ----------------------------------------------- | ------------------------------------------------------ |
| **API Key**     | Managing customer organizations via Partner API | Dashboard → Settings → API Keys                        |
| **Embed Token** | Embedding dashboards in your application        | API endpoint `/api/v1/users/{external_id}/embed-token` |

<Note>
  You may see references to "Bearer tokens" or login endpoints in our API. These are for internal use by the Answering Agent dashboard and are not needed for partner integrations.
</Note>

***

## Example Integration

Here's a complete example of authenticating and creating your first customer organization:

<Tabs>
  <Tab title="cURL" value="curl" default>
    ```bash theme={null}
    # Store your API key securely
    API_KEY="sk_live_AbCdEfGhIjKlMnOpQrSt"
    BASE_URL="https://answeringagent.com/api/v1"

    # Create a customer organization with owner
    curl -X POST "${BASE_URL}/organizations" \
      -H "X-API-KEY: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Acme Corporation",
        "description": "A technology company",
        "owner": {
          "external_id": "user_123",
          "email": "john@acme.com",
          "name": "John Doe"
        }
      }'
    ```
  </Tab>

  <Tab title="JavaScript" value="javascript">
    ```javascript theme={null}
    const API_KEY = process.env.ANSWERING_AGENT_API_KEY;
    const BASE_URL = 'https://answeringagent.com/api/v1';

    async function createOrganization(orgData) {
      const response = await fetch(`${BASE_URL}/organizations`, {
        method: 'POST',
        headers: {
          'X-API-KEY': API_KEY,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(orgData)
      });

      if (!response.ok) {
        throw new Error(`API error: ${response.status}`);
      }

      return response.json();
    }

    // Usage
    const result = await createOrganization({
      name: 'Acme Corporation',
      description: 'A technology company',
      owner: {
        external_id: 'user_123',
        email: 'john@acme.com',
        name: 'John Doe'
      }
    });

    console.log('Organization created:', result.organization);
    console.log('Owner user:', result.owner);
    ```
  </Tab>

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

    API_KEY = os.getenv('ANSWERING_AGENT_API_KEY')
    BASE_URL = 'https://answeringagent.com/api/v1'

    def create_organization(org_data):
        response = requests.post(
            f'{BASE_URL}/organizations',
            headers={
                'X-API-KEY': API_KEY,
                'Content-Type': 'application/json'
            },
            json=org_data
        )
        response.raise_for_status()
        return response.json()

    # Usage
    result = create_organization({
        'name': 'Acme Corporation',
        'description': 'A technology company',
        'owner': {
            'external_id': 'user_123',
            'email': 'john@acme.com',
            'name': 'John Doe'
        }
    })

    print(f"Organization created: {result['organization']}")
    print(f"Owner user: {result['owner']}")
    ```
  </Tab>

  <Tab title="PHP" value="php">
    ```php theme={null}
    <?php

    $apiKey = getenv('ANSWERING_AGENT_API_KEY');
    $baseUrl = 'https://answeringagent.com/api/v1';

    function createOrganization($orgData) {
        global $apiKey, $baseUrl;

        $ch = curl_init("$baseUrl/organizations");
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => [
                "X-API-KEY: $apiKey",
                'Content-Type: application/json'
            ],
            CURLOPT_POSTFIELDS => json_encode($orgData)
        ]);

        $response = curl_exec($ch);
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($statusCode !== 201) {
            throw new Exception("API error: $statusCode");
        }

        return json_decode($response, true);
    }

    // Usage
    $result = createOrganization([
        'name' => 'Acme Corporation',
        'description' => 'A technology company',
        'owner' => [
            'external_id' => 'user_123',
            'email' => 'john@acme.com',
            'name' => 'John Doe'
        ]
    ]);

    echo "Organization created: " . print_r($result['organization'], true);
    echo "Owner user: " . print_r($result['owner'], true);
    ```
  </Tab>
</Tabs>

***

## Security Best Practices

| Practice                                | Why It Matters                                                                  |
| --------------------------------------- | ------------------------------------------------------------------------------- |
| **Never expose keys in client code**    | API keys grant full access to your partner account. Keep them server-side only. |
| **Use environment variables**           | Store keys in `.env` files or secrets managers, never in source code.           |
| **Rotate keys periodically**            | Generate new keys every 6-12 months to limit exposure risk.                     |
| **Use separate keys per environment**   | Different keys for development, staging, and production isolate issues.         |
| **Revoke compromised keys immediately** | If a key is exposed, revoke it in the dashboard and generate a new one.         |
| **Monitor API usage**                   | Watch for unexpected patterns that might indicate unauthorized access.          |

***

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="Can I use the same key for multiple environments?">
    While technically possible, we recommend generating separate API keys for development, staging, and production environments. This makes it easier to rotate keys and debug issues without affecting production traffic.
  </Accordion>

  <Accordion title="What happens if my API key is compromised?">
    Immediately revoke the compromised key in **Settings → API Keys** and generate a new one. Update your integration with the new key. The old key will stop working immediately after revocation.
  </Accordion>

  <Accordion title="Can I expose my API key in client-side JavaScript?">
    No! API keys should only be used from your backend servers. Exposing them in browser JavaScript would allow anyone to access your partner account and manage your customer organizations.
  </Accordion>

  <Accordion title="How is this different from the /api/auth/login endpoint?">
    The `/api/auth/login` endpoint is used internally by the Answering Agent dashboard for user logins. As a partner, you use API keys with the `/api/v1/*` endpoints instead. You don't need to worry about the login endpoint.
  </Accordion>

  <Accordion title="Do I need to sign my requests with HMAC or timestamps?">
    No. Simply include your API key in the `X-API-KEY` header. No additional signing or cryptographic operations are required.
  </Accordion>

  <Accordion title="What if I need to give customers access to their dashboard?">
    Use embed tokens! After creating a customer organization, retrieve an embed token for the owner user and embed our dashboard in your application. See the [Embed Guide](/advanced/embed) for details.
  </Accordion>

  <Accordion title="Can I have multiple API keys active at once?">
    Yes! You can generate multiple API keys and they will all work simultaneously. This is useful for key rotation (generate new key, update systems, then revoke old key) or for different services.
  </Accordion>
</AccordionGroup>

***

## Next Steps

Now that you understand authentication, you're ready to start building your integration:

<CardGroup cols={2}>
  <Card title="Organizations" icon="building" href="/v1/organizations">
    Create and manage customer organizations
  </Card>

  <Card title="Users" icon="users" href="/v1/users">
    Add users to organizations
  </Card>

  <Card title="Locations" icon="map-pin" href="/v1/locations">
    Set up phone numbers and locations
  </Card>

  <Card title="Quickstart Guide" icon="rocket" href="/v1/quickstart">
    Build your first integration in 5 minutes
  </Card>
</CardGroup>

***

## Support

If you have questions about authentication or need help with your integration:

* **Email**: [support@answeringagent.com](mailto:support@answeringagent.com)
