Authentication & Scopes
Authentication scheme
There are three distinct authentication paths, depending on who is calling whom:
-
Your system → Smartbtn (REST API calls):
every request carries
Authorization: Bearer <token>. The token resolves server-side to a widget-scoped identity and its granted scopes; access is deny-by-default -- a request without the required scope is rejected with403. Each token is also subject to its own rate limit, reported viaX-RateLimit-Limit/X-RateLimit-Remaining/X-RateLimit-Resetresponse headers. -
Smartbtn → your system (webhooks / external AI operator):
outgoing requests are signed with a per-tenant secret and carry an
X-Smartbtn-Signature: sha256=<signature>header so you can verify the body was sent by Smartbtn and not tampered with in transit. An optional bearer credential may be included as well if your integration requires one. - Your external AI operator → Smartbtn (async reply callback): the async-reply endpoint uses its own signed frame, pinned to your AI-operator identity and widget, keyed by a durable causation id rather than a short-lived nonce -- see Endpoints for the request shape.
Never put a token in the URL (e.g. ?api_token=...) -- URLs are
logged in more places than headers are. Always use the
Authorization header.
Safe writes and AI setup
Send X-Smartbtn-Idempotency-Key on every POST/PATCH/PUT/DELETE: a new UUID for a new operation, the same key for the same operation. This is a safe client convention, not global server-side UUID validation. Required operations carry x-idempotency: required in OpenAPI; the reference lists exact DELETE exemptions and the separate causation_id contract for AI replies. On a required operation, a missing key returns 400 and reuse within 24 hours returns 409, not a cached successful response. Read state after uncertainty; never automatically change the key, and respect Retry-After. On 405 for a documented method, stop and report the method, path and status without the token; do not seek alternate writes.
To configure your widget, choose the “AI setup” preset: widget:read, widget:write, ai:read, ai:write, ai:apply, kb:read, kb:write, files:write, stats:read. It replaces the entire scope selection. Grant ai:credentials:write separately only when the owner authorizes provider credential setup. Account, billing and partner rights are unnecessary. Enable “Allow widget API (JS and REST)”; issuing a token does not enable this switch.
https://smartbtn.ru/api/v1 and https://smartbtn.me/api/v1 serve the same API and project data. A different embed domain does not mean a different widget. Choose a verified base URL; send the token only in Authorization directly to that host and never automatically forward it on redirects.
Scopes
Every token carries an explicit list of scopes. The canonical registry has 40 grantable scopes: 39 are operational (38 route-required and one conditional) and one is reserved but unavailable. A request only succeeds if the token has the route scope and any conditional scope selected by its body. The Endpoints page is authoritative for what is callable today; granting a reserved scope creates no endpoint.
| Scope | Grants |
|---|---|
chats:read | Read chats and their metadata. |
chats:write | Close, transfer, or request a rating for a chat. |
messages:read | Read a chat's message history. |
messages:write | Send messages, typing indicators, and read receipts as an agent. |
contacts:read | Read contacts. |
contacts:write | Update contact fields and attributes. |
agents:read | Read agent/operator info and presence. |
tags:read | Read tags. |
tags:write | Attach tags to a contact. |
files:read | Download a previously uploaded file. |
files:write | Upload a new file. |
stats:read | Read aggregate chat/message/rating statistics. |
channels:read | Read a custom channel's online status. |
channels:write | Deliver an inbound message on a custom channel. |
webhooks:read | List your webhook subscriptions. |
webhooks:write | Create, delete, or redeliver a webhook subscription. |
responder:inject sensitive | Inject a reply into a live chat as an external AI operator/bot. |
responder:escalate sensitive | Conditional on POST /v1/ai/replies: permit caller-directed handoff via escalate=true or [KEY_TO_OPERATOR]. Empty replies and platform safety floors do not require it. |
channels:register sensitive | Register a new custom channel (gated to installed apps only). |
widget:read | Read widget appearance, behaviour, and embed settings. |
widget:write | Update widget settings and purge the served widget cache. |
agents:write sensitive | Invite, update, suspend, restore, or remove agents. An invitation creates a new person with operator-console access to every chat on this widget. |
agents:events:read | Read an agent's activity/event log and per-agent metrics. |
departments:read | Read departments, their agents, and their schedules. |
departments:write | Create, update, or delete departments and their schedules. |
messengers:read | Read which messenger and social channels are connected (never their credentials). |
messengers:write sensitive | Connect or disconnect a messenger channel. Writes provider credentials and repoints provider-side webhook registration. |
ai:read | Read AI assistants, their configuration, and AI alerts. |
ai:write sensitive | Create and update AI assistants, AI settings, and AI operators. This includes the persona and system prompt the bot speaks to your customers under. |
ai:credentials:write sensitive | Store third-party LLM provider credentials that the platform then uses for outbound calls. |
ai:apply sensitive | Approve an improvement that rewrites a live assistant's persona/system prompt. |
kb:read | Read knowledge-base rules and ingested sources. |
kb:write | Create, update, or delete knowledge-base rules and ingestion sources. |
transcripts:read | Export a chat transcript. |
account:read | Read the owning account's profile and all of its legal entities, including those used by sibling widgets. |
account:write | Update only the owning account's name, surname, and phone; legal entities are not writable here. |
billing:read | Read this widget's billing records and the owning account's account-wide legal entities. |
billing:write sensitive | Create, update, or delete the owning account's account-wide legal entities. It does not issue invoices or move money. |
partners:read | Read partner/referral account data. |
partners:withdraw sensitive | reserved_unavailable: no payout operation consumes this scope in the current API, so granting it is currently inert. |
The scopes marked sensitive above let a token act as (or
hand off to) another operator on your behalf, invite a new person into your
operator console, write third-party credentials, rewrite a live
assistant's persona, or select another high-impact action -- grant them to a
self-issued token only if you actually need that operational capability.
partners:withdraw remains marked sensitive for any future review,
but it is reserved and has no callable operation today.
Signature rotation
The outbound signature header is versioned independently of the API path
version, e.g. X-Smartbtn-Signature: sha256=v1:<hex hmac>.
When you rotate your per-tenant signing secret, both the old and the new
secret remain valid for a short overlap window so in-flight deliveries
signed with the old secret still verify -- there is no moment where every
delivery fails. Revoking a token or secret, on the other hand, takes effect
immediately.
Keeping credentials safe
Treat your API token and any webhook signing secret as passwords: never commit them to source control, never log them, and never pass a token as a URL query parameter. If a token or secret leaks, contact support to revoke it and have a new one issued -- a compromised credential cannot be "changed" in place, only replaced.