What you can rely on
Workspace isolation
Every credential belongs to exactly one workspace, and everything it can read or write is inside that workspace (API overview).GET /v1/workspaces shows a key exactly one. Lookups check ownership before they answer: a recording, a secret or a key that belongs to another workspace is reported as not found, and nothing is signed or revealed for it. A tool or connection name is checked only inside its own workspace, so a name used elsewhere is never disclosed (Call recordings, Secrets and request signing, Migration and changelog).
When you build an integration, treat not_found on an id you were given as “not yours or not there”, and do not retry it with a different credential in the hope of a different answer.
Credentials
For API keys, theAuthorization header value is Bearer <api-key>. Replace <api-key> with your key and never put that value in a URL or log.
- API keys. Send
Authorization: Bearer sempera_sk_.... The secret is shown once, when the key is created. Sempera stores only a one-way hash of it, as the privacy policy describes.DELETE /v1/api-keys/{id}revokes a key immediately. No other header or scheme is recognised, and a key presented anywhere outside/v1is ignored (Authentication and credentials). - Kinds cap what a key may hold. A runtime or CI key is never more than a viewer, whoever minted it, and a CI key is read-only. A key is never minted above the role of the person who minted it.
- Browsers never hold an API key. Your server calls
POST /v1/sessionsand hands the browser a token bound to one room. It expires in 30 minutes and lets the browser do nothing but join that conversation (Authentication and credentials, Sessions and calls). - People sign in to the App, not the API. The App’s session cookie is host-only,
HttpOnlyandSecure, carries a CSRF check on writes, and is not a credential for the API host (Authentication and credentials). - Rate limits are 600 requests a minute per key and 60 a minute per address for routes that need no credential (Errors and limits).
DELETE /v1/api-keys/{id} or in the Sempera App, then mint a replacement.
Secrets in tools and connections
A tool’s credential is a reference to a named workspace secret, never a value. A connection’s provider credentials are never returned by any read, a published agent version never shows a secret, and the App does not display a secret again after it is saved (Tools and integrations, Secrets and request signing). A secret you delete takes its stored value with it.Signed requests and signed events
- Outbound events carry
X-Sempera-Signature, an HMAC-SHA256 over{t}.{body}with a five-minute tolerance. Verify it with a constant-time comparison before you trust the body. The recipe and a known-answer vector are in Webhooks. - Delivery is guarded. Before an event is sent, the destination host is resolved and the connection is pinned to the address that was checked. An address inside a private network is refused and a redirect counts as a failed attempt. An endpoint URL with a private address literal, embedded credentials or a bad port is refused when you save it (Webhooks, Migration and changelog).
- Requests Sempera makes in your name can also carry a short-lived signed token that you verify against a published key set. It is an owner setting (Secrets and request signing).
Calls, recordings and consent
- Disclosure. Every agent says plainly that it is an AI when a caller asks whether it is a person, and never claims to be one. Whether it also says it is an AI virtual assistant at the start of every call is the agent’s AI disclosure setting, off by default and chosen by the workspace owner, who is responsible for the disclosure laws that apply to their calls. When calls are recorded, the opening always carries the recording notice, whatever that setting says (Migration and changelog).
- Recording is the workspace owner’s choice. Whether calls are recorded, how long a recording is kept, legal holds and deletion are owner settings in the App. The API reports the state of each recording (Call recordings).
- Playback is gated.
GET /v1/recordings/{recording_id}signs a link valid for 5 minutes, only for a recording your workspace owns. The link works for the signed-in member it was issued to and nobody else. An API key never receives audio. Every link issued and every play is recorded in the workspace’s audit log. - Outbound calls need a stated basis.
POST /v1/callsrecords aconsent_basis, refuses a number on the workspace’s do-not-contact list, and respects the call limits the owner set (Sessions and calls, Owner features in the App). - Deleted means gone from the reads. An export never contains a deleted transcript, and the stored bodies of
call.completedandcall.outcomesdeliveries lose the words read from a call once its transcript is deleted (Owner features in the App, Migration and changelog).
Public pages hold no workspace data
These pages are public and need no key. Every example in them is invented: a demonstration agent, made-up ids and digests, numbers in the reserved fictional range, and placeholders where a secret would go. If you find a real customer name, number or key in any page, report it as described below.Reporting a problem
Write to hello@sempera.org. That mailbox is the contact named in the privacy policy and in the OpenAPI document. Include theX-Request-Id of the response you are asking about, which every response carries, and describe what you saw. Do not send secrets, call audio or personal information in the first message. This page promises no response time and no reward programme.