POST /api/chain/state-machines
Spin up a state machine. The caller's ZID becomes the owner. The handler auto-mints a zsm_… API key with admin scope and returns it once in the response body — only its SHA-256 is persisted server-side. If you lose the raw key, mint a new one from the portal.
Auth
Bearer token. Free-tier and trial-locked plans are allowed; the free-tier gate runs after auth.
Rate limit
10 spin-ups / minute / IP.
Request
POST /api/chain/state-machines HTTP/1.1
Host: zeq.dev
Authorization: Bearer zsm_…
Content-Type: application/json
{
"slug": "my-iot-fleet",
"is_public": false,
"display_name": "Production IoT fleet",
"purpose": "Audited heartbeats from kitchen sensors",
"parent_origin": "zeq-dev"
}
| Field | Type | Required | Notes |
|---|---|---|---|
slug | string | optional | [a-z0-9-]{1,64}. Defaults to lowercased ZID. Auto-suffix -2, -3, … if collision and slug was auto-derived. User-supplied collisions return 409. |
is_public | bool | optional | Default false. Public machines expose read endpoints anonymously and emit to the public aggregator. |
display_name | string | optional | ≤ 255 chars. Browseable label. |
purpose | string | optional | ≤ 4000 chars. Documentation field. |
parent_origin | string | optional | Tenant origin. Defaults to env ZEQ_ORIGIN or zeq-dev. |
Response — 201 Created
{
"ok": true,
"machine": {
"id": "uuid",
"slug": "my-iot-fleet",
"parent_origin": "zeq-dev",
"is_public": false,
"status": "active",
"genesis_zeqond": "2287439210",
"display_name": "Production IoT fleet",
"purpose": "Audited heartbeats from kitchen sensors",
"owner_zid": "ZEQ07491829374",
"region": "us-east",
"created_at": "2026-04-28T01:49:00Z",
"updated_at": "2026-04-28T01:49:00Z"
},
"api_key": "zsm_…"
}
For paid tiers (advanced, enterprise, architect, builder) the response also includes subdomain and container_port after the Docker provisioner runs.
Errors
| Status | Body error | Cause |
|---|---|---|
400 | invalid_slug | slug fails [a-z0-9-]{1,64} |
401 | unauthorized | bearer missing or invalid; or invalid_zid from the resolver |
409 | slug_taken | user-supplied slug collides; response includes existing_slug |
429 | rate_limited | spin-up limit |
500 | unspecified | DB error |
Curl
curl -sS https://zeqapi.com/api/chain/state-machines \
-H "Authorization: Bearer ${ZSM_KEY}" \
-H "Content-Type: application/json" \
-d '{"slug":"my-iot-fleet","is_public":false}'
See also
- Spin up your first state machine — full tutorial.
- State machines concept.