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

# API introduction

> Authenticate with the REST API and start building

The Famulor REST API lets you manage the same customer resources available in the dashboard, including assistants, calls, campaigns, transcripts, knowledge, and workspace settings.

<Tip>
  For a multi-step business process — enrich a lead, then call, then update a CRM, then notify a channel — an [Automation](/automations/overview) is often less code to maintain than wiring the steps together yourself. Reach for the API directly when you need simple, immediate, programmatic control, like triggering a single call from your own app.
</Tip>

## Base URL

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

If you use a white-label domain, replace `app.famulor.io` with that domain. The paths stay the same.

## API Access

REST requests require **API Access** through your workspace plan or a recurring add-on. If access is removed, existing API keys and OAuth credentials stay available to workspace administrators for review and revocation, but regular `/api/v1` requests return `403 api_access_required`.

After a failed plan payment, `POST /api/v1/billing/invoice-payment` and `POST /api/v1/billing/portal` remain available with a valid credential so an owner can recover billing. Authentication, role, and scope checks still apply.

## Authentication

Send a Bearer token in the `Authorization` header:

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

Two credential types are supported:

* **Workspace API keys** (`fam_...`) — create them under **Settings → API & MCP** for server-to-server integrations. The full key is shown once. The dashboard has no scope picker, so a key created there always carries every scope. To mint a narrower key, call `POST /api/v1/api-keys` or `POST /api/v1/workspaces/{workspace_id}/api-keys` with an explicit `scopes` array — the new key's scopes must be a subset of the credential that creates it.
* **OAuth 2.0 access tokens** (`fam_at_...`) — use Authorization Code with PKCE-S256 for applications acting on behalf of a signed-in user.

User-authorised access follows the user's current workspace membership and role. Workspace API keys continue to follow their own status and scopes until an authorised workspace admin revokes them.

<Warning>
  Treat API keys like passwords. Never embed them in browser or mobile application code; use OAuth for user-facing applications.
</Warning>

### Key hygiene

* Store keys in environment variables or a secrets manager, never in source control.
* Scope each key to only what the integration needs — a key that only reads calls shouldn't also have `assistants:write`. Dashboard-created keys are always full-access; use the API path above to mint a scoped one.
* Rotate keys periodically and immediately after anyone with access to one leaves the team.
* Revoking a key from **Settings → API & MCP** takes effect immediately; requests already in flight may still complete.

### OAuth client requirements

A hand-built client drives the authorization and token endpoints directly:

```text theme={null}
https://app.famulor.io/api/oauth/authorize
https://app.famulor.io/api/oauth/token
```

Use HTTPS redirect URLs. Native applications may also use literal loopback HTTP addresses such as `127.0.0.1`. OAuth authorization requests must use PKCE-S256 and request only scopes registered for the client. When a request is rate-limited, retry after the delay indicated by the response.

The client either uses credentials pre-approved for your workspace, or registers itself dynamically with `POST /api/oauth/register` — supply between 1 and 10 unique `redirect_uris`. Endpoints, supported scopes, and grant types are discoverable at `/.well-known/oauth-authorization-server`.

Access tokens are renewed with the `refresh_token` grant. Refresh tokens rotate on every use: requesting a new access token also issues a new refresh token and immediately invalidates the one you sent.

## Response format

Successful responses wrap the result in `data` and may include `meta`:

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

Responses contain customer-facing workspace data only. Secrets are never returned after they are saved, and sensitive values are masked where useful. Recordings are provided through temporary links. Usage and billing are reported in the minutes and credits shown in your account.

## Pagination

List endpoints use `limit` and `offset`:

| Parameter | Default | Maximum | Description               |
| --------- | ------- | ------- | ------------------------- |
| `limit`   | `50`    | `200`   | Number of items to return |
| `offset`  | `0`     | —       | Number of items to skip   |

Use `meta.pagination.total` to determine whether more pages are available.

## Errors

Failures return a stable code and a readable message:

```json theme={null}
{
  "error": {
    "code": "invalid_request",
    "message": "A destination phone number is required."
  }
}
```

| Status | Code                  | Meaning                                             |
| ------ | --------------------- | --------------------------------------------------- |
| `400`  | `invalid_request`     | Invalid request body or parameters                  |
| `401`  | `unauthorized`        | Missing, invalid, expired, or revoked credential    |
| `403`  | `forbidden`           | The scope, role, or plan does not allow the action  |
| `403`  | `api_access_required` | API Access is not available for this workspace      |
| `404`  | `not_found`           | Resource not found or not visible to this workspace |
| `409`  | `conflict`            | The resource is in a conflicting state              |
| `429`  | `rate_limited`        | Too many requests; wait and retry                   |
| `500`  | `internal_error`      | Unexpected error                                    |

## White-label customer management

Authorised resellers can use the `platform` endpoints to manage their own end customers, issue and revoke customer API tokens, transfer credits, and manage their custom domain. These endpoints require the `platform:read` or `platform:write` scopes; custom-domain operations use the corresponding settings scope.

| Endpoint                                        | Purpose                                                         |
| ----------------------------------------------- | --------------------------------------------------------------- |
| `GET /api/v1/platform/users`                    | List your end customers                                         |
| `POST /api/v1/platform/users`                   | Register an end customer                                        |
| `GET /api/v1/platform/users/{user_id}`          | Read an end customer's account summary                          |
| `POST /api/v1/platform/users/{user_id}/token`   | Issue an API token for that customer                            |
| `POST /api/v1/platform/users/login`             | Authenticate a customer                                         |
| `POST /api/v1/platform/users/{user_id}/logout`  | Revoke that customer's API tokens                               |
| `POST /api/v1/platform/users/{user_id}/balance` | Transfer credits between your reseller balance and the customer |
| `GET /api/v1/custom-domain`                     | Read custom-domain status                                       |
| `POST /api/v1/custom-domain`                    | Add a custom domain and receive the required DNS records        |
| `POST /api/v1/custom-domain/verify`             | Check DNS and activate a ready domain                           |
| `DELETE /api/v1/custom-domain`                  | Remove the custom domain                                        |

See the [White Label API guide](/admin/whitelabel-api) for examples.

## MCP

The same customer-facing capabilities are available as AI tools through the [MCP endpoint](/mcp/overview):

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

MCP uses the same API keys, OAuth consent, scopes, and workspace access. Its availability is controlled separately by **Connect AI / MCP**, not by API Access.
