Attribution
How much of your converted traffic carries usable attribution, and where the gaps are.
| Endpoint | Method | Path | Permission |
|---|---|---|---|
| Get attribution coverage How much revenue attribution explains, and why not | GET | /v1/attribution/coverage | metrics:read |
Base URL https://app.sourceloop.ai/api/v1
Get attribution coverage
How much revenue attribution explains, and why not
GET /v1/attribution/coverage
Requires metrics:read
Call this before concluding that tracking is broken. Recorded revenue is classified per fact into: `attributed`, `predates_tracking` (the CUSTOMER arrived before the tracker existed), `imported_contact` (loaded from a CRM or spreadsheet), and `no_visitor` / `no_sessions` (the tracker was running and the person still could not be tied to a visit).
The first three are permanent facts about the business; only the last two indicate a problem. `meta.expected_gap_amount` and `meta.worth_investigating_amount` split them, because summing everything into one "unattributed" number reported a working install as 93% broken on the workspace this was measured on.
`predates_tracking` is keyed on when the relationship started, not on the payment date: classifying per payment put 92.8% of the money in the wrong bucket.
These are revenue FACTS as recorded, while /metrics counts credit as distributed, so the two do not tie out line for line.
curl -s -X GET "https://app.sourceloop.ai/api/v1/attribution/coverage?website=acme.com&period=last%2030%20days" \
-H "Authorization: Bearer $SOURCELOOP_API_KEY" const res = await fetch(
"https://app.sourceloop.ai/api/v1/attribution/coverage?website=acme.com&period=last%2030%20days",
{
method: "GET",
headers: {
Authorization: `Bearer ${process.env.SOURCELOOP_API_KEY}`,
},
},
);
const data = await res.json(); import os, requests
res = requests.get(
"https://app.sourceloop.ai/api/v1/attribution/coverage?website=acme.com&period=last%2030%20days",
headers={"Authorization": f"Bearer {os.environ['SOURCELOOP_API_KEY']}"},
)
data = res.json() Query parameters
websitestringWebsite domain, e.g. acme.com. Required only when the key covers more than one.
periodstringPlain-language period: "last 30 days", "yesterday", "July 2026", or "2026-07-01..2026-07-31". Ignored when from/to are given.
Example
last 30 days
Responses
-
200One row per bucket -
429Too many requests for this workspace in the current minute. Wait Retry-After seconds and repeat the request unchanged.