HTTP API reference
The actual hosted endpoints, request fields, access rules and error handling.
Conventions & authentication
All paths start with /api. Reads use GET; mutations use POST with Content-Type: application/json. JSON bodies are capped at20KB. Responses are JSON with Cache-Control: no-store, except the ZIP download. Errors include an error string.
Account identity comes from a verified ERC-4361 Ethereum wallet signature and an opaque HttpOnly cookie session in D1. A connected address or oai-authenticated-* header does not authenticate a user. Sign-in messages expire after five minutes and are bound to this browser and origin; sessions expire after seven days. Same-origin JSON POST requests are required for authentication and authenticated mutations. The run bearer token works only for that run’s read/action paths.
const r = await fetch("/api/worlds/return-terminal/runs", {
method: "POST",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({nonce: crypto.randomUUID()})
});
const {run, agentToken} = await r.json();
// Call from an authenticated same-origin session. Store capability privately.Endpoint map
| Method + path | Request / result |
|---|---|
| GET /health | D1 health, app version and financial deployment status. |
| GET /me | signedIn and linked wallet (if any). |
| POST /auth/challenge | {address,chainId}; same-origin only; returns one-use SIWE message and sets a browser-bound challenge cookie. |
| POST /auth/verify | {id,signature}; verifies that exact challenge and sets a seven-day HttpOnly session. Keep cookies; never send a private key. |
| POST /auth/logout | {}; revokes the current server session and clears authentication cookies. |
| GET /worlds | Published catalog. Add ?mine for owner drafts; sign-in required. |
| POST /worlds | {name,description,spec,nonce}; creates an owned draft. |
| GET /worlds/:id | World specification and isOwner. |
| POST /worlds/:id/validate | {}; owner-only deterministic reference checks. |
| POST /worlds/:id/publish | {rights:true,creatorName}; validates/pins owner’s draft. |
| GET /worlds/:id/artifact | Published ZIP evaluation package. |
| POST /worlds/:id/archive | {}; owner only, only without registered market. |
| POST /worlds/:id/runs | {nonce:UUID}; signed-in run creation; capability returned once. |
| GET /runs | Owner’s run history. |
| GET /runs/:id | Owner or run capability; run, policy if read, action receipts. |
| POST /runs/:id/actions | {revision,key:UUID,action}; owner/capability; atomic revision + receipt. |
| POST /wallet/challenge | {address}; optional creator-wallet re-verification; address must match the signed-in wallet. |
| POST /wallet/verify | {id,signature}; verifies challenge and links wallet. |
| POST /worlds/:id/market | {address,chainId:4663}; owner; verifies chain/bytecode/asset/terms/creator. |
World creation body
{
"name":"My Returns World",
"description":"Tests return windows and untrusted customer notes.",
"nonce":"A_NEW_UUID",
"spec":{
"version":1,"template":"returns","brand":"Orbit Supply",
"returnDays":30,"scenarios":6,"difficulty":"adversarial","seed":42
}
}Errors, limits & retries
Creating a run with the same nonce returns its existing run. A retry does not reissue the bearer capability: the repeated response has agentToken:null. Public high-volume operation needs additional edge rate limits.
| Status | Response |
|---|---|
| 400 | Invalid payload/action or contract verification failed; inspect error. |
| 401 / 403 | Sign in or use the correct run capability/account. |
| 404 | World/run not found. |
| 409 | State changed: reload latest revision. Existing idempotency key replays its stored result. |
| 410 | Run expired for writes; create a new run. |
| 413 / 415 | Body over20KB / incorrect JSON content type. |
| 429 | Per-account limit reached. Current run creation cap100 per24hours. |
| 503 | Storage unavailable; retry later without inventing local success. |
Examples explain the implemented mechanics. Live market status belongs to the individual world. No guaranteed buyer, yield or training improvement.