- Content type:
application/json - Time values: Unix milliseconds
- Idempotency for writes: optional
Idempotency-Keyheader - Lease-protected endpoints:
Authorization: Bearer <lease_token>
GET /openapi.jsonGET /.well-known/openapi.json
POST /v1/tracesPOST /otlp/v1/traces
OTLP attribute mapping keys:
nulltickets.run_idnulltickets.task_id
GET /health
POST /pipelinesGET /pipelinesGET /pipelines/{id}
POST /tasksPOST /tasks/bulkGET /tasks?stage=&pipeline_id=&limit=&cursor=GET /tasks/{id}
POST /tasks and bulk items support:
retry_policy:{ max_attempts?, retry_delay_ms?, dead_letter_stage? }dependencies:string[](task ids)assigned_agent_id,assigned_by
POST /tasks/{id}/dependencieswith{ "depends_on_task_id": "..." }GET /tasks/{id}/dependencies
POST /tasks/{id}/assignmentswith{ "agent_id": "...", "assigned_by": "..." }GET /tasks/{id}/assignmentsDELETE /tasks/{id}/assignments/{agent_id}
POST /leases/claimPOST /leases/{id}/heartbeat(Bearer)
POST /runs/{id}/events(Bearer)GET /runs/{id}/events?limit=&cursor=POST /runs/{id}/transition(Bearer)POST /runs/{id}/fail(Bearer)
POST /runs/{id}/transition request fields:
trigger(required)instructions(optional)usage(optional JSON)expected_stage(optional)expected_task_version(optional)
Transition returns 409 when:
expected_stagedoes not matchexpected_task_versiondoes not match
POST /artifactsGET /artifacts?task_id=&run_id=&limit=&cursor=
PUT /store/{namespace}/{key}with{ "value": ... }GET /store/{namespace}/{key}DELETE /store/{namespace}/{key}GET /store/{namespace}(list entries)DELETE /store/{namespace}(delete all entries in namespace)GET /store/search?q=&namespace=&limit=&filter_path=&filter_value=(FTS5 full-text search)
Notes:
namespaceandkeypath segments are URL-decoded server-side, so clients should percent-encode reserved characters such as spaces or/.searchis a reserved namespace name becauseGET /store/searchis the full-text search endpoint.filter_pathandfilter_valueapply an exact JSON filter on top of FTS results.
GET /ops/queue?near_expiry_ms=&stuck_ms=
Returns per-role stats:
claimable_countoldest_claimable_age_msfailed_countstuck_countnear_expiry_leases
Paginated endpoints return:
{
"items": [...],
"next_cursor": "..."
}
next_cursor = null means end of list.
{
"error": {
"code": "not_found",
"message": "Task not found"
}
}