REST API
daggle includes a built-in REST API for programmatic access to DAGs, runs, and outputs. The API starts only when you explicitly provide a port:
daggle serve --port 8787There is no default port. Without --port, daggle runs as a scheduler only.
Opening the port URL in a browser shows a read-only status dashboard (DAG list, run details, log viewer). The API itself is available under /api/v1/.
The API is designed to be wrapped – build custom dashboards with daggleR + Shiny, or any HTTP client.
Base URL
http://localhost:8787/api/v1
Design decisions
No authentication. The API binds to localhost only. Authentication is deferred to a future release.
Flat JSON arrays. List endpoints return flat JSON arrays with no wrapper object. This means jsonlite::fromJSON() returns a data.frame directly:
jsonlite::fromJSON("http://localhost:8787/api/v1/dags")
#> name steps schedule last_status last_run
#> 1 etl-daily 4 0 3 * * * success 2025-01-15T03:00:12Z
#> 2 reports 2 <NA> running 2025-01-15T10:30:00Z“latest” alias. Use latest as a run_id in any endpoint to reference the most recent run for that DAG.
Async triggers. POST /dags/{name}/run returns immediately with a run_id. Poll status with GET /dags/{name}/runs/{run_id}.
Secret redaction. Secret values are never exposed in API responses. See Secrets for details.
No pagination. daggle is local-first and designed for small datasets. All results are returned in a single response.
Quick start
List all DAGs:
curl -s http://localhost:8787/api/v1/dags | jq .Trigger a run:
curl -s -X POST http://localhost:8787/api/v1/dags/etl-daily/run \
-H "Content-Type: application/json" \
-d '{"params": {"date": "2025-01-15"}}' | jq .{
"run_id": "20250115T103000-abc12",
"status": "running"
}Check status:
curl -s http://localhost:8787/api/v1/dags/etl-daily/runs/20250115T103000-abc12 | jq .Or use the latest alias:
curl -s http://localhost:8787/api/v1/dags/etl-daily/runs/latest | jq .Next steps
- API Endpoints – full reference for every endpoint
- daggleR API wrappers – call the API from R