Service Accounts & API
Service accounts let external systems - CI pipelines, orchestrators, and scripts - call dbdeux programmatically without a human login. Each service account is a named machine identity that holds one or more scoped API tokens, so you can automate job runs and read run status from anywhere.
Service Accounts
A service account is a machine identity that belongs to an organization. Create one for each system that needs programmatic access (for example, "CI pipeline" or "Airflow orchestrator"), give it a description so teammates know what it's for, and it can hold as many tokens as you need.
- Named identity: A friendly name and optional description for the system or team that owns it
- Multiple tokens: Issue separate tokens per environment or consumer, then rotate or revoke them independently
- Activate / deactivate: Turn an entire account off in one click without deleting its history
- Service accounts are managed from the Service Accounts tab in organization settings, and are available to organization admins
API Tokens
Tokens are the actual secrets used to authenticate API calls. A guided drawer walks you through creating one in a few steps: name it, choose its scopes, then set its limits and security options.
Scopes
Tokens follow the principle of least privilege - grant only what a token needs. Scopes are never implied, so a token with jobs:run cannot also read jobs unless you add jobs:read.
| Scope | Grants |
|---|---|
projects:read | List the organization's projects (id and name) for discovery |
jobs:read | List and inspect scheduled jobs |
jobs:write | Create, update, and delete scheduled jobs |
jobs:run | Trigger a scheduled job run |
runs:read | Read job run status, history, logs, and artifacts |
environments:read | List a project's environments and variable metadata (never values) |
connections:read | List warehouse connections (identity and status only, never config) |
catalog:read | Browse the project's catalog nodes, columns, lineage, and governance metadata |
Limits and security
Each token can be constrained further so a leaked secret has a limited blast radius:
- Expiry: Pick a lifetime (30 days, 90 days, 1 year, or no expiry). Shorter lifetimes are safer; rotate before expiry to avoid interruptions.
- Rate limit: Cap how many requests per minute the token can make (default 120, range 1 to 300). This ceiling leaves ample headroom for any legitimate automation. Requests over the cap receive
429 Too Many Requestswith aRetry-Afterheader. - IP allowlist (optional): Restrict the token to specific IPs or CIDR ranges. Leave blank to allow any source.
Reveal once
When a token is minted, its secret is shown exactly once. dbdeux stores only a one-way hash and can never display the secret again, so copy it into a secret manager right away. If you lose it, rotate the token to get a new secret.
- Rotate: Revoke a token and issue a new one carrying the same grants - ideal for scheduled secret rotation
- Revoke: Immediately and permanently disable a token
- Each token shows its prefix, last-used time, last-used IP, expiry, and rate limit at a glance
Using the API
Authenticate every request with the token as a Bearer credential. A token only ever reaches resources in its own organization.
curl -X POST <API_BASE_URL>/api/v1/public/v1/scheduled-jobs/<JOB_ID>/runs \
-H "Authorization: Bearer dbx_your_token_here" \
-H "Content-Type: application/json" \
-d '{"vars": {}}'
Replace <API_BASE_URL> with the API base URL for your environment. If you're not sure which URL to use, contact our support team and we'll point you to the right endpoint.
API reference
Every endpoint lives under /api/v1/public/v1 and authenticates with a Bearer token. The API covers discovery, full scheduled-job management (create, update, delete, and run), run status with logs and artifacts, and read-only access to environments, connections, and the catalog. Click any endpoint to see its parameters, a ready-to-run curl example, and a sample response. Replace <API_BASE_URL> with the API base URL for your environment (see the note above), and swap the placeholder ids for your own.
A typical flow starts with discovery: list the organization's projects to resolve a project_id, list that project's jobs to resolve a job_id, then trigger a run.
GET /projects -> project ids
GET /scheduled-jobs?project_id=... -> job ids
POST /scheduled-jobs/{job_id}/runs -> trigger a run
GET /scheduled-job-runs/{run_id} -> read run status
You can pass per-run dbt variables in the request body ({"vars": {...}}), which are injected into the triggered run just like variables set on the job. Triggering a run returns 201 Created; if the job's concurrency policy is set to skip when a run is already in progress, the API returns 409 Conflict instead of starting a duplicate.
Rate limit responses
When a token exceeds its per-minute rate limit, the API returns 429 Too Many Requests along with Retry-After, X-RateLimit-Limit, and X-RateLimit-Remaining headers so your client can back off gracefully.
Auditing
Every API call made with a service-account token is recorded in the Audit Log - including the scope requested, the token used, and whether the call was rate limited - so you always have a trail of programmatic activity.
Best practices
- Create a separate service account per system, and a separate token per environment
- Grant the narrowest set of scopes each token actually needs
- Set an expiry and rotate tokens on a schedule
- Store secrets in a secret manager, never in source control
- Use the IP allowlist when the calling system has stable egress IPs