Skip to main content

Authentication

Stateway uses API keys for authentication. Every API request must include a valid API key in the X-API-Key header.

API Key Format​

Stateway API keys follow a prefixed format:

sw_live_abc123...

The sw_live_ prefix identifies the key as a Stateway live key. All API keys are hashed at rest.

Registering a Tenant​

Registration is a two-step process: submit your details, then verify your email address.

Step 1 — Submit registration​

Request:

curl -X POST https://api.stateway.io/v1/register \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"email": "admin@acmecorp.com"
}'

Response:

{
"data": {
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "pending_verification",
"message": "A 6-digit verification code has been sent to your email. It is valid for 10 minutes."
}
}

An optional slug field can be provided. If omitted, it is derived from name.

Step 2 — Verify email and get your API key​

Request:

curl -X POST https://api.stateway.io/v1/register/verify \
-H "Content-Type: application/json" \
-d '{
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"verificationCode": "482910"
}'

Response:

{
"data": {
"tenant": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "Acme Corp",
"slug": "acme-corp",
"email": "admin@acmecorp.com",
"plan": "free"
},
"apiKey": {
"id": "9a8b7c6d-...",
"key": "sw_live_Kx9mN2pQ4rT7vY1w...",
"prefix": "sw_live_Kx9m",
"name": "Default API Key",
"scopes": ["admin"],
"createdAt": "2026-04-26T12:00:00.000Z"
}
}
}
warning

The key value is only shown once at this step. Store it securely — you cannot retrieve it later.

Making Authenticated Requests​

Include the API key in every request:

Request:

curl https://api.stateway.io/v1/definitions \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..."

Response:

{
"data": [
{
"id": "def_01j...",
"key": "expense-approval",
"version": 1,
"name": "Expense Approval",
"source_type": "json",
"is_active": true,
"created_at": "2026-04-26T12:00:00.000Z"
}
]
}

How Tenant Resolution Works​

Stateway implements multitenancy by API key. When a request arrives with a valid X-API-Key header:

  1. The key is validated and looked up
  2. The associated tenant is resolved automatically
  3. All subsequent operations are scoped to that tenant

You never need to pass tenant_id in request bodies, query parameters, or URLs. The API key handles tenant resolution transparently.

API Key Scopes​

Each API key has a list of scopes that controls what it can do. The admin scope grants full access. Scoped keys allow least-privilege access per integration.

ScopeAccess
definitions:readRead process and decision definitions
definitions:writeCreate, update, delete definitions
instances:readRead instances, tokens, variables, history
instances:writeStart, suspend, resume, terminate instances; update variables; send events
tasks:readRead human tasks
tasks:writeClaim, unclaim, complete, delegate tasks
webhooks:manageCreate, update, delete webhook subscriptions
credentials:readList and inspect credential metadata
credentials:writeCreate, rotate, delete credentials
adminFull access to all operations

The first key created on registration has the admin scope. When creating additional keys, pass only the scopes needed.

Managing API Keys​

List API Keys​

Request:

curl https://api.stateway.io/v1/auth/keys \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..."

Response:

{
"data": [
{
"id": "9a8b7c6d-...",
"prefix": "sw_live_Kx9m",
"name": "Default API Key",
"scopes": ["admin"],
"created_at": "2026-04-26T12:00:00.000Z",
"last_used_at": "2026-04-27T08:30:00.000Z"
}
]
}

Create Additional API Keys​

Request:

curl -X POST https://api.stateway.io/v1/auth/keys \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..." \
-H "Content-Type: application/json" \
-d '{
"name": "CI/CD Pipeline",
"scopes": ["definitions:write", "instances:write"]
}'

Response:

{
"data": {
"id": "a1b2c3d4-...",
"key": "sw_live_newkey...",
"prefix": "sw_live_newk",
"name": "CI/CD Pipeline",
"scopes": ["definitions:write", "instances:write"],
"createdAt": "2026-04-27T09:00:00.000Z"
}
}

Revoke an API Key​

Request:

curl -X DELETE https://api.stateway.io/v1/auth/keys/{key_id} \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..."

Returns 204 No Content. Revoked keys are immediately invalid. Any in-flight requests using a revoked key will receive a 401 UNAUTHORIZED response.

API key cache

Stateway caches API key lookups for up to 60 seconds. A revoked key may continue to work for up to 60 seconds after revocation due to this cache.

Tenant Management​

Get Current Tenant​

Request:

curl https://api.stateway.io/v1/tenant \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..."

Response:

{
"data": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "Acme Corp",
"slug": "acme-corp",
"email": "admin@acmecorp.com",
"plan": "free"
}
}

Update Tenant Settings​

Request:

curl -X PUT https://api.stateway.io/v1/tenant \
-H "X-API-Key: sw_live_Kx9mN2pQ4rT7vY1w..." \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Corp (Updated)" }'

Response:

{
"data": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "Acme Corp (Updated)",
"slug": "acme-corp",
"email": "admin@acmecorp.com",
"plan": "free"
}
}

Error Responses​

StatusError CodeDescription
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENValid key but insufficient permissions

Example 401 response:

{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}

Best Practices​

  • Rotate keys regularly — revoke old keys and create new ones
  • Use separate keys per environment (development, staging, production)
  • Use separate keys per integration (web app, CI/CD, monitoring)
  • Never commit keys to source control — use environment variables
  • Never log API keys — they are the equivalent of tenant credentials