HTTP Admin API
Complete reference for the Dispatch admin API endpoints.
The admin API is served by api.New(eng, router). All routes are mounted under /v1. Requests and responses use JSON.
Setup
import (
"github.com/xraph/dispatch/api"
"github.com/xraph/dispatch/engine"
)
// With Forge router:
a := api.New(eng, forgeRouter)
a.RegisterRoutes(forgeRouter)
// Standalone (net/http):
mux := http.NewServeMux()
api.RegisterRoutes(mux, eng) // convenience wrapperUsing the Forge extension auto-registers routes unless WithDisableRoutes(true) is set.
Jobs
List jobs
GET /v1/jobs?state=pending&queue=critical&limit=50&offset=0Query parameters:
| Parameter | Type | Description |
|---|---|---|
state | string | Filter: pending, running, completed, failed, retrying, cancelled |
queue | string | Filter by queue name |
limit | int | Max results (default: 50, max: 1000) |
offset | int | Pagination offset |
Response 200 OK:
[
{
"id": "job_01h455vb4pex5vsknk084sn02q",
"name": "send_email",
"queue": "default",
"state": "completed",
"payload": {"to":"user@example.com","subject":"Welcome"},
"attempt": 1,
"max_attempts": 3,
"run_at": "2025-01-15T10:00:00Z",
"started_at": "2025-01-15T10:00:01Z",
"completed_at": "2025-01-15T10:00:02Z",
"scope_app_id": "",
"scope_org_id": "org_01h455vb"
}
]Get job
GET /v1/jobs/{jobId}Response 200 OK: Single job object (same schema as above).
Response 404 Not Found: {"error": "job not found"}
Cancel job
Cancels a job in pending or retrying state.
POST /v1/jobs/{jobId}/cancelResponse 204 No Content
Response 400 Bad Request: If the job is not in a cancellable state.
Job counts
Returns counts grouped by state.
GET /v1/jobs/countsResponse 200 OK:
{
"pending": 12,
"running": 3,
"completed": 4820,
"failed": 7,
"retrying": 2,
"cancelled": 1
}Workflows
List registered workflows
Returns the names of all workflows registered with the engine.
GET /v1/workflowsResponse 200 OK:
{
"names": ["onboard_user", "process_order", "send_report"]
}List workflow runs
GET /v1/workflows/runs?state=running&limit=50&offset=0Query parameters:
| Parameter | Type | Description |
|---|---|---|
state | string | Filter: running, completed, failed |
limit | int | Max results (default: 50) |
offset | int | Pagination offset |
Response 200 OK:
[
{
"id": "run_01h455vb4pex5vsknk084sn02q",
"name": "onboard_user",
"state": "running",
"current_step": "send-welcome",
"started_at": "2025-01-15T10:00:00Z",
"completed_at": null,
"scope_app_id": "",
"scope_org_id": "org_01h455vb"
}
]Get workflow run
GET /v1/workflows/runs/{runId}Response 200 OK: Single run object.
Response 404 Not Found: {"error": "run not found"}
Dead Letter Queue
List DLQ entries
GET /v1/dlq?queue=default&limit=50&offset=0Query parameters:
| Parameter | Type | Description |
|---|---|---|
queue | string | Filter by originating queue name |
limit | int | Max results (default: 50) |
offset | int | Pagination offset |
Response 200 OK:
[
{
"id": "dlq_01h455vb4pex5vsknk084sn02q",
"job_id": "job_01h455vb4pex5vsknk084sn02q",
"job_name": "send_email",
"queue": "default",
"error": "dial tcp: connection refused",
"payload": {"to":"user@example.com"},
"failed_at": "2025-01-15T10:05:00Z",
"scope_org_id": "org_01h455vb"
}
]Get DLQ entry
GET /v1/dlq/{entryId}Response 200 OK: Single DLQ entry object.
Replay DLQ entry
Re-enqueues the entry as a new pending job in its original queue.
POST /v1/dlq/{entryId}/replayResponse 201 Created: The newly created job.Job object.
Purge DLQ
Removes DLQ entries older than a threshold.
POST /v1/dlq/purgeResponse 200 OK:
{
"purged": 42
}DLQ count
GET /v1/dlq/countResponse 200 OK:
{
"count": 17
}Crons
List cron entries
GET /v1/crons?limit=50&offset=0Response 200 OK:
[
{
"id": "cron_01h455vb4pex5vsknk084sn02q",
"name": "daily-cleanup",
"schedule": "0 3 * * *",
"enabled": true,
"last_fired_at": "2025-01-15T03:00:00Z",
"next_run_at": "2025-01-16T03:00:00Z",
"scope_app_id": "",
"scope_org_id": ""
}
]Get cron entry
GET /v1/crons/{cronId}Response 200 OK: Single cron entry object.
Enable cron entry
POST /v1/crons/{cronId}/enableResponse 200 OK: Updated cron entry with enabled: true.
Disable cron entry
POST /v1/crons/{cronId}/disableResponse 200 OK: Updated cron entry with enabled: false.
Delete cron entry
Permanently removes the cron entry. It will no longer fire.
DELETE /v1/crons/{cronId}Response 204 No Content
Stats
Returns aggregate statistics across all subsystems.
GET /v1/statsResponse 200 OK:
{
"jobs": {
"pending": 12,
"running": 3,
"completed": 4820,
"failed": 7,
"retrying": 2,
"cancelled": 1
},
"dlq_count": 17,
"workflows": {
"running": 5,
"completed": 312,
"failed": 4
}
}Error responses
All errors return a JSON object:
{
"error": "job not found"
}| Scenario | Status Code |
|---|---|
| Resource not found | 404 |
| Invalid input | 400 |
| Internal error | 500 |