OpenAPI specification
Machine-readable OpenAPI 3.1 document for the Edgaze v1 REST API, generated from the same Zod schemas the handlers use.
Developers generating SDKs, importing into Postman/Insomnia, or building custom API tooling.
The v1 REST API ships with a committed OpenAPI 3.1 document. Generators, docs UIs, and validators can consume it without keys, without CORS gymnastics, and without hand-maintained shim schemas.
Where to find it#
https://api.edgaze.ai/v1/openapi(production, dedicated host)https://www.edgaze.ai/api/v1/openapi(App Router route handler)https://www.edgaze.ai/openapi.json(committed static asset, same bytes)
All three URLs are unauthenticated, respond with Content-Type: application/json, allow Access-Control-Allow-Origin: *, and are cached publicly for one hour. Fetch the URL closest to your consumer.
What is in the document#
openapi: "3.1.0"andinfo.version: "1.0.0". The spec version is a dedicated constant, decoupled from the platform release version so unrelated deploys never move it.serverspoints athttps://api.edgaze.ai/v1.securitySchemes.bearerAuthis HTTP bearer. Every non-webhook operation declaressecurity: [{ bearerAuth: [] }]and carriesx-required-scopesfor programmatic scope checks.- Eight explicit
operationIds:listWorkflows,getWorkflow,listWorkflowVersions,acceptWorkflowUpdate,createRun,getRun,listRunEvents,streamRun. These match the handler paths undersrc/app/api/v1/and are stable across releases. - Response headers include
Cache-ControlandVaryon every authenticated response.createRunadds rate-limit headers on 429.streamRundeclares the SSE headers. createRundocuments theIdempotency-Keyheader (max 255 chars) and the 409idempotency_conflictconflict response.streamRundocuments theLast-Event-IDresume header.- A
webhookssection describesrun.completed,run.failed,run.cancelled, andwebhook.test, each with theedgaze-signatureHMAC verification contract.
Zod is the source of truth#
Every schema in components.schemas is generated from a Zod schema in src/lib/api/v1/schemas.ts. To evolve the API surface:
- Edit the Zod schema.
- Run
npm run openapi:generate. - Commit the updated
public/openapi.json.
CI runs the same generator and fails the build when the committed document drifts from the code, so you can never merge a spec that misrepresents the handlers.
Version resolution#
The public v1 API pins every run to an immutable workflow version, but the same workflow id can execute different graphs depending on who is calling. Two callers hitting POST /runs with the same workflow can execute two completely different immutable graphs.
POST /runs resolves the version in this order:
- Explicit
versionin the request body. The run executes that exact immutable graph. The caller must be entitled to it: owners can select any version in the workflow's history; buyers can select the version their purchase pin already covers. Sending an unknown or forbiddenversionreturns 403forbidden. - Caller's purchase pin. When
versionis omitted andworkflow_purchases.workflow_version_idis non-null for this caller, the run executes that pinned version. A creator publishing a newer version does not silently upgrade a pinned buyer. - Follow active. When
versionis omitted and the caller's purchase pin is null, or they have no purchase row, the run executes the workflow's currentactive_version_id. These callers float with each publish.
GET /workflows/{id} surfaces three related fields so integrators can detect and reason about drift without polling every run:
pinnedVersionId: the version this caller is pinned to via a prior purchase, ornullwhen they follow the active version.activeVersionId: the workflow's current active version.updateAvailable:truewhen the caller is pinned to an older version than the active one.
Cache these values per workflow. When updateAvailable flips to true, treat it as a signal to inspect any newly required inputs or output shapes before the next run. Buyers who want to re-pin to the newest version can call POST /workflows/{id}/accept-update (requires workflow:write).
Note: existing purchase rows with a null pin remain grandfathered as "follows active" forever. Only new purchases mint or resolve a version at purchase time.
Undocumented endpoints#
Two endpoints intentionally do not appear in the OpenAPI document:
DELETE /runs/{id}exists only to return405 method_not_allowedwith a stable envelope. Runs are immutable in the public API; documenting the DELETE would suggest deletion is supported.GET /openapi(and its aliases) is the document itself. Listing it inside itself is circular and adds no client value.
Both are recorded in UNDOCUMENTED_V1_OPERATIONS in src/lib/api/v1/openapi.ts so the completeness test in src/lib/api/v1/openapi.test.ts treats them as expected omissions rather than gaps.