Spin up your first state machine
Every action on the Zeq framework — wizard, prove, mail, message, playground, AI chat, app dev, contract transition — comes out of an API key bound 1:1 to a state machine. To get going you do five things:
- Register a Zeq identity (the
ZEQ07XXXXXXXXXZID). - Spin up a state machine on that identity.
- Copy the
zsm_…API key the spin-up returns to you (shown once). - Send your first event into the entangled state.
- Read the entangled state back, then validate the entangled state integrity.
Every step below is a real, runnable call against the live API at https://zeqapi.com. If you're self-hosting, replace https://zeqapi.com with your local origin (https://localhost:3099 for the dev stack).
1. Register a Zeq identity
Identity in Zeq is equation-as-credential. The client computes an HMAC over your equation (the salt is generated client-side, version v2:), POSTs only the hash, and the server never sees the raw equation. The browser flow at /auth/ runs the wizard for you; the wire-level protocol is POST /api/zeq-auth/register-v3.
For a programmatic walk-through, the simplest path is to call /zeq/wizard/compute to get a candidate equation, then HMAC it client-side and POST the hash:
curl -sS https://zeqapi.com/api/zeq/wizard/compute \
-H "Content-Type: application/json" \
-d '{"query":"orbit of a satellite around earth"}'
Response (truncated):
{
"ok": true,
"equation": "□φ − μ²(r)φ − λφ³ … = T^μ_μ + …",
"operators": ["KO42", "NM21", "GR37"],
"envelope_id": 821334910,
"phase": 0.4119,
"zeqond": "2287439210.7",
"domain": "orbital-mechanics",
"pulseHz": 1.287,
"precision": 0.00071
}
Pick that equation up, HMAC it with the HITE key + your random 32-byte salt, then register:
curl -sS https://zeqapi.com/api/zeq-auth/register-v3 \
-H "Content-Type: application/json" \
-d '{
"equation_hash": "0123abc...64hex...",
"equation_salt": "fedc...64hex...",
"display_name": "Pad",
"hash_version": 2
}'
You get back your ZID, a JWT token, your zid_email (zeq07xxxxxxxxx@zeq.dev), and — because of the auto-state-machine policy in zeqAuthV3.ts — your default state machine's slug and its first API key:
{
"ok": true,
"zid": "ZEQ07491829374",
"zid_email": "zeq07491829374@zeq.dev",
"token": "eyJ...",
"displayName": "Pad",
"plan": "free",
"hash_version": 2,
"state_machine": {
"slug": "zeq07491829374",
"api_key": "zsm_LIVE_KEY_SHOWN_ONCE_ONLY"
}
}
Save the
api_key. The framework only stores its SHA-256 hash. If you lose this string you have to mint a new key from the portal.
If you'd rather take the browser path: open https://zeqapi.com/auth/, run the wizard, and your default state machine + key appear in /portal/.
2. Spin up an additional state machine (optional)
The register-v3 flow auto-creates one. You can spin up more — one per project, one per device, one per audit boundary. Use POST /api/chain/state-machines:
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,
"display_name": "Production IoT fleet",
"purpose": "Audited heartbeats from the kitchen sensors"
}'
const res = await fetch("https://zeqapi.com/api/chain/state-machines", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ZSM_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
slug: "my-iot-fleet",
is_public: false,
display_name: "Production IoT fleet",
purpose: "Audited heartbeats from the kitchen sensors",
}),
});
const data = await res.json();
console.log(data.machine.slug, data.api_key);
import os, requests
r = requests.post(
"https://zeqapi.com/api/chain/state-machines",
headers={"Authorization": f"Bearer {os.environ['ZSM_KEY']}"},
json={
"slug": "my-iot-fleet",
"is_public": False,
"display_name": "Production IoT fleet",
"purpose": "Audited heartbeats from the kitchen sensors",
},
)
print(r.json()["machine"]["slug"], r.json().get("api_key"))
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 the kitchen sensors",
"owner_zid": "ZEQ07491829374",
"created_at": "2026-04-28T01:49:00.000Z"
},
"api_key": "zsm_..."
}
Slug rules: [a-z0-9-]{1,64}. If your machine collides with one you already own, the framework auto-appends -2, -3, … up to -100. User-supplied slugs collide loudly with 409 so you can correct an intentional choice.
3. Send your first event
Four write endpoints exist on the entangled state, each scoped to your machine:
| Endpoint | Purpose |
|---|---|
POST /api/chain/:slug/event | Catch-all log. Pre-hash with body.hash or send body.payload and the server hashes it. |
POST /api/chain/:slug/state | State-hash snapshot. Caller pre-hashes; server records hash + Zeqond. |
POST /api/chain/:slug/file | File-hash event. Hash + name + bytes + mime. |
POST /api/chain/:slug/connection | Connection event. Direction (inbound/outbound), peer hash, protocol, state. |
The framework records the hash, never the bytes (free tier). If you need the bytes back later, you keep them — the entangled state proves what was claimed at Zeqond N.
curl -sS https://zeqapi.com/api/chain/my-iot-fleet/event \
-H "Authorization: Bearer ${ZSM_KEY}" \
-H "Content-Type: application/json" \
-d '{
"type": "heartbeat",
"payload": {"temp_c": 21.4, "uptime_ms": 12345}
}'
await fetch(`https://zeqapi.com/api/chain/${slug}/event`, {
method: "POST",
headers: {
"Authorization": `Bearer ${zsmKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "heartbeat",
payload: { temp_c: 21.4, uptime_ms: 12345 },
}),
});
requests.post(
f"https://zeqapi.com/api/chain/{slug}/event",
headers={"Authorization": f"Bearer {zsm_key}"},
json={"type": "heartbeat", "payload": {"temp_c": 21.4, "uptime_ms": 12345}},
)
Response (201):
{
"ok": true,
"zeqondNumber": 2287439213,
"transitionId": "9b1c…uuid"
}
That transitionId is on the entangled state forever, hashed against the previous transition's state_hash. Your event just became immortal.
4. Observe the entangled state
Pull the latest state, a specific block, or a windowed range:
curl -sS "https://zeqapi.com/api/chain/my-iot-fleet/state" \
-H "Authorization: Bearer ${ZSM_KEY}"
curl -sS "https://zeqapi.com/api/chain/my-iot-fleet/explore?from=0&to=999999999&limit=100" \
-H "Authorization: Bearer ${ZSM_KEY}"
For a live feed (useful in dashboards):
const es = new EventSource(
`https://zeqapi.com/api/chain/${slug}/explore/sse?token=${jwt}`,
);
es.onmessage = (e) => {
const tx = JSON.parse(e.data);
console.log("tx", tx.zeqond, tx.type, tx.stateHash);
};
EventSource doesn't support custom headers, so the SSE endpoint also accepts ?token=<jwt> for cookie-less auth.
To watch from a browser without code, point the State Explorer at your machine:
https://zeqapi.com/state/?slug=my-iot-fleet
5. Validate the entangled state (PoHC)
Proof of Harmonic Convergence — the entangled state is hash-linked from the genesis seed forward. To prove integrity over a window:
curl -sS "https://zeqapi.com/api/chain/my-iot-fleet/pohc/validate" \
-H "Authorization: Bearer ${ZSM_KEY}"
{
"ok": true,
"valid": true,
"count": 17,
"broken_at": null,
"genesis_zeqond": "2287439210"
}
If a row's prev_hash doesn't match the previous row's state_hash, valid flips to false and broken_at carries the offending Zeqond number.
You can also bound the window: ?from=2287439210&to=2287439999.
You're alive
Your state machine is now on the entangled state, ticking on the universal 1.287 Hz HulyaPulse, with every action attributed to your zsm_ key. Every action you take on the framework from here — call the wizard, run the prove endpoint, send mail, run an LLM chat, deploy a contract template — flows through that same key and lands on the same entangled state.
Where to go next:
- Concept — What a state machine is
- Build — Hello, Zeq (compute layer)
- Build — The ready-to-deploy contract templates
- Embed — Drop the universal tracker on any site
- Examples — 5 runnable patterns
- API — Every public route
Middleware active. Kernel synced. Awaiting next Zeqond.