> ## 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.

# Quickstart Guide

> Get started with the Answering Agent Partner API in 5 minutes

Get your first customer organization up and running with AI phone answering in under 5 minutes!

## What You'll Build

By the end of this guide, you'll have:

* ✅ An authenticated API connection
* ✅ A customer organization created
* ✅ A phone number provisioned with AI answering
* ✅ An embed token to display the dashboard

***

## Prerequisites

<Steps>
  <Step title="Partner Account">
    You need a partner account with Answering Agent. If you don't have one, [contact us](mailto:support@answeringagent.com) to get started.
  </Step>

  <Step title="API Key">
    Sign in to your partner dashboard and generate an API key at **Settings → API Keys**. Copy it somewhere safe!
  </Step>

  <Step title="Development Environment">
    You can use any language or tool that makes HTTP requests. We'll show examples in cURL, JavaScript, and Python.
  </Step>
</Steps>

***

## Step 1: Test Your API Key

First, let's verify your API key works by listing your organizations:

<Tabs>
  <Tab title="cURL" value="curl" default>
    ```bash theme={null}
    # Set your API key
    export API_KEY="sk_live_YourApiKeyHere"

    # Test the connection
    curl -X GET "https://answeringagent.com/api/v1/organizations" \
      -H "X-API-KEY: $API_KEY" \
      -H "Content-Type: application/json"
    ```
  </Tab>

  <Tab title="JavaScript" value="javascript">
    ```javascript theme={null}
    // Set your API key (use environment variables in production!)
    const API_KEY = 'sk_live_YourApiKeyHere';
    const BASE_URL = 'https://answeringagent.com/api/v1';

    // Test the connection
    const response = await fetch(`${BASE_URL}/organizations`, {
      headers: {
        'X-API-KEY': API_KEY,
        'Content-Type': 'application/json'
      }
    });

    const organizations = await response.json();
    console.log('Your organizations:', organizations);
    ```
  </Tab>

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

    # Set your API key (use environment variables in production!)
    API_KEY = 'sk_live_YourApiKeyHere'
    BASE_URL = 'https://answeringagent.com/api/v1'

    # Test the connection
    response = requests.get(
        f'{BASE_URL}/organizations',
        headers={
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
        }
    )

    organizations = response.json()
    print('Your organizations:', organizations)
    ```
  </Tab>
</Tabs>

**Expected Response:**

```json theme={null}
[]
```

An empty array is perfect! It means your API key is working and you have no organizations yet.

<Note>
  If you get a 401 error, double-check that your API key is correct and you're using the `X-API-KEY` header (not `Authorization`).
</Note>

***

## Step 2: Create Your First Organization

Now let's create an organization for a customer. We'll create the organization and its owner user in a single API call:

<Tabs>
  <Tab title="cURL" value="curl" default>
    ```bash theme={null}
    curl -X POST "https://answeringagent.com/api/v1/organizations" \
      -H "X-API-KEY: $API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Pizza Palace",
        "description": "A local pizzeria serving Denver since 1995",
        "owner": {
          "external_id": "customer_001",
          "email": "maria@pizzapalace.com",
          "name": "Maria Rodriguez"
        }
      }'
    ```
  </Tab>

  <Tab title="JavaScript" value="javascript">
    ```javascript theme={null}
    const orgResponse = await fetch(`${BASE_URL}/organizations`, {
      method: 'POST',
      headers: {
        'X-API-KEY': API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'Pizza Palace',
        description: 'A local pizzeria serving Denver since 1995',
        owner: {
          external_id: 'customer_001',  // Your system's ID for this user
          email: 'maria@pizzapalace.com',
          name: 'Maria Rodriguez'
        }
      })
    });

    const { organization, owner } = await orgResponse.json();
    console.log('Organization created!', organization);
    console.log('Owner user created!', owner);

    // Save this for next steps
    const ORG_ID = organization.id;
    const USER_EXTERNAL_ID = owner.external_id;
    ```
  </Tab>

  <Tab title="Python" value="python">
    ```python theme={null}
    org_response = requests.post(
        f'{BASE_URL}/organizations',
        headers={
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
        },
        json={
            'name': 'Pizza Palace',
            'description': 'A local pizzeria serving Denver since 1995',
            'owner': {
                'external_id': 'customer_001',  # Your system's ID for this user
                'email': 'maria@pizzapalace.com',
                'name': 'Maria Rodriguez'
            }
        }
    )

    data = org_response.json()
    organization = data['organization']
    owner = data['owner']

    print('Organization created!', organization)
    print('Owner user created!', owner)

    # Save this for next steps
    ORG_ID = organization['id']
    USER_EXTERNAL_ID = owner['external_id']
    ```
  </Tab>
</Tabs>

**Expected Response:**

```json theme={null}
{
  "organization": {
    "id": 123,
    "name": "Pizza Palace",
    "created_at": "2025-01-24T10:30:00Z",
    "updated_at": "2025-01-24T10:30:00Z"
  },
  "owner": {
    "id": 456,
    "external_id": "customer_001",
    "name": "Maria Rodriguez",
    "email": "maria@pizzapalace.com",
    "created_at": "2025-01-24T10:30:00Z",
    "updated_at": "2025-01-24T10:30:00Z"
  }
}
```

🎉 **Great!** You've created your first organization with an owner user. Note the `organization.id` - you'll need it for the next step.

<Tip>
  The `external_id` is **your** system's ID for this user. Use it to link this Answering Agent user to your database. All future API calls can use this ID instead of the internal Answering Agent user ID.
</Tip>

***

## Step 3: Add a Phone Number

Now let's provision a phone number for this organization:

<Tabs>
  <Tab title="cURL" value="curl" default>
    ```bash theme={null}
    # Replace 123 with your organization ID from step 2
    ORG_ID=123

    curl -X POST "https://answeringagent.com/api/v1/locations" \
      -H "X-API-KEY: $API_KEY" \
      -H "Content-Type: application/json" \
      -d "{
        \"organization_id\": $ORG_ID,
        \"name\": \"Main Location\",
        \"address\": \"123 Main St, Denver, CO 80202\",
        \"area_code\": \"303\"
      }"
    ```
  </Tab>

  <Tab title="JavaScript" value="javascript">
    ```javascript theme={null}
    const locationResponse = await fetch(`${BASE_URL}/locations`, {
      method: 'POST',
      headers: {
        'X-API-KEY': API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        organization_id: ORG_ID,  // From step 2
        name: 'Main Location',
        address: '123 Main St, Denver, CO 80202',
        area_code: '303'  // Denver area code
      })
    });

    const { location } = await locationResponse.json();
    console.log('Phone number provisioned!', location.phone_number);
    ```
  </Tab>

  <Tab title="Python" value="python">
    ```python theme={null}
    location_response = requests.post(
        f'{BASE_URL}/locations',
        headers={
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
        },
        json={
            'organization_id': ORG_ID,  # From step 2
            'name': 'Main Location',
            'address': '123 Main St, Denver, CO 80202',
            'area_code': '303'  # Denver area code
        }
    )

    location = location_response.json()['location']
    print('Phone number provisioned!', location['phone_number'])
    ```
  </Tab>
</Tabs>

**Expected Response:**

```json theme={null}
{
  "location": {
    "id": 789,
    "name": "Main Location",
    "phone_number": "+13035551234",
    "status": "active",
    "address": "123 Main St, Denver, CO 80202",
    "created_at": "2025-01-24T10:35:00Z",
    "updated_at": "2025-01-24T10:35:00Z"
  }
}
```

📞 **Awesome!** The phone number is now active and ready to receive calls with AI answering!

***

## Step 4: Get an Embed Token

Finally, let's get an embed token so your customer can access their dashboard:

<Tabs>
  <Tab title="cURL" value="curl" default>
    ```bash theme={null}
    # Replace with your user's external_id from step 2
    USER_EXTERNAL_ID="customer_001"

    curl -X GET "https://answeringagent.com/api/v1/users/$USER_EXTERNAL_ID/embed-token" \
      -H "X-API-KEY: $API_KEY"
    ```
  </Tab>

  <Tab title="JavaScript" value="javascript">
    ```javascript theme={null}
    const tokenResponse = await fetch(
      `${BASE_URL}/users/${USER_EXTERNAL_ID}/embed-token`,
      {
        headers: { 'X-API-KEY': API_KEY }
      }
    );

    const { embed_token } = await tokenResponse.json();
    console.log('Embed token:', embed_token);

    // Use this token to embed the dashboard in your app
    const embedUrl = `https://answeringagent.com/embed?token=${embed_token}`;
    console.log('Embed URL:', embedUrl);
    ```
  </Tab>

  <Tab title="Python" value="python">
    ```python theme={null}
    token_response = requests.get(
        f'{BASE_URL}/users/{USER_EXTERNAL_ID}/embed-token',
        headers={'X-API-KEY': API_KEY}
    )

    embed_token = token_response.json()['embed_token']
    print('Embed token:', embed_token)

    # Use this token to embed the dashboard in your app
    embed_url = f'https://answeringagent.com/embed?token={embed_token}'
    print('Embed URL:', embed_url)
    ```
  </Tab>
</Tabs>

**Expected Response:**

```json theme={null}
{
  "embed_token": "MTIzNDV8ZDgyZDk3Mzg1OTAxNTkzNA",
  "user_id": "customer_001"
}
```

🔑 **Perfect!** You now have an embed token that lets your customer access their Answering Agent dashboard.

***

## Complete Example

Here's the entire flow in one script:

<Tabs>
  <Tab title="JavaScript" value="javascript" default>
    ```javascript theme={null}
    const API_KEY = 'sk_live_YourApiKeyHere';  // Use env vars in production!
    const BASE_URL = 'https://answeringagent.com/api/v1';

    async function onboardCustomer() {
      try {
        // 1. Create organization with owner
        console.log('Creating organization...');
        const orgResponse = await fetch(`${BASE_URL}/organizations`, {
          method: 'POST',
          headers: {
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            name: 'Pizza Palace',
            description: 'A local pizzeria serving Denver since 1995',
            owner: {
              external_id: 'customer_001',
              email: 'maria@pizzapalace.com',
              name: 'Maria Rodriguez'
            }
          })
        });
        const { organization, owner } = await orgResponse.json();
        console.log('✓ Organization created:', organization.id);

        // 2. Add phone number
        console.log('Provisioning phone number...');
        const locationResponse = await fetch(`${BASE_URL}/locations`, {
          method: 'POST',
          headers: {
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            organization_id: organization.id,
            name: 'Main Location',
            address: '123 Main St, Denver, CO 80202',
            area_code: '303'
          })
        });
        const { location } = await locationResponse.json();
        console.log('✓ Phone number provisioned:', location.phone_number);

        // 3. Get embed token
        console.log('Generating embed token...');
        const tokenResponse = await fetch(
          `${BASE_URL}/users/${owner.external_id}/embed-token`,
          { headers: { 'X-API-KEY': API_KEY } }
        );
        const { embed_token } = await tokenResponse.json();
        console.log('✓ Embed token generated');

        // Return data for your system
        return {
          organizationId: organization.id,
          phoneNumber: location.phone_number,
          embedToken: embed_token,
          embedUrl: `https://answeringagent.com/embed?token=${embed_token}`
        };
      } catch (error) {
        console.error('Error:', error);
        throw error;
      }
    }

    // Run it!
    onboardCustomer().then(result => {
      console.log('\n🎉 Success! Customer onboarded:');
      console.log(result);
    });
    ```
  </Tab>

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

    API_KEY = 'sk_live_YourApiKeyHere'  # Use env vars in production!
    BASE_URL = 'https://answeringagent.com/api/v1'

    def onboard_customer():
        headers = {
            'X-API-KEY': API_KEY,
            'Content-Type': 'application/json'
        }

        # 1. Create organization with owner
        print('Creating organization...')
        org_response = requests.post(
            f'{BASE_URL}/organizations',
            headers=headers,
            json={
                'name': 'Pizza Palace',
                'description': 'A local pizzeria serving Denver since 1995',
                'owner': {
                    'external_id': 'customer_001',
                    'email': 'maria@pizzapalace.com',
                    'name': 'Maria Rodriguez'
                }
            }
        )
        org_response.raise_for_status()
        org_data = org_response.json()
        organization = org_data['organization']
        owner = org_data['owner']
        print(f'✓ Organization created: {organization["id"]}')

        # 2. Add phone number
        print('Provisioning phone number...')
        location_response = requests.post(
            f'{BASE_URL}/locations',
            headers=headers,
            json={
                'organization_id': organization['id'],
                'name': 'Main Location',
                'address': '123 Main St, Denver, CO 80202',
                'area_code': '303'
            }
        )
        location_response.raise_for_status()
        location = location_response.json()['location']
        print(f'✓ Phone number provisioned: {location["phone_number"]}')

        # 3. Get embed token
        print('Generating embed token...')
        token_response = requests.get(
            f'{BASE_URL}/users/{owner["external_id"]}/embed-token',
            headers=headers
        )
        token_response.raise_for_status()
        embed_token = token_response.json()['embed_token']
        print('✓ Embed token generated')

        # Return data for your system
        return {
            'organization_id': organization['id'],
            'phone_number': location['phone_number'],
            'embed_token': embed_token,
            'embed_url': f'https://answeringagent.com/embed?token={embed_token}'
        }

    # Run it!
    if __name__ == '__main__':
        try:
            result = onboard_customer()
            print('\n🎉 Success! Customer onboarded:')
            print(result)
        except Exception as error:
            print(f'Error: {error}')
    ```
  </Tab>
</Tabs>

***

## Already-Owned Organizations: Multi-Account Viewer Flow

The quickstart above provisions organizations owned by your partner account. If your customers already own their Answering Agent organizations, use the owner-linked viewer flow instead:

1. The customer owner accepts the partner link.
2. The owner or an organization admin grants your partner account dashboard-viewer management.
3. Create one identity with `POST /users` and an approved linked `organization_id`, or reuse an existing identity with `PUT /organizations/{organization_id}/dashboard-viewers/{external_id}`.
4. Request `GET /users/{external_id}/embed-token?organization_id={organization_id}`.
5. Put that compact token in a single `/dashboard/embed` iframe. Request a different scoped token and replace the iframe `src` when the account manager switches organizations.

```bash theme={null}
# Attach an existing partner identity to an independently approved organization
curl -X PUT -H "X-API-KEY: $API_KEY" \
  https://answeringagent.com/api/v1/organizations/456/dashboard-viewers/account-manager-42

# Issue the token for exactly that organization
curl -H "X-API-KEY: $API_KEY" \
  "https://answeringagent.com/api/v1/users/account-manager-42/embed-token?organization_id=456"
```

<Warning>
  The scoped viewer is organization-wide and read-only. It cannot change settings, manage members or roles, call mutation endpoints, or trigger recurring AI/model work. Detach or owner-side revocation invalidates stale scoped authority without removing access to other organizations.
</Warning>

***

## What's Next?

You've successfully onboarded your first customer! Here's what you can do next:

<CardGroup cols={2}>
  <Card title="Embed the Dashboard" icon="frame" href="/advanced/embed">
    Learn how to embed the Answering Agent dashboard in your application
  </Card>

  <Card title="Add More Users" icon="users" href="/v1/users">
    Add team members to the organization
  </Card>

  <Card title="Customize AI Settings" icon="robot" href="/v1/organizations">
    Configure the AI agent's behavior and responses
  </Card>

  <Card title="Explore All Endpoints" icon="book" href="/v1/organizations">
    See the complete API reference
  </Card>
</CardGroup>

***

## Troubleshooting

### "Invalid credentials" Error

* Double-check your API key is correct
* Make sure you're using the `X-API-KEY` header (not `Authorization: Bearer`)
* Verify your partner account is active

### "Organization not found" Error

* Make sure you're using the correct organization ID
* Verify the organization belongs to your partner account
* Check that the organization wasn't deleted

### Phone Number Not Provisioning

* Ensure the `area_code` is valid (3 digits, US/Canada)
* Some area codes may have limited availability
* Try a different area code if provisioning fails

### Embed Token Not Working

* Verify the user's `external_id` is correct
* Make sure the user belongs to the organization
* For multi-organization viewers, include the intended `organization_id` when requesting the token
* Check that the owner-approved viewer grant and partner link remain active
* Ensure the scoped relationship has not been detached or rotated

***

## Need Help?

We're here to help you succeed:

* **Technical Support**: [support@answeringagent.com](mailto:support@answeringagent.com)
* **Documentation Issues**: Report on GitHub or email support
* **Integration Questions**: Our team is happy to jump on a call

Happy building! 🚀
