Reporting API

The report endpoint returns totals rather than individual leads: new leads and CRM statuses reached, per day (or for a whole period) and per channel or UTM source, medium or campaign. It is the simplest way to feed a dashboard.

You need an API key and the project ID.

Request

GET https://api.tagpilot.io/integrations/v1/lead-tracking/projects/{projectId}/report
Parameter Values Default
from, to First and last day as YYYY-MM-DD, both included; at most 366 days required
timezone IANA time zone the days are cut in, e.g. Europe/Warsaw UTC
granularity day for a row per day, total for the whole period day
group_by Comma-separated: channel, utm_source, utm_medium, utm_campaign; empty for no grouping channel
curl -H "Authorization: Bearer $TAGPILOT_KEY" -H "User-Agent: acme-dashboard/1.0" \
  "https://api.tagpilot.io/integrations/v1/lead-tracking/projects/$PROJECT_ID/report?from=2026-10-01&to=2026-10-07&timezone=Europe/Warsaw&group_by=channel"

Response

{
  "from": "2026-10-01",
  "to": "2026-10-07",
  "timezone": "Europe/Warsaw",
  "granularity": "day",
  "group_by": ["channel"],
  "statuses": ["Client", "Prospect", "Suspect"],
  "rows": [
    { "date": "2026-10-01", "channel": "Paid Search", "leads": 4, "statuses": { "Client": 0, "Prospect": 1, "Suspect": 3 } },
    { "date": "2026-10-01", "channel": "Organic Social", "leads": 2, "statuses": { "Client": 0, "Prospect": 0, "Suspect": 1 } },
    { "date": "2026-10-01", "channel": "Not tracked", "leads": 0, "statuses": { "Client": 1, "Prospect": 2, "Suspect": 9 } }
  ],
  "totals": { "leads": 6, "statuses": { "Client": 1, "Prospect": 3, "Suspect": 13 } }
}
Field Meaning
statuses Every CRM status reached in the period; each row has a count for each
rows[].date The day, in timezone (only with granularity=day)
rows[].channel, utm_* The group, one field per group_by dimension
rows[].leads Leads whose first form submission was on that day
rows[].statuses Leads that reached each CRM status on that day
totals The same counts for the whole period

Rows are ordered by day, then by the most leads. Days and groups with nothing to count are left out, so fill gaps with zeros in your chart.

How leads are counted

If your CRM sends status changes without a timestamp, they are dated when Tag Pilot receives them, so days are only as precise as your CRM sync interval.

Sources and channels

A form submission's source is taken from, in this order: the form page's UTM parameters or ad click ID; the visitor's landing page before the form (its UTMs, click ID or referrer); the external site that referred the form page; an ad click ID kept in the ad platforms' cookies; otherwise (direct).

An ad click ID without UTMs reads like Google Analytics auto-tagging: gclid becomes google / cpc, msclkid becomes bing / cpc. fbclid alone counts as organic, because Meta adds it to organic links too. A referrer becomes the site's host with medium organic for search engines and referral otherwise.

Channels follow the Google Analytics 4 default channel group:

Channel When
Paid Search Google or Microsoft Ads click ID, or a search engine source with a paid medium (cpc, ppc, paid…)
Paid Social TikTok, LinkedIn, X, Reddit, Pinterest or Snapchat click ID; a social source with a paid medium; or medium paid_social
Display Medium display, banner, cpm, or a Google dclid
Paid Other Any other paid medium
Email Source or medium email, newsletter, or a webmail referrer
Organic Search Medium organic, or a search engine source
Organic Social Medium social, or a social network source (Facebook, Instagram, LinkedIn, X, TikTok, YouTube, …)
Affiliates Medium affiliate
Referral Medium referral, e.g. another website linking to yours
Direct No source at all
Unassigned UTMs that match none of the above
Not tracked No form submission before the status (see above)

When a link has UTM parameters, they decide the channel, source and medium, even if an ad click ID is present too.

Examples

Totals per channel for October:

…/report?from=2026-10-01&to=2026-10-31&granularity=total

Daily leads per campaign:

…/report?from=2026-10-01&to=2026-10-31&group_by=utm_source,utm_medium,utm_campaign

Daily totals with no grouping:

…/report?from=2026-10-01&to=2026-10-31&group_by=