API Reference
Base: https://app.durum.ai/api/v1 Auth: header Authorization: Bearer durum_sk_live_… All routes are GET (read-only) and return { "data": … }.
Common period params: from and to in YYYY-MM-DD format (optional).
Self-documenting index
GET /v1 (no route) returns the list of available routes and their required scope.
Dashboard
| Route | Scope | Params |
|---|---|---|
GET /dashboard/kpis | read:dashboard | from, to |
GET /dashboard/daily | read:dashboard | from, to |
GET /dashboard/breakdowns | read:dashboard | from, to, dim = source|campaign|product|rep |
Ads
| Route | Scope | Params |
|---|---|---|
GET /ads/spend | read:ads | from, to |
GET /ads/campaigns | read:ads | from, to |
GET /ads/rules | read:ads | — your automated ad rules |
GET /ads/rules/runs | read:ads | rule_id, limit — a rule's run history |
Attribution
| Route | Scope | Params |
|---|---|---|
GET /attribution | read:attribution | from, to |
GET /attribution/health | read:attribution | — |
GET /attribution/report | read:attribution | from, to |
Events
| Route | Scope | Params |
|---|---|---|
GET /events | read:events | type, from, to, limit (max 200), cursor, rep |
GET /events/summary | read:events | from, to |
Pagination: events returns 50 rows by default; use cursor (ISO timestamp of the last row) for the next page.
Sales & Finance
| Route | Scope | Params |
|---|---|---|
GET /sales/summary | read:sales | from, to |
GET /sales/reps | read:sales | from, to |
GET /sales/cycle | read:sales | from, to |
GET /finance/pnl | read:finance | from, to — margin fields are stripped |
Funnel
| Route | Scope | Params |
|---|---|---|
GET /funnel | read:funnel | from, to |
Contacts & Calls
| Route | Scope | Params |
|---|---|---|
GET /contacts | read:contacts | from, to, limit (max 500), offset, search |
GET /contacts/calls | read:calls | email |
GET /contacts/customers | read:contacts | — |
GET /contacts/purchases | read:contacts | from, to |
ICP & Pixels
| Route | Scope | Params |
|---|---|---|
GET /icp/criteria | read:icp | — |
GET /capi/pixels | read:capi | — — your connected Meta pixels (IDs, default); tokens are never returned |
Writes (actions)
Writes use PUT with a JSON body and require a write:* scope.
| Route | Scope | Body |
|---|---|---|
PUT /goals | write:goals | { "goals": { … } } — replaces your KPI goals |
PUT /sale-rule | write:settings | { "sale_rule": { … } } — sale counting rule |
PUT /icp | write:icp | { "icp": { … } } — your ICP criteria |
POST /ads/rules/enable | write:ads | { "rule_id": "…", "enabled": true } — enable/disable a rule |
POST /ads/rules/dry-run | write:ads | { "rule_id": "…", "dry_run": true } — simulation mode (no Meta action) |
POST /ads/rules/delete | write:ads | { "rule_id": "…" } — delete a rule |
bash
curl -X PUT "https://app.durum.ai/api/v1/goals" \
-H "Authorization: Bearer durum_sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"goals": {"revenue_target": 100000}}'Response codes
| Code | Meaning |
|---|---|
200 | OK — { "data": … } |
401 | Missing or invalid API key |
403 | insufficient_scope — the key lacks the required scope |
404 | Unknown route |
429 | Rate limit exceeded (see X-RateLimit-* headers) |
Example
bash
curl "https://app.durum.ai/api/v1/attribution?from=2026-06-01&to=2026-06-30" \
-H "Authorization: Bearer durum_sk_live_YOUR_KEY"json
{ "data": [ { "ad_name": "…", "attributed_revenue": 12400, "spend": 3100, "roas": 4.0 } ] }