API Reference
The dagctl API gives you programmatic control over every part of the platform: creating and managing projects, configuring jobs and schedules, reviewing and approving deployment plans, managing your team, and exporting execution data to your own systems.
In This Section
- Projects — Create, update, deploy, and delete SQLMesh and dbt projects
- Jobs — Configure scheduled jobs, trigger manual runs, and retrieve logs
- Plans — List, approve, reject, cancel, and retry deployment plans
- Team — Manage organization members, roles, and invitations
- Environment Variables — Create and manage secrets and config values injected into job pods
- Environment Protection — Restrict access to sensitive environments (e.g.
prod) - Execution Metrics — Job runs, model executions, daily stats, and per-model performance
- Examples — Polling scripts, SLA checks, and regression detection
Authentication
All API requests require two headers:
| Header | Value | Description |
|---|---|---|
Authorization |
Bearer dctl_... |
API token generated from your organization settings |
X-Organization-ID |
org-xxxxxxxx |
Your organization ID |
Creating an API Token
Generate a token from the dagctl web UI under Settings > Authentication, then select the API Tokens tab and click Create Token. The token is displayed once — copy it immediately.
When creating a token you choose its scopes — the subset of permissions it may exercise. The UI offers presets (Automation: view/create/approve plans and view/trigger jobs; Read-only; Full access) or a custom selection. The API accepts the same values:
{ "name": "claude-approver", "scopes": ["view_project", "view_plan", "create_plan", "approve_plan", "view_jobs", "trigger_jobs"] }
Available scopes: manage_team, manage_org, manage_billing, create_project, edit_project, delete_project, view_project, deploy_project, create_plan, approve_plan, view_plan, manage_jobs, trigger_jobs, view_jobs, manage_secrets, view_secrets. A request outside a token's scopes fails with 403 and names the missing scope. Tokens are not editable — create a new one to change scopes.
Note
Tokens created before scopes existed (an empty scope list) have full organization access. They are labelled Full access · Created before scopes in the UI; rotate them to scoped tokens.
Some actions require a user session and are refused for any API token: inviting members and driving the agent console with a scoped token. Writes performed with a token are attributed to it in audit fields (for example a plan's approved_by_actor: "api_token:<id>").
Example Request
curl -s "https://api.dagctl.io/api/v1/projects/${PROJECT_ID}/runs?limit=10" \
-H "Authorization: Bearer ${DAGCTL_TOKEN}" \
-H "X-Organization-ID: ${ORG_ID}"
Base URL
All endpoints are prefixed with /api/v1.
Conventions
Pagination
Paginated endpoints accept page and limit query parameters:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
page |
integer | 1 | - | Page number (1-indexed) |
limit |
integer | varies | 500 | Results per page |
Paginated responses include:
Date Formats
| Format | Used For | Example |
|---|---|---|
| RFC3339 | Timestamps and updated_after filter |
2026-02-26T00:00:00Z |
| YYYY-MM-DD | Date range filters (start_date, end_date) |
2026-02-26 |
Nullable Fields and omitempty
Nullable fields are omitted from the JSON response when their value is null. They do not appear as "field": null — the key is absent entirely.
Fields affected by this behavior:
cronjob_name— absent for manually triggered runsend_time— absent for in-progress runsduration_seconds— absent for in-progress runserror_message— absent when no error occurredpod_name— absent before pod scheduling
Your polling client should handle missing keys, not null values.