A read-only JSON API for the numbers on your dashboard: sessions and leads by channel, source, campaign, landing page, referrer and form, and the lead log's attribution columns. Use it to feed Looker Studio, Google Sheets or your own reports. It can change nothing, and it never returns contact details, form answers or the visitor and session ids TraceLead uses for counting.
The machine-readable description is report-api.v1.json (OpenAPI 3.1).
Tokens
An organisation owner creates tokens on the organisation page under Reporting API. A token starts with tlapi_, is shown once, and reads every site of the organisation. Revoke it there when it is no longer needed; the page shows when each token was last used. Send it as a bearer token:
curl -H "Authorization: Bearer tlapi_…" https://app.tracelead.io/api/v1/sites
Requests are limited to 60 per minute per token; above that the API answers 429. A missing, revoked or invalid token gets 401. A site of another organisation gets 404.
Endpoints
GET /api/v1/sites
The organisation's sites: public_id, name, status, domains, created_at.
GET /api/v1/sites/{public_id}/stats
Totals for a period, compared with the period of the same length before it, and one breakdown.
| Parameter | Meaning |
|---|---|
from, to |
Whole UTC days, YYYY-MM-DD. Default: the last 30 days. At most 366 days. |
group_by |
channel (default), source, campaign, term, content, landing_page, referrer_host, form or day |
{
"site": "tl_abcdefghij1234567890",
"from": "2026-09-13",
"to": "2026-10-12",
"group_by": "channel",
"totals": { "sessions": 1840, "leads": 61, "contact_clicks": 22, "conversion_rate": 3.3, "previous": { "sessions": 1612, "leads": 48, "contact_clicks": 17 } },
"rows": [
{ "key": "paid_search", "label": "Paid search", "sessions": 702, "leads": 31, "contact_clicks": 9, "conversion_rate": 4.4, "previous": { "sessions": 655, "leads": 25, "contact_clicks": 6 } }
]
}
With group_by=day each row is { "date": "2026-10-12", "sessions": 64, "leads": 3, "contact_clicks": 1 }.
contact_clicks counts clicks on phone, email, SMS and WhatsApp links (Contact clicks). It is 0 unless the site has contact clicks switched on, and it is never part of leads or conversion_rate. Rows grouped by form always show 0, because a click has no form.
GET /api/v1/sites/{public_id}/leads
Lead attribution records, newest first, 100 per page: id, occurred_at, channel, source, medium, utm_campaign, utm_term, utm_content, utm_id, click_id_type, referrer_host, landing_page, page_path, form_id, first_touch_at. Filter with from, to, channel and form_id. Pass next_cursor from a response as cursor to get the next page; it is null on the last page.
Google Sheets
Extensions → Apps Script, paste this, set the token and site id, and run importChannels (or attach it to a daily trigger):
const TOKEN = 'tlapi_…';
const SITE = 'tl_abcdefghij1234567890';
function importChannels() {
const response = UrlFetchApp.fetch(`https://app.tracelead.io/api/v1/sites/${SITE}/stats?group_by=channel`, {
headers: { Authorization: `Bearer ${TOKEN}` },
});
const body = JSON.parse(response.getContentText());
const rows = body.rows.map((row) => [row.label, row.sessions, row.leads, row.conversion_rate]);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('TraceLead') || SpreadsheetApp.getActiveSpreadsheet().insertSheet('TraceLead');
sheet.clearContents();
sheet.getRange(1, 1, 1, 4).setValues([['Channel', 'Sessions', 'Leads', 'Conversion %']]);
if (rows.length) sheet.getRange(2, 1, rows.length, 4).setValues(rows);
}
Keep the token in Project Settings → Script properties rather than in the code if others can open the sheet.
Looker Studio
Looker Studio reads a Google Sheet directly, so the simplest route is the Sheets script above on a daily trigger with group_by=day and group_by=channel written to two tabs, then Add data → Google Sheets in Looker Studio. A community JSON connector pointed at the stats endpoint with an Authorization header works too; TraceLead does not publish its own connector.
What the API never returns
Names, email addresses, phone numbers, form answers, IP addresses, user agents, full referrer URLs, click id values, visitor ids and session ids.