Atribu
API Reference

Readiness

One ordered checklist of what a profile still needs, and the single next thing to do about it.

Endpoint
GET /api/v1/profile/readiness

Scope: analytics:read

Everything a profile needs before ads, outcomes and attribution work end to end, as an ordered list of steps — and for every step that is not done, the one next action.

This is the read to make when a dashboard is empty and you need to say why. Before it existed, answering that meant calling /connections, /goals/definitions, /goals/outcome-counts, /exports/destinations, /conversion-sync/legal, /quality/attribution and /profile/freshness and reasoning about the result yourself.

Derived, never stored

There is no checklist table. Every step is computed at read time from the state the rest of the product already keeps, so a connection that broke an hour ago reads degraded on the next call, and a conversion definition you created a second ago is reflected immediately. Nothing here is cached.

wizard_finished is not the answer to this question. It is the legacy onboarding_completed boolean on GET /api/v1/profile, and it means exactly one thing: a person pressed Finish in Atribu's own setup wizard. Every wizard step is skippable, so it is not evidence that any step below is done — nothing in summary is derived from it. Use it only to tell "has been through onboarding and is still missing things" from "nobody has started".

Request

cURL
curl -H "Authorization: Bearer atb_live_YOUR_KEY" \
  "https://api.atribu.app/api/v1/profile/readiness"
JavaScript
import { Atribu } from "@atribu/node";

const atribu = new Atribu({ apiKey: "atb_live_YOUR_KEY" });
const { data } = await atribu.profile.readiness();

console.log(data.summary.next_step); // "capi_destination_enabled"
Python
import requests

res = requests.get(
    "https://api.atribu.app/api/v1/profile/readiness",
    headers={"Authorization": "Bearer atb_live_YOUR_KEY"},
)
data = res.json()["data"]

There are no parameters. This is a property of the profile's configuration, not of a date range — the only clock involved is the tracker step's seven-day look-back, which is part of that step's definition.

Response

200 OK
{
  "data": {
    "steps": [
      {
        "key": "attribution_enabled",
        "status": "done",
        "why": "Atribu's attribution pipeline is enabled for this profile.",
        "next": null,
        "docs_url": "https://www.atribu.app/docs/getting-started/overview"
      },
      {
        "key": "ad_platform_connected",
        "status": "degraded",
        "why": "meta_ads is connected but its status is \"reconnect_required\" — it is not delivering spend or delivery data. Re-authorize it; the account itself is already linked, so this is a reconnect rather than a first connect.",
        "next": { "handoff_kind": "connect" },
        "docs_url": "https://www.atribu.app/docs/getting-started/connect-ads"
      },
      {
        "key": "conversion_definitions_valid",
        "status": "missing",
        "why": "This profile has no conversion definition that is both revenue_type 'cash' and attribution_eligible, so nothing it records can ever produce a ROAS. Create one with POST /api/v1/goals/definitions; GET /api/v1/goals/definitions/suggestions proposes definitions from the outcome events already arriving.",
        "next": { "method": "POST", "path": "/api/v1/goals/definitions" },
        "docs_url": "https://www.atribu.app/docs/settings/goals"
      }
    ],
    "summary": { "done": 9, "total": 12, "next_step": "ad_platform_connected" },
    "wizard_finished": true
  },
  "meta": { "profile_id": "your-profile-id" }
}

steps is always all twelve steps, in golden-path order. A checklist that omitted the steps it could not evaluate would have a length that varies by profile, and done/total would stop meaning anything.

The four statuses

statusmeaning
doneSatisfied. next is null.
missingNever configured. The ordinary next thing to do.
degradedConfigured, and not working — a reconnect-required ad account is the canonical case. The fix is to re-connect, so a client that drew this as missing would tell someone to connect what they already connected.
blockedCannot be satisfied by you at all, whatever you do. Today only attribution_enabled reaches it.

Only done counts toward summary.done. degraded is not partial credit: a destination that is configured and failing exports nothing, and a checklist that scored it as progress would read 12/12 while the profile sends Meta nothing.

next — what to do about it

Every step that is not done carries a next, in one of two shapes.

{"method", "path"} is a call you can make right now with the credential you already hold. The path is always one this API serves today, never a route that is being built. Where a step's own write does not exist on v1 yet, the nearest existing route is named and why says where the write actually happens.

{"handoff_kind"} is a class of action only a person can take:

kindwhy an agent cannot do it
connectAn OAuth consent. It needs a browser and someone who can grant it.
sign_dpaA signature. One forged on a human's behalf is not a signature.
checkoutA payment.
contact_supportAtribu itself has to change something — see attribution_enabled below.

A handoff_kind tells you what kind of hand-off is owed, not where: minting the actual URL is a separate capability.

summary.next_step is the first non-done step in golden-path order, or null when everything is done. First, not "most important" — the order is the priority.

The steps

attribution_enabled

Whether the atribu_attribution entitlement is on for this profile. When it is not, Atribu's whole pipeline — recompute, conversion extraction, automatic events — is a deliberate no-op, so every other step can be finished and still produce no attributed conversions.

Profiles created through a partner application deliberately do not hold this entitlement. Such a profile answers blocked with contact_support, never an empty checklist — the rest of the steps are still evaluated and still report what they find, because "well configured" and "will never attribute anything" are both facts you need.

tracker_installed

At least one tracking event reached Atribu in the last 7 days. missing points at GET /api/v1/tracking/snippet; the GTM and Shopify-pixel variants are at /api/v1/tracking/installers/gtm and /api/v1/tracking/installers/shopify-pixel.

ad_platform_connected

A meta_ads or google_ads connection exists and is healthy (connected or syncing). One healthy provider is enough — a working Meta connection beside a broken Google one is done.

crm_or_outcome_source_connected

Something is telling Atribu when a lead, appointment or sale happens. Satisfied by a healthy gohighlevel or shopify connection, or by outcome events arriving through POST /api/v1/events — a system that posts its own outcomes needs no CRM connection and no browser.

A connection that exists and is broken outranks the API-events fallback in the why: an ERP that posted an event last month does not make a broken GoHighLevel link fine.

payments_connected

A healthy stripe, mercadopago or shopify connection, or outcome events from POST /api/v1/payments/webpay. Without one, no conversion can carry cash and every ROAS on the profile is unmeasurable.

conversion_definitions_valid

At least one conversion_definitions row that is both revenue_type: "cash" and attribution_eligible. Only cash counts toward ROAS — a profile whose definitions are all pipeline records conversions that can never produce one. GET /api/v1/goals/definitions/suggestions proposes definitions from the outcome events already arriving.

attribution_windows_set

A profile_attribution_settings row exists. why says whether the windows are explicit or Atribu's defaults (click 30 d, view-through 24 h, first-touch 90 d). Defaults are a legitimate answer, so both are done.

next names PATCH /api/v1/profile/attribution-settings (#1060), which writes click_window_days, view_window_hours, first_touch_window_days and cash_window_days directly and creates the row if it does not exist yet. The same fields are editable in the Atribu console under Attribution.

first_conversion_attributed

At least one conversion has been credited to a touch. This is an outcome of the steps above rather than a setting: finish them, then POST /api/v1/attribution/recompute to re-project without waiting for the scheduled run. GET /api/v1/quality/attribution shows how many conversions carry a touch at all.

capi_destination_enabled · capi_rules_enabled

An enabled export destination, and at least one enabled signal rule. A destination with no rules sends nothing, which is why they are two steps. Destination and rule writes are not on this API yet; next names the reads that show what is configured (GET /api/v1/exports/destinations, GET /api/v1/ads/signals) and why says the writes happen in the Atribu console under Conversion Sync.

The Data Processing Agreement has been accepted. GET /api/v1/conversion-sync/legal reads the full compliance record.

plan

done unless the workspace's plan limit is already spent. When active profiles have reached max_active_profiles the step is degraded, not blocked: the profile in hand keeps working, and what is refused is adding another one. A workspace with no subscription row at all reads missing. An admin or beta_tester override bypasses the limit and says so.

whatsapp_dataset_connected

Only meaningful for a profile with a WhatsApp Business account. It is done for every profile without one — there is no click-to-WhatsApp traffic to attribute, so there is nothing to wire.

With a WABA and no enabled WhatsApp dataset, it is missing: click-to-WhatsApp conversions still ship, to the website pixel, where Meta cannot credit them to the click-to-WhatsApp ad that produced them. next is a handoff rather than a call — creating the dataset needs the customer's Meta token, and when Meta withholds business_management a person has to paste the dataset id out of Events Manager. GET /api/v1/exports/destinations reads back what is wired, including each destination's data_source_kind.

What this response does not contain

No account ids, no pixel ids, no amounts, no PII. It says which providers are connected, how many rules exist and which plan tier the workspace is on — which is why it sits at analytics:read rather than a higher scope. A credential that can read the dashboard can be told why the dashboard is empty.

Next steps

On this page