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

# API overview

> Hostnames, versioning, IDs, JSON, timestamps, request ids, tracing.

## Hostnames

| Hostname | What it is |
| - | - |
| `sempera.org` | The company |
| `app.sempera.org` | The Sempera App, the product a customer signs in to |
| `api.sempera.org` | The Sempera API, the one developer surface |

There is exactly one API hostname. The App's own browser traffic goes to `app.sempera.org/api/*`, a same-origin routing layer for its session cookie; it is not a second API and nothing outside the App should call it.

## Versioning

The API major version is in the path: `/v1` for Sempera-native resources. It is not the Agent's version. An Agent's published configuration versions are `agent_version` resources under `/v1/agents/{id}/versions`.

The `/v2` paths that exist today are compatibility facades for observed console traffic. They are intentionally thin, keep the same credential and workspace boundary as `/v1`, and do not introduce a second source of truth. A future Sempera-native `/v2` would ship with a deprecation notice, a migration guide and a sunset date for `/v1`, published in the changelog. Nothing is removed from `/v1` silently.

## Routes that need no credential

These routes answer anyone, at the anonymous limit of 60 requests a minute per address ([Errors and limits](https://docs.sempera.org/errors-and-limits.md)). They carry no workspace data.

| Route | What it answers |
| - | - |
| `GET /v1` | The API's front door: its version and links to the contract and the guide pages. |
| `GET /v1/health` | Liveness: `ok`, the API version, the build and the environment. |
| `GET /openapi.json` | The OpenAPI 3.1 contract, generated from the running route table. |
| `GET /llms.txt` | The map of these pages for coding agents. |
| `GET /robots.txt` | The search policy of the API host. |
| `GET /docs/{page}` | A guide page as Markdown. The `.md` suffix is optional. |
| `GET /v2/models` | The speech models Sempera publishes, as the model list many client libraries expect ([Sessions and calls](https://docs.sempera.org/sessions-and-calls.md)). |
| `GET /v1/workspaces/{workspace_id}/.well-known/jwks.json` | A workspace's public signing keys, for a receiver that verifies a signed request ([Secrets and request signing](https://docs.sempera.org/secrets-and-signing.md)). |
| `POST /v1/phone-onboarding/start` | Starts a Sempera Phone sign-up link an assistant shows its owner. It grants nothing ([Personal phone plan](https://docs.sempera.org/phone-plan.md)). |
| `POST /v1/phone-onboarding/poll` | Whether the owner approved that link. Only after the owner approves does it hand over one limited credential, once ([Personal phone plan](https://docs.sempera.org/phone-plan.md)). |

`GET /v1/me` needs a credential, but any class of credential may call it; without one it answers `401 authentication_required`. The routes that Sempera's service providers call are not in this table; the next section says why.

## Supported routes and compatibility routes

`openapi.json` groups every operation by tag. Two kinds are worth telling apart.

* **Supported routes** are everything outside the `Compatibility` tag. These pages name each one, the contract covers it, and it changes only under the deprecation policy in [Migration and changelog](https://docs.sempera.org/changelog.md).
* **Compatibility routes** carry the `Compatibility` tag. They are thin facades, at `/v1/compat/...`, under `/v2` and elsewhere, that answer in the shapes other consoles use so that a client built for those shapes keeps working. They use the same credential and the same workspace boundary as every other route and read the same records, so they add no second source of truth. These pages do not name each one: `openapi.json` is their contract.

Provider ingress, a few routes under `/v1/webhooks` that a telephony carrier or the payment provider calls, is a third group. It needs no Sempera credential because each route carries its provider's own proof. It is not part of the integration contract, these pages do not list its routes, and you never call it ([Webhooks](https://docs.sempera.org/webhooks.md)).

## IDs

IDs are opaque strings. Agent ids are Sempera's own stable slugs (never a voice or telephony provider's identifier). Keys, workspaces, calls and webhook endpoints are UUIDs. Sessions carry the id the runtime recorded them under. Do not parse ids.

## JSON, timestamps, objects

Requests and responses are `application/json` (uploads are `multipart/form-data`). Timestamps are UTC ISO-8601. Most Sempera-native resources carry an `object` field naming their type, and most Sempera-native lists are `{"object": "list", "data": [...], "has_more": bool, "next_cursor": string|null}`. Compatibility facade endpoints keep their observed external envelopes instead; the OpenAPI `Compatibility` tag and the route-specific schemas are the source of truth for those shapes.

## Request ids and tracing

Every response carries `X-Request-Id`, minted by Sempera. A value you send in `X-Request-Id` is echoed back as `X-Client-Request-Id`. A W3C `traceparent` header is echoed back unchanged.

## Idempotency

Writes where a duplicate would be dangerous accept `Idempotency-Key`. See [Errors and limits](https://docs.sempera.org/errors-and-limits.md).

## Tenancy

Every credential belongs to one workspace. Everything it can read or write is inside that workspace; an id from another workspace answers `not_found`, the same as an id that never existed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.