REST API
Dagu provides a comprehensive REST API for programmatic control over workflow orchestration. The API enables DAG management, execution control, monitoring, and system operations through standard HTTP endpoints.
API Reference
For the complete API documentation with all endpoints, see REST API Reference.
Base Configuration
- Base URL:
http://localhost:8080/api/v1 - Content-Type:
application/json - Required Headers:
Accept: application/json
Mounted deployments can change both the server base path and the API base path. The live OpenAPI document advertises the mounted API path in servers[0].url so generated clients can target /api/v1, /dagu/api/v1, /dagu/rest, or any other configured mount point correctly.
Authentication
The REST API supports three authentication methods:
- Basic Authentication: Include
Authorization: Basic <base64(username:password)>header - Bearer Token: Include
Authorization: Bearer <token>header - No Authentication: When auth is disabled (default for local development)
Core Operations
Health Monitoring
Check server health and status:
curl http://localhost:8080/api/v1/healthResponse includes server status, version, uptime, and timestamp.
OpenAPI Document
Fetch the normalized OpenAPI document served by the current Dagu instance:
curl http://localhost:8080/api/v1/openapi.jsonWhen authentication is enabled, /openapi.json requires the same auth as the rest of the API. The web UI also exposes a live viewer at /api-docs, which loads this document with the current session.
DAG Management
List DAGs
# Get all DAGs
curl http://localhost:8080/api/v1/dags
# With filtering and pagination
curl "http://localhost:8080/api/v1/dags?page=1&perPage=10&name=example&tags=prod"
# Sort alphabetically
curl "http://localhost:8080/api/v1/dags?sort=name&order=desc"
# Sort by the scheduler's next planned run time
curl "http://localhost:8080/api/v1/dags?sort=nextRun&order=asc"Supported Sort Fields
GET /api/v1/dags supports server-side sorting by name and nextRun.
name: case-insensitive DAG name sortnextRun: earlier scheduled run times first in ascending order; DAGs without schedules appear last
Get DAG Details
curl http://localhost:8080/api/v1/dags/my-dagThe DAG detail response includes paramDefs when Dagu can derive parameter metadata. paramDefs carries typed metadata for inline rich params: definitions, top-level inline JSON Schema, and representable external schemas. For named params, clients should submit a JSON object payload; JSON arrays are mainly for positional or mixed raw input.
defaultParams is a shell-style string of resolved default pairs such as environment="staging" batch_size="25". It is not JSON.
When a param uses inline eval, paramDefs.default still represents only the authored literal default, if one exists. Computed defaults such as ${BASE_DIR}/out or `nproc` are resolved by the server when the DAG is started.
Create New DAG
# Create with default template
curl -X POST http://localhost:8080/api/v1/dags \
-H "Content-Type: application/json" \
-d '{"name": "my-new-dag"}'
# Create with custom specification (validated before creation)
curl -X POST http://localhost:8080/api/v1/dags \
-H "Content-Type: application/json" \
-d '{
"name": "my-new-dag",
"spec": "steps:\n - command: echo hello"
}'Validate DAG Specification
curl -X POST http://localhost:8080/api/v1/dags/validate \
-H "Content-Type: application/json" \
-d '{
"spec": "steps:\n - command: echo hello",
"name": "optional-dag-name"
}'Validates DAG specifications without saving. Returns a validity flag, validation errors, and parsed DAG details when possible.
Example response (valid):
{
"valid": true,
"errors": [],
"dag": {
"name": "my-new-dag"
}
}Example response (invalid):
{
"valid": false,
"errors": [
"field 'steps': decoding failed due to the following error(s):",
"invalid keys: command1"
]
}DAG Execution Control
Start DAG
curl -X POST http://localhost:8080/api/v1/dags/my-dag/start \
-H "Content-Type: application/json" \
-d '{
"params": "{\"env\": \"production\"}",
"dagRunId": "custom-run-id",
"dagName": "adhoc-my-dag"
}'params remains a JSON string payload. The server validates and coerces its values against the DAG's inline param definitions or external parameter schema before execution.
Enqueue DAG
curl -X POST http://localhost:8080/api/v1/dags/my-dag/enqueue \
-H "Content-Type: application/json" \
-d '{
"params": "{\"env\": \"production\"}",
"dagName": "queue-override-my-dag",
"queue": "high-priority" // optional: override queue
}'The same validation rules apply to enqueue requests. Invalid typed values are rejected before the run is queued.
Suspend/Resume DAG
# Suspend
curl -X POST http://localhost:8080/api/v1/dags/my-dag/suspend \
-H "Content-Type: application/json" \
-d '{"suspend": true}'
# Resume
curl -X POST http://localhost:8080/api/v1/dags/my-dag/suspend \
-H "Content-Type: application/json" \
-d '{"suspend": false}'Queue Management
List Queues
# Get queue summaries
curl http://localhost:8080/api/v1/queuesGET /queues returns queue summaries only: queue type (global or dag-based), optional maxConcurrency, runningCount, queuedCount, currently running items, and a top-level capacity summary.
To inspect queue contents, use GET /queues/{name}/items:
# Get queued items from one queue
curl "http://localhost:8080/api/v1/queues/default/items?type=queued&page=1&perPage=20"
# Get running items from one queue
curl "http://localhost:8080/api/v1/queues/default/items?type=running&page=1&perPage=20"DAG Run Management
List DAG Runs
# Get the newest DAG runs
curl http://localhost:8080/api/v1/dag-runs
# Filter by name and status
curl "http://localhost:8080/api/v1/dag-runs?name=my-dag&status=2"GET /dag-runs and GET /dag-runs/{name} now use forward-only cursor pagination. Each response returns dagRuns and, when more data exists, nextCursor.
# Follow the next page
curl "http://localhost:8080/api/v1/dag-runs?limit=100&cursor=<opaque-cursor>"Run From Inline Spec
Create and start a DAG-run directly from a YAML spec without persisting a DAG file.
curl -X POST "http://localhost:8080/api/v1/dag-runs?remoteNode=local" \
-H "Content-Type: application/json" \
-d '{
"spec": "steps:\n - name: hello\n command: echo hello",
"name": "hello", # optional if spec includes name
"params": "{\"env\":\"prod\"}", # optional JSON string
"dagRunId": "custom-run-id", # optional; autogenerated if omitted
"singleton": true # optional; prevent start if already active
}'Notes:
namemust be <= 40 chars and match[A-Za-z0-9_.-]+when provided.- When
singletonis true, starting while another run of the same DAG name is active returns 409 (max_run_reached). - Response:
{ "dagRunId": "<run-id>" }Stop or Cancel DAG Run
curl -X POST http://localhost:8080/api/v1/dag-runs/my-dag/20240101_120000/stopThis endpoint stops a running DAG run. It can also cancel a failed root DAG run that is still pending DAG-level automatic retry.
Retry DAG Run
curl -X POST http://localhost:8080/api/v1/dag-runs/my-dag/20240101_120000/retry \
-H "Content-Type: application/json" \
-d '{"dagRunId": "new-run-id"}'Step Management
Update Step Status
# Mark step as successful
curl -X PATCH http://localhost:8080/api/v1/dag-runs/my-dag/20240101_120000/steps/step1/status \
-H "Content-Type: application/json" \
-d '{"status": 4}' # 4 = Success
# Mark step as failed
curl -X PATCH http://localhost:8080/api/v1/dag-runs/my-dag/20240101_120000/steps/step1/status \
-H "Content-Type: application/json" \
-d '{"status": 2}' # 2 = FailedSearch Operations
Legacy full DAG search is still available:
curl "http://localhost:8080/api/v1/dags/search?q=database"The global search page uses cursor-based feed endpoints:
# Lightweight DAG search results
curl "http://localhost:8080/api/v1/search/dags?q=database"
# Lightweight document search results
curl "http://localhost:8080/api/v1/search/docs?q=runbook"
# Load more snippets for one DAG result
curl "http://localhost:8080/api/v1/search/dags/example/matches?q=database&cursor=<opaque-cursor>"
# Load more snippets for one document result
curl "http://localhost:8080/api/v1/search/docs/matches?path=runbooks/oncall&q=runbook&cursor=<opaque-cursor>"The feed endpoints return lightweight results with preview matches, hasMore, and optional cursors for both additional results and additional snippets per result.
Event Logs
Centralized event logs are available through GET /event-logs when the event store is enabled:
curl "http://localhost:8080/api/v1/event-logs?kind=dag_run&type=dag.run.failed&limit=50"Supported filters include kind, type, dagName, dagRunId, attemptId, sessionId, userId, model, startTime, and endTime.
The endpoint supports:
- offset pagination with
limitandoffset - cursor pagination with
limit,paginationMode=cursor, andcursor
When builtin authentication is enabled, this endpoint requires a manager or admin role.
Monitoring and Metrics
Prometheus Metrics
Dagu exposes Prometheus-compatible metrics for comprehensive monitoring:
curl http://localhost:8080/api/v1/metricsAvailable metrics include:
- System Metrics: Build info, uptime, scheduler status
- Execution Metrics: Running DAGs, queued runs, execution totals by status
- Performance Metrics: Success rates, queue lengths
Error Handling
All API endpoints return structured error responses:
{
"code": "error_code",
"message": "Human readable error message",
"details": {
"additional": "error details"
}
}Common error codes:
bad_request: Invalid request parametersnot_found: Resource doesn't existinternal_error: Server-side errorunauthorized: Authentication failedforbidden: Insufficient permissionsalready_exists: Resource (e.g., run ID) already existsmax_run_reached: Concurrency or singleton limit reachednot_running: DAG is not running
Response Formats
DAG List Response
{
"dags": [
{
"fileName": "example",
"dag": {
"name": "example_dag",
"schedule": [{"expression": "0 * * * *"}],
"description": "Example DAG",
"tags": ["example", "demo"]
},
"nextRun": "2026-03-29T09:30:00+09:00",
"latestDAGRun": {
"dagRunId": "20240101_120000",
"name": "example_dag",
"status": 1,
"statusLabel": "running",
"startedAt": "2024-01-01T12:00:00Z"
},
"suspended": false
}
],
"errors": [],
"pagination": {
"totalRecords": 45,
"currentPage": 1,
"totalPages": 5,
"nextPage": 2,
"prevPage": null
}
}schedule entries are recurring cron objects such as {"expression":"0 * * * *"} or typed one-off start entries such as {"kind":"at","at":"2026-03-29T09:30:00+09:00"}. nextRun is the scheduler-aware next planned run time for that DAG. For a pending one-off start entry, nextRun can remain visible even after that timestamp has passed, until the scheduler consumes it.
Health Check Response
{
"status": "healthy",
"version": "1.0.0",
"uptime": 3600,
"timestamp": "2024-02-11T12:00:00Z"
}