Skip to content

Tasks API

GET /api/v1/tasks?project_id=...&state=failed&cursor=...&limit=50

Filters:

  • project_id (required)
  • state - pending / started / succeeded / failed / cancelled / retried / lost
  • engine - celery / rq / …
  • queue - name
  • name - task name (exact or like=%foo%)
  • from / to - timestamps (RFC 3339)
  • has_error - boolean

Response:

{
"items": [
{
"id": "01H...",
"engine": "celery",
"name": "email.send",
"state": "failed",
"args": ["<redacted>"],
"kwargs": {"to": "<email>"},
"enqueued_at": "...",
"started_at": "...",
"finished_at": "...",
"error": { "exc_type": "ValueError", "exc_msg": "..." },
"retried_as": null
}
],
"next_cursor": "...",
"has_more": true
}
GET /api/v1/tasks/{id}

Returns the task plus its full event stream.

POST /api/v1/tasks/{id}/retry

Role: operator. Returns:

{"ok": true, "new_task_id": "01H..."}
POST /api/v1/tasks/{id}/cancel

Role: operator. Body:

{"terminate": false}

terminate=true sends SIGTERM to the worker (Celery only; requires admin).

POST /api/v1/tasks/bulk-retry

Body mirrors list filters:

{
"project_id": "...",
"state": "failed",
"name": "email.send",
"from": "2026-04-16T00:00:00Z",
"to": "2026-04-16T23:59:59Z"
}

Max 10,000 tasks per call. Response includes a job_id to poll:

GET /api/v1/tasks/bulk-retry/{job_id}
POST /api/v1/queues/{name}/purge

Role: operator. Removes all pending messages from the named queue.

This is destructive. Confirm in UI; external clients must set ?confirm=yes.

GET /api/v1/tasks/{id}/events

All lifecycle events for one task, oldest first.