Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Using the HTTP API

The HTTP gateway exposes the client side of the gRPC API as JSON, so any language with an HTTP client can submit and inspect work. It listens on server.http_addr (default 127.0.0.1:7071). When authentication is enabled, every /v1 route needs authorization: Bearer <token>: the /v1/tasks routes need the client role, and /v1/snapshot, /v1/workers and /v1/recurring need the metrics role (admin works for all of them). Request bodies need content-type: application/json.

export CRONOQ=http://localhost:7071
export AUTH="authorization: Bearer $CRONOQ_CLIENT_TOKEN"
export JSON="content-type: application/json"

Submit

curl -s $CRONOQ/v1/tasks -H "$AUTH" -H "$JSON" -d '{
  "payload": {"prompt": "summarize ..."},
  "pool": "llm",
  "kind": "summarize",
  "priority": "high",
  "key": "summary-42",
  "deadline_in_s": 30,
  "timeout_s": 60,
  "retry": {"max_attempts": 5, "initial_backoff_s": 0.5},
  "resources": {"openai": 1},
  "tags": {"tenant": "acme"}
}'
# {"duplicate":false,"id":"17"}
  • payload is any JSON value (sent to workers as application/json); use payload_b64 for binary data.
  • key makes the submission idempotent: sending it again returns the same id with "duplicate": true. Use it for every request you might retry.
  • Add "wait": true (and optionally "wait_timeout_s") to block until the task finishes and include its result.
  • Unknown fields are rejected, so typos fail loudly instead of being ignored.

Dependencies and batches

curl -s "$CRONOQ/v1/tasks:batch" -H "$AUTH" -H "$JSON" -d '{"tasks": [
  {"payload": "extract", "key": "extract"},
  {"payload": "load", "key": "load", "after": ["extract"]},
  {"payload": "alert", "deps": [{"key": "load", "cond": "on_failure"}]}
]}'
# {"tasks":[{"duplicate":false,"id":"18"},{"duplicate":false,"id":"19"},{"duplicate":false,"id":"20"}]}

after accepts keys (strings) and ids ({"id": "18"} or a number). A batch is all-or-nothing, and its tasks may reference each other in any order. alert runs only if load fails; if load succeeds, alert ends as skipped.

Status, results, cancellation

Ids and keys have separate routes:

curl -s $CRONOQ/v1/tasks/17 -H "$AUTH"
curl -s $CRONOQ/v1/tasks/by-key/summary-42 -H "$AUTH"
# {"attempt":1,...,"id":"17","key":"summary-42","kind":"summarize",...,"pool":"llm",...,"status":"running"}

curl -s "$CRONOQ/v1/tasks/17/result?timeout_s=60" -H "$AUTH"
# {"id":"17","output":{...},"output_available":true,"output_b64":"...","status":"succeeded"}

curl -s -X DELETE $CRONOQ/v1/tasks/by-key/summary-42 -H "$AUTH"
# {"cancelled":true}

Percent-encode keys that contain / (report%2F2024). A result request that times out returns 504 while the task keeps running: ask again.

Scheduled work

# Start in 10 minutes; skip it if it cannot start within 30 s of that time.
curl -s $CRONOQ/v1/tasks -H "$AUTH" -H "$JSON" -d '{
  "payload": {"report": "daily"}, "start_in_s": 600, "tolerance_s": 30, "on_miss": "skip"}'

The server reserves capacity for the start time, and holds a worker slot free shortly before it. Recurring schedules are managed through the gRPC Admin service with an admin token, for example with the Python client's add_recurring.

Operations

curl -s $CRONOQ/v1/snapshot -H "authorization: Bearer $CRONOQ_METRICS_TOKEN"  # pools, waits, adherence, cost
curl -s $CRONOQ/metrics -H "authorization: Bearer $CRONOQ_METRICS_TOKEN"      # Prometheus text
curl -s $CRONOQ/healthz                  # process is up
curl -s $CRONOQ/readyz                   # 200 on the leader, 503 on standbys

Set server.metrics_addr to serve /metrics without a token on a separate, internal port.

Errors

Errors are JSON {"error": "...", "code": "..."}:

StatusWhenRetry?
400Invalid JSON, unknown field or enum value, invalid duration, cycleno
401Missing or invalid tokenno
403Token lacks the role, or the pool is outside its scopeno
404Unknown task, pool, resource or dependencyno
409Fixed-start reservation conflictafter changing the start
413 / 415Body too large / missing content-type: application/jsonno
429Queue fullyes, with backoff
503Not the leader, shutting down, or store unavailableyes, with backoff
504A wait ended before the task finishedask for the result again

Full details: HTTP API reference.