Atribu
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

OperationDeprecatedSunsetSuccessor
POST /api/v1/goals2026-09-052026-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 (standard 300/min, elevated 1200/min, internal 6000/min) that sets its per-minute allowance on client-credential requests. An atb_live_ key keeps its own rate_limit_per_minute — the two meter different principals and are not merged.

2026-09-06

  • Added · #1209GET /api/v1/openapi.json is served from the API host itself, so the spec and the API it describes cannot come from different deploys.
  • Added · #1190DELETE /api/v1/workspaces/{workspaceId} archives a workspace, driven by membership.
  • Changed · #1185 — An OAuth app's empty allowed_return_origins no longer means "no bounce": the effective allowlist derives from its own redirect_uris. return_url_supported on GET /api/v1/me's app-credential branch reports the effective set, and the admin routes return effective_return_origins.

2026-09-05

  • Breaking · #1159 — Two new scopes, workspaces:write and profiles:write, both granted by mcp:write. An MCP user token minted with the default mcp:read grant could create workspaces and profiles; it now gets 403 insufficient_scope and 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 prepareConnectStart path.
  • Added · #1099 — Every operation in the published spec carries structured x-atribu-scopes, x-atribu-auth, x-atribu-idempotency and x-atribu-scope-grain extensions, 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 · #1086POST /api/v1/goals is deprecated in favour of POST /api/v1/goals/definitions, which can express what the older collection cannot (updates, an explicit conversion_key, lookback_window_days, is_default).

2026-09-03

  • Added · #1000GET /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 · #502DELETE /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_keys can exceed the number of keys you minted under it.

2026-09-02

  • Added · #533POST /api/v1/ads/{id}/creative-analysis queues an on-demand creative analysis at the new creatives:write scope. It never runs a model on the request; it answers 202 and the GET on the same path is the poll.
  • Added · #391 — Two commerce reads at the new commerce:read scope: a connected store's catalogue (an ascending change feed you walk with updated_since) and an order lookup by number, email or phone. The order row carries no customer identity.

2026-09-01

  • Breaking · #898GET /api/v1/overview answers spend: null and roas: null — not "0" — when spend is unmeasurable for the requested filters. A measured zero is still "0". Guard the denominator; do not ?? 0 it.
  • Added · #675 — Eight classification writes at goals:write. Every one of them changes the PAST: each queues a full-profile replay, so read replay_queued on the response — false means the change is saved but existing sessions keep their old channels until a replay runs.

On this page