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

# API introduction

> Authenticate against the REST API and start building

The OurAiCalling platform exposes a REST API under your platform domain. Everything you can do in the dashboard — managing assistants, starting calls, running campaigns, reading transcripts — is available programmatically.

## Base URL

```text theme={null}
https://app.famulor.io/api/v1
```

`app.famulor.io` is the hosted platform. If you sign in on a white-label tenant domain, use that domain instead — the API runs under it with the tenant's branding and the same paths apply.

## Authentication

All requests require a Bearer token in the `Authorization` header. Two token types are accepted:

* **Service-account API keys** (`fam_...`) — create them under **Settings → API Keys**. Each new key belongs to a dedicated, non-human principal instead of the admin who created it. The full key is shown exactly once; only a hash is stored. Every new key has explicit scopes from the canonical registry (for example `assistants:read`, `calls:write`, `campaigns:write`, `dashboards:read`, `knowledge:write`, `voices:read`, or `billing:read`). Best for server-to-server integrations.
* **OAuth 2.0 access tokens** (`fam_at_...`) — issued through Authorization Code with mandatory PKCE-S256. Scoped and short-lived (1 hour, with rotating refresh tokens). Best for third-party apps acting on behalf of a user.

User-bound credentials are revoked in the same database transaction when a member is removed, demoted, or suspended. Workspace suspension revokes all workspace credentials. A service-account key is independent of the creating admin's membership and remains governed by its own status and scopes.

```bash theme={null}
curl https://app.famulor.io/api/v1/assistants \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX"
```

<Warning>
  Treat API keys like passwords. Never embed them in client-side code — for browser use cases, use the OAuth flow instead.
</Warning>

### OAuth client security

Dynamic clients may register HTTPS redirect URIs. Native applications may additionally use HTTP redirect URIs on literal loopback addresses (`127.0.0.1` or `[::1]`) with any port. `localhost`, non-loopback HTTP, URI fragments, and credentials in redirect URIs are rejected.

Authorization requests must send `code_challenge_method=S256` and a valid SHA-256 code challenge. Requested scopes must be both canonical and a subset of the scopes registered for that client. Dynamic registration, authorization, and token exchange are protected by distributed rate limits; a limited request returns `429` with `Retry-After`.

## Response envelope

Every endpoint returns a consistent JSON envelope. Successful responses wrap the payload in `data` (plus optional `meta`):

```json theme={null}
{
  "data": [ { "id": "…", "name": "Support Agent" } ],
  "meta": { "pagination": { "limit": 50, "offset": 0, "total": 1 } }
}
```

## What the API returns — and what it doesn't

Both the REST API and the MCP endpoint return the same, deliberately curated view of your workspace data: everything you need to build on, nothing about how the platform runs internally.

Not included in any response:

* **Infrastructure identifiers** — media-session, room, trunk, dispatch and carrier identifiers of the underlying telephony stack.
* **Internal storage paths** — recordings are served as time-limited signed URLs (`GET /calls/{id}/recording`), never as bucket paths.
* **Platform cost and billing internals** — provider costs, token/character/second counters and charge bookkeeping. Your own consumption is reported in the units you are billed in: minutes and credits (`GET /balance`, `GET /transactions`).
* **Model internals** — which model scored a call or wrote a summary. Verdicts, scores and summaries are returned; the engine behind them is not.
* **Secrets** — passwords, tokens and carrier credentials are never readable back after they are stored; you get a masked hint at most.
* **Operational diagnostics** — internal call events (component fallbacks, session errors, usage bookings) are filtered out of `GET /calls/{id}` events.

Everything else is fair game: transcripts, summaries, analysis verdicts, extracted fields, QA scores, contacts, campaigns, numbers, and your full assistant configuration.

## Pagination

List endpoints paginate with `limit` and `offset` query parameters:

| Parameter | Default | Max   | Description   |
| --------- | ------- | ----- | ------------- |
| `limit`   | `50`    | `200` | Page size     |
| `offset`  | `0`     | —     | Items to skip |

The response's `meta.pagination.total` carries the total number of matches (ignoring `limit`/`offset`), so you can page until `offset + limit >= total`:

```bash theme={null}
curl "https://app.famulor.io/api/v1/calls?limit=100&offset=200" \
  -H "Authorization: Bearer fam_XXXXXXXXXXXX"
```

## Errors

Failures return an error envelope with a stable machine-readable `code` and a human-readable `message`:

```json theme={null}
{
  "error": {
    "code": "invalid_request",
    "message": "\"to_number\" is required (E.164 format, e.g. +4930123456)."
  }
}
```

| Status | Code              | Meaning                                                                           |
| ------ | ----------------- | --------------------------------------------------------------------------------- |
| `400`  | `invalid_request` | Invalid request body or parameters                                                |
| `401`  | `unauthorized`    | Missing, invalid, expired or revoked token                                        |
| `403`  | `forbidden`       | Missing scope, or your plan does not include this feature                         |
| `404`  | `not_found`       | Resource not found (or not yours)                                                 |
| `409`  | `conflict`        | Resource is in a conflicting state (e.g. stopping a campaign that is not running) |
| `429`  | `rate_limited`    | Rate limit exceeded — back off and retry                                          |
| `500`  | `internal_error`  | Unexpected server error                                                           |

## Rate limits

Fair-use rate limits apply per account. If you exceed them the API responds with `429 Too Many Requests`; back off and retry with exponential delay. Published per-plan limits will be documented here.

## White label: manage your platform's customers

If your workspace has the white-label feature, a dedicated endpoint group lets you run your own platform programmatically: list and register your end-users, issue them API tokens (with or without their password), log them out, move credits between your wallet and theirs, and manage the custom domain your platform runs on. Platform admins on the root platform get the same endpoints, scoped to direct platform customers.

All of these require an API key of **your** white-label workspace with the `platform:read` / `platform:write` scopes (custom domain: `settings:*`):

| Endpoint                                                                                                           | What it does                                                                                             |
| ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| [`GET /platform/users`](/api-reference/white-label/list-platform-users)                                            | List your platform's end-users (paginated, searchable with `q`)                                          |
| [`POST /platform/users`](/api-reference/white-label/register-a-platform-user)                                      | Register a new end-user (invite email or preset password)                                                |
| [`GET /platform/users/{user_id}`](/api-reference/white-label/get-a-platform-user)                                  | User detail incl. workspaces and balances                                                                |
| [`POST /platform/users/{user_id}/token`](/api-reference/white-label/create-a-platform-user-token)                  | Issue an API token for a user — no password needed                                                       |
| [`POST /platform/users/login`](/api-reference/white-label/log-in-a-platform-user)                                  | Authenticate a user with email + password and receive their API token                                    |
| [`POST /platform/users/{user_id}/logout`](/api-reference/white-label/log-out-a-platform-user)                      | Revoke a user's API tokens                                                                               |
| [`POST /platform/users/{user_id}/balance`](/api-reference/white-label/transfer-credits-to-or-from-a-platform-user) | Transfer credits: positive = credit the customer from your wallet, negative = reclaim (never below zero) |
| [`GET /custom-domain`](/api-reference/settings/get-custom-domain-status)                                           | Custom domain status of your platform                                                                    |
| [`POST /custom-domain`](/api-reference/settings/add-custom-domain)                                                 | Connect a custom domain (returns the DNS records to set)                                                 |
| [`POST /custom-domain/verify`](/api-reference/settings/check-custom-domain-dns)                                    | Re-check DNS and activate the domain                                                                     |
| [`DELETE /custom-domain`](/api-reference/settings/remove-custom-domain)                                            | Remove the custom domain                                                                                 |

Step-by-step recipes (custom auth flows, dashboards, balance management): [White Label API guide](/admin/whitelabel-api). The same capabilities are available as MCP tools via the `platform` toolset (`https://<your-domain>/mcp?toolsets=platform`).

## MCP — use the API as AI tools

Everything in this reference is also exposed through the platform's **MCP endpoint** (Model Context Protocol, streamable HTTP):

```text theme={null}
https://app.famulor.io/mcp
```

Connect Claude, ChatGPT, Cursor, or any MCP client and use the same capabilities as AI tools — same services, same validation (plan limits, model catalog, DNC checks) and the same permission model (API keys or OAuth). Requires the **Connect AI / MCP** plan feature. Full setup guide: [MCP endpoint](/api/mcp).

**Quick connect** — Claude and ChatGPT discover authentication automatically (OAuth); other clients can pass an API key as a static Bearer header:

<CodeGroup>
  ```bash Claude Code theme={null}
  claude mcp add --transport http voice-ai https://app.famulor.io/mcp \
    --header "Authorization: Bearer fam_XXXXXXXXXXXX"
  ```

  ```json Cursor (~/.cursor/mcp.json) theme={null}
  {
    "mcpServers": {
      "voice-ai": {
        "url": "https://app.famulor.io/mcp",
        "headers": { "Authorization": "Bearer fam_XXXXXXXXXXXX" }
      }
    }
  }
  ```

  ```json mcp-remote (OAuth) theme={null}
  {
    "mcpServers": {
      "voice-ai": {
        "command": "npx",
        "args": ["mcp-remote", "https://app.famulor.io/mcp"]
      }
    }
  }
  ```
</CodeGroup>

### Available MCP tools

| Area               | Tools                                                                                                                                                                                                                        |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Assistants         | `list_assistants`, `get_assistant`, `create_assistant`, `update_assistant`, `delete_assistant`                                                                                                                               |
| Voices             | `get_voices`                                                                                                                                                                                                                 |
| Calls              | `list_calls`, `get_call`, `make_call`                                                                                                                                                                                        |
| History            | `list_history`, `get_email_history_item`                                                                                                                                                                                     |
| Workspace settings | `list_email_senders`, `get_custom_domain`, `add_custom_domain`, `verify_custom_domain`, `remove_custom_domain`, `get_memory_settings`, `update_memory_settings`, `get_ai_inference_settings`, `update_ai_inference_settings` |
| Campaigns          | `list_campaigns`, `get_campaign`, `create_campaign`, `update_campaign`, `delete_campaign`, `start_campaign`, `stop_campaign`                                                                                                 |
| Leads              | `list_leads`, `add_lead`, `add_leads`, `remove_lead_from_campaign`, `delete_lead` (legacy alias)                                                                                                                             |
| Phone numbers      | `list_phone_numbers`, `search_phone_numbers`, `buy_phone_number`, `release_phone_number`, `assign_phone_number`                                                                                                              |
| SIP trunks         | `list_sip_trunks`, `get_sip_trunk`, `create_sip_trunk`, `delete_sip_trunk`                                                                                                                                                   |
| Knowledge bases    | `list_knowledge_bases`, `get_knowledge_base`, `create_knowledge_base`, `delete_knowledge_base`, `add_document`                                                                                                               |
| Account & billing  | `get_balance`, `get_me`, `get_usage_summary`                                                                                                                                                                                 |
| API keys           | `list_api_keys`, `create_api_key`, `revoke_api_key`                                                                                                                                                                          |
| White label        | `list_platform_users`, `get_platform_user`, `register_platform_user`, `create_platform_user_token`, `logout_platform_user`, `transfer_platform_credits`                                                                      |
