Skip to content

API reference

API

This page covers what applies to every call. The calls themselves are described where you use them: Run an automation, Incoming webhooks, API keys and, for an App, the App SDK and the workstudio CLI, which make the calls for you.

https://api.work.studio/api/v1/workflow/

Every path in these docs is relative to it, for example POST /api/v1/workflow/execute/{endpoint}.

Caller Send
Your backend, with an API key X-API-Key: svx_tk_… (organization key) or svx_ck_… (customer key). Add X-Scope-Key: customer:acme to act for one customer with an organization key.
A short-lived token for one customer Authorization: Bearer <accessToken> from the token exchange
Embed Authorization: Bearer svx_ik_… or svx_st_… plus X-Embed-Tenant. See Embed authentication.

If a request carries both a bearer token and an API key, the bearer token is used.

Most errors come back as one flat JSON object:

{
"timestamp": "2026-10-21T17:04:12.345Z",
"status": 400,
"error": "Bad Request",
"message": "…what went wrong…",
"path": "/api/v1/workflow/run/6f1c2a9e-…",
"service": "…",
"details": null
}
  • error is the HTTP reason phrase.
  • message says what went wrong.
  • details maps each field to its problem when the request body fails validation.

There is no separate error code field. Branch on the HTTP status.

A few places answer in their own shape:

  • A refused API key (401 or 403) gets the server’s default error body.
  • The OAuth token exchange answers in the standard OAuth form, { "error": …, "error_description": … }.
  • Incoming webhooks answer security refusals with { "ERROR": "…" }.
  • The refusals for an organization that requires MFA, below, use the same OAuth form.

An organization can require two-factor authentication for its members (see Account security). A request made with a member’s work.studio sign-in token is then refused unless that sign-in included a code:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="insufficient_user_authentication", error_description="This organization requires two-factor authentication", acr_values="mfa"
{
"error": "mfa_required",
"error_description": "This organization requires two-factor authentication. Sign in again with the code from your authenticator app.",
"acr_values": "mfa",
"tenantId": "…"
}

Refreshing the token doesn’t help, because a refreshed token comes from the same sign-in. Send the person through sign-in again with prompt=login&acr_values=mfa on the authorization request. That sign-in always asks for a code, or has them set one up. Then retry with the new token. If the retry is refused the same way within a few minutes, show the error instead of sending them round again.

Two related answers:

  • 503 with "error": "mfa_policy_unavailable" means the organization’s sign-in policy couldn’t be checked. Retry shortly.
  • 403 with "error": "tenant_mismatch" means the organization in the path, such as /tenants/{tenantId}/…, isn’t the one the request selected.

API keys, tokens from the token exchange, embed credentials, service accounts and App SDK end users are never refused for this.

The general API publishes no per-key rate limit. Each incoming webhook has its own limit, set on the webhook (see Incoming webhooks), and your plan limits how many automations run at once.