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
Never ship an embed key to a browser
An embed key selects the customer it acts for. Anyone who reads it from your page source can act as every customer you have. Mint a session token instead — it is a one-line call and the token cannot be widened.
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"
}
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
Request headers
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:
Give Sandbox its own key
Anything that should only ever touch Sandbox, such as a test harness or a partner's trial integration, should hold a Sandbox-only key. Even if that key leaks, it cannot reach Production.
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.
Pick a stable id
Use an identifier that won't change — your internal customer id rather than a company name. Changing the scope key later means the customer reconnects their accounts.
Origin allowlist
List the sites where your product shows the catalog in Embed settings.
A wildcard covers exactly one level of subdomain.
List your sites before you embed
Until you add your site, the catalog does not load there, even with a valid session token, and neither do requests your pages make to the API directly (with the SDK or your own code). Your server-side calls, which send no Origin, are unaffected.
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.
Referrer policy
Firefox reports the page through its referrer until the component has started the frame. A plain <iframe> with referrerpolicy="no-referrer" is refused in Firefox. Use the web component, or leave the referrer policy at its default.
A rejected origin returns 403 with a message naming the origin.
Errors
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 —
mintSessionTokenand the rest of the client
Something not behaving as described? support@work.studio