Authentication

Three credentials, each with a different job. Getting them right is the difference between a safe embed and a leaked one.


The three credentials

Credential Prefix Where it belongs What it can do
Embed key svx_ik_ Your server only Act as any of your customers; mint session tokens
Session token svx_st_ The browser Act as exactly one customer, until it expires
Customer MCP key svx_mk_ Your customer's AI assistant Use that customer's own connections, on the MCP endpoint only

Minting a session token

POST https://api.work.studio/api/v1/workflow/embed/session-tokens
Authorization: Bearer svx_ik_…
X-Embed-Tenant: <your tenant id>
Content-Type: application/json

{ "scopeKey": "customer:acme", "ttlSeconds": 900 }
{
  "token": "svx_st_eyJhbGciOiJIUzI1NiJ9…",
  "expiresAt": "2026-09-15T18:45:00Z",
  "scopeKey": "customer:acme"
}
Field Required Notes
scopeKey Yes The customer this token acts for
ttlSeconds No Default 900, minimum 60, maximum 3600

Only an embed key can mint a token. A session token cannot mint another one.

The scope is signed into the token, so a browser cannot change which customer it acts for — unlike a header, which anyone can edit. So is the environment: send X-Embed-Env when minting to choose it (see Environments).


Request headers

Header Purpose
Authorization Bearer <embed key or session token>
X-Embed-Tenant Your tenant id
X-Embed-Env Environment id, when you use more than one
X-Embed-Scope The customer to act for. Only honoured with an embed key — with a session token the scope comes from the token

Environments

A workspace has more than one environment, typically Sandbox and Production, and each keeps its own activations, connections and automations.

Session tokens belong to one environment: the one you name with X-Embed-Env when you mint it, or your default environment if you name none. A browser holding a token for Sandbox cannot reach Production.

Embed keys come in two kinds, both made in Embed settings:

Key Acts in
All environments Any environment of your workspace. Name the one you want with X-Embed-Env.
One environment That environment only. Calls naming another environment, and tokens minted for one, are refused with 401.

Rotating or revoking one key leaves your other keys working.


Customer scope

A scope key is your own identifier for a customer, written as customer:<your id>.

Everything is keyed to it: connected accounts, credentials, activations, automations, assistant conversations and MCP keys. Two customers of yours cannot see each other's data, and a token for one cannot reach the other.


Origin allowlist

List the sites where your product shows the catalog in Embed settings.

Pattern Matches Does not match
https://app.acme.com that exact origin anything else
https://*.acme.com https://portal.acme.com https://a.b.acme.com

A wildcard covers exactly one level of subdomain.

When it applies:

  • The web component and the iframe — the catalog frame reports the page it is shown on, as the browser gives it, and that page must be on your list. If the frame is nested, every page above it must be. A frame that cannot tell where it is shown is refused.
  • Requests your pages make directly — checked by their Origin, whichever credential they use.
  • Requests with no Origin — your own backend — are not checked, so configuring an allowlist never breaks server-to-server calls.
  • MCP keys — never checked; an AI assistant has no browser origin.

A rejected origin returns 403 with a message naming the origin.


Errors

Status Meaning
401 Missing, malformed or expired credential
403 Origin not allowed, or the credential lacks the scope for that call
404 The integration, activation or connector doesn't exist for this customer

Session tokens expire. Treat a 401 in the browser as "fetch a new token from my server", not as an error to show your customer.


Next steps

  • Quick start — the whole flow end to end
  • SDK — mintSessionToken and the rest of the client

Something not behaving as described? support@work.studio