API Reference
Changelog
Every developer-facing change to the /api/v1 surface, newest first
Developer-facing changes to https://api.atribu.app/api/v1/**. See the deprecation policy for what a removal looks like before it happens.
Active deprecations
| Operation | Deprecated | Sunset | Successor |
|---|---|---|---|
POST /api/v1/goals | 2026-09-05 | 2026-12-04 | /api/v1/goals/definitions |
Changes
Each line links the issue that carries the full reasoning — what broke, what to change, and why the decision went the way it did.
2026-09-07
- Added · #452 — Per-consumer usage: request counts, the 4xx/5xx split and p50/p95 latency, per API key for a workspace and per registered app for Atribu ops. Every rate-limited response now also carries
X-RateLimit-Reset. - Changed · #452 — A registered consumer app now has a rate TIER (
standard300/min,elevated1200/min,internal6000/min) that sets its per-minute allowance on client-credential requests. Anatb_live_key keeps its ownrate_limit_per_minute— the two meter different principals and are not merged.
2026-09-06
- Added · #1209 —
GET /api/v1/openapi.jsonis served from the API host itself, so the spec and the API it describes cannot come from different deploys. - Added · #1190 —
DELETE /api/v1/workspaces/{workspaceId}archives a workspace, driven by membership. - Changed · #1185 — An OAuth app's empty
allowed_return_originsno longer means "no bounce": the effective allowlist derives from its ownredirect_uris.return_url_supportedonGET /api/v1/me's app-credential branch reports the effective set, and the admin routes returneffective_return_origins.
2026-09-05
- Breaking · #1159 — Two new scopes,
workspaces:writeandprofiles:write, both granted bymcp:write. An MCP user token minted with the defaultmcp:readgrant could create workspaces and profiles; it now gets403 insufficient_scopeand nothing is created on the way to that refusal. Sessions and app credentials are unchanged. - Breaking · #1154 — A webhook subscription URL must point at a public host; a private or non-routable target is refused at registration AND again at delivery time, and redirects are no longer followed.
- Added · #1109 — An agent can start a provider connect and hand the human a session-less URL. Stripe and MercadoPago join Meta Ads, Google Ads, Google Search Console and GoHighLevel on the shared
prepareConnectStartpath. - Added · #1099 — Every operation in the published spec carries structured
x-atribu-scopes,x-atribu-auth,x-atribu-idempotencyandx-atribu-scope-grainextensions, plus a response example per tag. - Added · #1089 — Every error envelope now carries
docs_url, pointing at that exact code's section of the generated errors reference. - Deprecated · #1086 —
POST /api/v1/goalsis deprecated in favour ofPOST /api/v1/goals/definitions, which can express what the older collection cannot (updates, an explicitconversion_key,lookback_window_days,is_default).
2026-09-03
- Added · #1000 —
GET /api/v1/workspaces/{workspaceId}/pii-access-log— who read this workspace's customer/visitor personal data, when, through which route and with what result. Durable for 365 days. - Changed · #502 —
DELETE /api/v1/connections/{id}now also revokes key generations older than the authorization that names them, when the authorization revoked is the app's last live one on that profile.revoked_keyscan exceed the number of keys you minted under it.
2026-09-02
- Added · #533 —
POST /api/v1/ads/{id}/creative-analysisqueues an on-demand creative analysis at the newcreatives:writescope. It never runs a model on the request; it answers202and theGETon the same path is the poll. - Added · #391 — Two commerce reads at the new
commerce:readscope: a connected store's catalogue (an ascending change feed you walk withupdated_since) and an order lookup by number, email or phone. The order row carries no customer identity.
2026-09-01
- Breaking · #898 —
GET /api/v1/overviewanswersspend: nullandroas: null— not"0"— when spend is unmeasurable for the requested filters. A measured zero is still"0". Guard the denominator; do not?? 0it. - Added · #675 — Eight classification writes at
goals:write. Every one of them changes the PAST: each queues a full-profile replay, so readreplay_queuedon the response —falsemeans the change is saved but existing sessions keep their old channels until a replay runs.