The Reporting API
Read your websites' stats, leads, pages, sources and sanitised events from your own code with an API token.
The Reporting API gives your scripts, dashboards and reporting tools the same numbers as the website's analytics page. It is read-only and returns JSON.
https://pixelrelay.co/api/v1
The full machine-readable description is the OpenAPI document at https://pixelrelay.co/api/v1/openapi.json. Load it into Postman, Insomnia or any OpenAPI tool.
Get a token
- Open your name in the top bar, then API tokens.
- Give the token a name, choose its abilities, optionally restrict it to one website and choose when it expires.
- Click Create token and copy it. It is shown once.
Send it with every request:
curl https://pixelrelay.co/api/v1/websites \
-H "Authorization: Bearer 12|pxr_your_token" \
-H "Accept: application/json"
The website's API key and server key never work here: they only send events. Keep tokens on a server, never in a web page, and revoke a token on the same page the moment you stop using it.
Clients need the Use the Reporting API permission and View analytics for the website. Ask your account team if you do not see API tokens. Taking a permission away stops existing tokens at once.
Abilities
| Ability | Allows |
|---|---|
websites:read |
GET /websites and GET /websites/{id} |
stats:read |
the summary, daily, by-event, pages, sources and forms endpoints |
events:read |
GET /websites/{id}/events, the sanitised event log |
ads:read |
ad spend and cost per lead: the /ads endpoint and the ads block of the summary. The owner also needs View ad performance. |
A token restricted to one website can only read that website. GET /token shows the calling token's abilities, website and rate limit, whatever its abilities.
Dates and time zone
fromandtoare dates like2026-10-01. Both days are included.- Without them you get the last 30 days, ending today. A range can be at most 366 days.
- Days are UTC days, the same days as the daily statistics. The
meta.timezonefield of every response says so.
Endpoints
| Endpoint | What it returns |
|---|---|
GET /websites |
The websites the token can read: id, name, domains, is_active, last_event_at. |
GET /websites/{id}/summary |
Received, delivered, failed, delivery rate, visitors, page views, leads and the visitor to lead rate. |
GET /websites/{id}/stats/daily |
One row per day, empty days included. Add event=Lead to count one Meta event. |
GET /websites/{id}/stats/by-event |
Received, delivered and failed per Meta event. |
GET /websites/{id}/stats/pages |
The most viewed cleaned page addresses, with visitors. limit up to 100. |
GET /websites/{id}/stats/sources |
Referring sites with their events and leads, plus the referred and direct totals. |
GET /websites/{id}/stats/forms |
Events, leads and deliveries per form, for forms that report one (Gravity Forms through the WordPress plugin). |
GET /websites/{id}/ads |
Spend, cost per lead, CPM, CTR and the click to lead funnel, one row per day, and the split by campaign, ad set or ad (level=campaign, adset or ad), with the unattributed leads. Needs ads:read. |
GET /websites/{id}/events |
The sanitised event log, newest first, 50 per page (per_page up to 200). Filter with event and status=delivered or failed. |
The stats endpoints also take domain to count one of the website's domains, as the domain filter on the analytics page does.
Leads are the Lead events the relay received. They are not Meta's attributed lead count. For tokens with ads:read, the summary adds the ad spend under ads: spend, currency, cost_per_lead (spend divided by the relay's leads), and Meta's own count labelled meta_reported_leads with meta_cost_per_lead, so the two are never confused. ads is null when the website has no ad spend or the token cannot read it. See Ad performance and cost per lead for how each number is worked out.
Example: the last 7 days
curl "https://pixelrelay.co/api/v1/websites/9b1d.../summary?from=2026-10-15&to=2026-10-21" \
-H "Authorization: Bearer 12|pxr_your_token"
{
"data": {
"received": 1840,
"delivered": 1832,
"failed": 8,
"delivery_rate": 99.6,
"visitors": 612,
"page_views": 1590,
"leads": 41,
"lead_rate": 6.7,
"ads": null
},
"meta": {
"website": "9b1d...",
"from": "2026-10-15",
"to": "2026-10-21",
"timezone": "UTC",
"generated_at": "2026-10-21T09:14:03Z"
}
}
Paging through events
GET /websites/{id}/events returns meta.next_cursor. Pass it back as cursor until it is null:
curl "https://pixelrelay.co/api/v1/websites/9b1d.../events?event=Lead&cursor=eyJpZCI6..." \
-H "Authorization: Bearer 12|pxr_your_token"
Errors
Every error has the same shape:
{ "error": { "status": 403, "code": "missing_ability", "message": "This token lacks the \"events:read\" ability." } }
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated |
No token, or it is wrong, revoked or expired. |
| 403 | missing_ability |
The token does not have the ability the endpoint needs. |
| 403 | token_website_restricted |
The token is restricted to another website. |
| 403 | api_access_disabled |
API access was turned off for the account. |
| 403 | forbidden |
The account may not read stats for this website. |
| 404 | not_found |
No such website, or not one the account can see. |
| 422 | validation_failed |
A parameter is wrong. errors lists each one. |
| 429 | rate_limited |
Too many requests. Wait for the seconds in the Retry-After header. |
Rate limits and caching
Each token may make 60 requests a minute unless your account has its own limit. X-RateLimit-Limit and X-RateLimit-Remaining show where you are. Responses are cached for 60 seconds, so polling faster than once a minute returns the same numbers.
What the API shows
Only what the relay keeps after sanitising, see What Pixel Relay stores:
- cleaned page addresses, the site's own host and referring hosts only
- event names, the form reference like
gf:81, the cleaned event details and whether Meta accepted the event - a device and browser family, like
MobileandSafari
It never returns visitor IP addresses or their hashes, full user agents, hashed customer details or any Meta credentials. Visitors, page views, leads, pages, sources, forms and events come from the event log, which is kept for 90 days. Received, delivered and failed totals come from the daily statistics, which are kept for as long as the website exists.
Related articles
Still stuck?
Tell us what you are trying to do and we will help you set it up.