Hostnames
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). They carry no workspace data.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
Compatibilitytag. These pages name each one, the contract covers it, and it changes only under the deprecation policy in Migration and changelog. - Compatibility routes carry the
Compatibilitytag. They are thin facades, at/v1/compat/..., under/v2and 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.jsonis their contract.
/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).
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 areapplication/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 carriesX-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 acceptIdempotency-Key. See Errors and limits.
Tenancy
Every credential belongs to one workspace. Everything it can read or write is inside that workspace; an id from another workspace answersnot_found, the same as an id that never existed.