Skip to main content

Multitenancy

Stateway implements multitenancy by API key. Every resource is isolated per tenant, and the API key automatically handles tenant resolution.

How It Works

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 any API request. The API key handles tenant resolution transparently.

Data Isolation

Every resource in Stateway is scoped to a tenant:

ScenarioResult
Tenant A lists definitionsOnly sees Tenant A's definitions
Tenant A queries instance by ID404 if instance belongs to Tenant B
Tenant A tries to complete Tenant B's task404 — task not found
Tenant A evaluates Tenant B's decision404 — decision not found

There are no cross-tenant operations exposed through the API.

Registration Flow

Registration is a two-step process to verify email ownership.

Step 1 — Register

Request:

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

Response:

{
"data": {
"tenantId": "ten_01j...",
"message": "Verification code sent to admin@acme.com"
}
}

A 6-digit verification code is sent to the provided email. The slug field is optional — if omitted, Stateway generates one from the name.

Step 2 — Verify

Request:

curl -X POST https://api.stateway.io/v1/register/verify \
-H "Content-Type: application/json" \
-d '{
"tenantId": "ten_01j...",
"verificationCode": "482931"
}'

Response:

{
"data": {
"tenant": {
"id": "ten_01j...",
"name": "Acme Corp",
"slug": "acme"
},
"apiKey": "sw_live_...",
"scopes": ["admin"]
}
}

The API key is returned only once at this point. Store it securely — it cannot be retrieved again.

Multiple API Keys per Tenant

A single tenant can have multiple API keys — useful for different environments, integrations, or scoped permissions:

Request:

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

Response:

{
"data": {
"id": "key_01j...",
"key": "sw_live_...",
"name": "CI/CD Pipeline",
"scopes": ["definitions:write", "instances:read"],
"created_at": "2026-04-26T12:00:00.000Z"
}
}

The key value is returned only at creation time.

List API Keys

Request:

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

Response:

{
"data": [
{
"id": "key_01j...",
"name": "Production App",
"scopes": ["admin"],
"last_used_at": "2026-04-26T14:00:00.000Z",
"expires_at": null,
"revoked_at": null
}
]
}

The key value itself is never returned in list or get responses.

Revoke an API Key

Request:

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

Returns 204 No Content.

warning

API keys are cached for up to 60 seconds. A revoked key may remain valid for up to 60 seconds after revocation.

Tenant Management

Get Current Tenant

Request:

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

Response:

{
"data": {
"id": "ten_01j...",
"name": "Acme Corp",
"slug": "acme",
"email": "admin@acme.com",
"status": "active",
"created_at": "2026-04-26T12:00:00.000Z"
}
}

Update Tenant Settings

Request:

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

Response:

{
"data": {
"id": "ten_01j...",
"name": "Acme Corp (Updated)",
"slug": "acme",
"email": "admin@acme.com",
"status": "active",
"created_at": "2026-04-26T12:00:00.000Z"
}
}

Best Practices

  • One tenant per organization — don't create multiple tenants for the same company
  • Use separate API keys per environment — production, staging, CI/CD each get their own key
  • Use scoped keys — grant only the scopes needed; reserve admin-scoped keys for privileged operations
  • Rotate keys regularly — revoke old keys and create new ones periodically
  • Never log API keys — they are the equivalent of tenant credentials
  • Account for revocation latency — keys are cached for up to 60 seconds; time-sensitive revocation should account for this window