Security
Company isolation
Section titled “Company isolation”Every read is filtered by the company on the access token. The company comes from the token claim, never from a request parameter, so there is no input that widens the scope of a credential.
Resources are addressed by opaque, prefixed identifiers (mtg_, call_,
usr_, tpl_) that are allocated per company. Internal sequential ids are never
exposed, so record volume cannot be inferred and ids cannot be enumerated.
An identifier your company does not own returns 404, never 403 — the API does
not confirm that a resource exists elsewhere.
Ownership is resolved when you read
Section titled “Ownership is resolved when you read”A record belongs to the default company of the user who owns it, evaluated at query time rather than frozen when the record was created.
The consequence is worth stating plainly: if a user’s default company changes, their historical records move with them. A rep who moves between companies in the same group takes their meeting history to the new company’s API.
This is a deliberate trade-off of not denormalising ownership onto the record. If that behaviour does not fit your data agreement, raise it with your Salesbud contact before building on it.
Transcripts are gated separately
Section titled “Transcripts are gated separately”transcriptions.read is a distinct scope from meetings.read and calls.read,
and a credential can hold the collection scopes without it. A transcript is the
most sensitive payload the API serves — verbatim customer speech — so access to
the metadata of a meeting does not imply access to what was said in it.
The gate composes rather than replacing the collection scope: a transcript
request is checked against both, so a credential limited to calls cannot reach a
meeting transcript by holding transcriptions.read.
Transcript text is sanitised before it leaves the service.
Everything is audited
Section titled “Everything is audited”Every business read is recorded: which credential, which company, which route, which resource ids, and the calling identity.
The audit write is fail closed. If the trail cannot be written, the read is
not returned — you get 503 AUDIT_UNAVAILABLE instead. A successful response
therefore means the access was recorded.
Credential hygiene
Section titled “Credential hygiene”- Secrets are stored only as HMAC-SHA256 hashes with a service-side pepper. They cannot be read back, only rotated.
- Rotation keeps the previous secret valid for seven days so you can deploy without downtime; revoke it once the new one is live.
- On a suspected leak, revoke the client — that invalidates issued tokens immediately. Rotation does not, because the old secret stays valid.
- Set an IP allowlist when your integration runs from fixed addresses. It is enforced at token issuance and on every request, so a leaked token is useless from elsewhere.
What never leaves the service
Section titled “What never leaves the service”Stack traces, source paths, internal ids, tokens, secrets and request bodies are never returned in a response, and never written to logs.