Pixel API endpoints reference
Every endpoint, with the scope it needs and the parameters it takes. Paths are relative to https://admaxxer.com/api/v1; your workspace always comes from the API key, and every report and write call names the website with website_id.
JSON in, JSON out · Workspace from the key · Filters on six reports · Cursor pagination
All endpoints
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /me | Any key | The key's name, scopes and workspace ID. Returned without the usual wrapper. |
| GET | /pixel/websites | pixel:read | Your websites, newest first. Paginated with limit and cursor. |
| GET | /pixel/analytics/metadata | pixel:read | The same websites as a single list (websites, workspace_id), up to limit. |
| GET | /pixel/analytics/pages | pixel:read | Top pages with views, sessions, bounces, bounce rate and average time. Dates required; filters apply. |
| GET | /pixel/analytics/referrers | pixel:read | Where visitors came from. mode picks the grouping: referrer (default), utm_source, utm_campaign, keyword or channel. Dates required; filters apply. |
| GET | /pixel/analytics/campaigns | pixel:read | One row per UTM campaign, with its main source and medium. Visits without a campaign show as (none). Dates required. |
| GET | /pixel/analytics/hostnames | pixel:read | Referring hosts, with common variants folded together (every facebook.com subdomain counts as facebook.com) and your own domains left out. Dates required. |
| GET | /pixel/analytics/countries | pixel:read | Traffic by country (ISO-2 code). Dates required; filters apply. |
| GET | /pixel/analytics/devices | pixel:read | Traffic by device type. Dates required; filters apply. |
| GET | /pixel/analytics/browsers | pixel:read | Traffic by browser. Dates required; filters apply. |
| GET | /pixel/analytics/operating-systems | pixel:read | Traffic by operating system. Dates required; filters apply. |
| GET | /pixel/analytics/timeseries | pixel:read | One metric over time (metric, default visitors). Covers the last 30 days unless you pass dates. |
| GET | /pixel/analytics/timeseries/breakdown | pixel:read | The same series with metric=revenue by default, including new, renewal and refund revenue columns. |
| GET | /pixel/analytics/realtime | pixel:read | The last five minutes: live events, live visitors and sparklines in five-second steps. |
| GET | /pixel/analytics/realtime/map | pixel:read | The last five minutes by country: visitors and events per country. |
| GET | /pixel/analytics/overview | pixel:read | A tracking check: how many events arrived in the last five minutes, and when the latest one landed. |
| GET | /pixel/visitors/{visitor_id} | pixel:read | That visitor's most recent goal conversions (up to 100): time, goal name, details and session. |
| GET | /pixel/goals/{goal_name}/metadata | pixel:read | How a goal's text properties break down: distinct visitors per property and value. revenue_sum is always 0 — goals don't carry revenue. |
| GET | /pixel/segments | pixel:read | Saved segments for one website. |
| POST | /pixel/segments/{id}/apply | pixel:read | Returns a saved segment's filters object. |
| POST | /pixel/segments | pixel:write | Save a segment. |
| PATCH | /pixel/segments/{id} | pixel:write | Rename a segment or replace its filters. |
| DELETE | /pixel/segments/{id} | pixel:write | Delete a segment. |
| POST | /pixel/goals | pixel:write | Record one goal conversion. |
| POST | /pixel/payments | pixel:write | Record one payment. |
| POST | /pixel/events | pixel:write | Record one pageview or custom event. |
| POST | /pixel/identify | pixel:write | Attach your own identifier to a pixel visitor. |
Region and city breakdowns
/pixel/analytics/regionsand/pixel/analytics/citiesexist but always return503, because visitor location is recorded at country level only. Use/pixel/analytics/countries, and don't retry those two.
A lower-level GET /pixel/metrics/{report} endpoint also exists for advanced integrations. The named endpoints above cover the common reports — if you need one that isn't listed, email support@admaxxer.com.
Report parameters
| Parameter | Used by | Notes |
|---|---|---|
website_id | Every report, visitor history and goal metadata | Required. Your admx_ website ID. If it isn't one of your workspace's websites the call returns 403 forbidden. |
from_date, to_date | Pages, referrers, campaigns, hostnames, countries, devices, browsers, operating systems | Required on these. Whole days as YYYY-MM-DD; both days are included. Leaving either out returns 400 from_date_and_to_date_required. Optional on time series. Goal metadata reads from_date only and covers all time without it. |
limit | Reports and website lists | Maximum rows, up to 1,000. The default depends on the report — 100 for most, 250 for countries. |
mode | Referrers | referrer (default), utm_source, utm_campaign, keyword or channel. |
metric | Time series | visitors, sessions, pageviews, conversions, revenue, bounce_rate, session_time or conversion_rate. Anything else returns 400 invalid_metric. |
granularity | Time series | hour, day (default), week or month. |
lookback_days | Time series | How many days back from today to cover when you don't pass both dates. Default 30. |
tz | Time series | Time zone used to bucket the series, for example America/New_York. Default UTC. |
Each time-series row has ts, value, revenue_new, revenue_renewal and revenue_refund (the revenue columns are 0 unless the metric is revenue). Revenue is in major currency units — 89.5, not 8950 — and is summed as recorded, without currency conversion.
If from_date falls before the earliest day your plan's data retention keeps, the report starts at that day instead.
Filtering reports
Add filters to the query string of the pages, referrers, countries, devices, browsers and operating-systems reports. Each filter narrows the result further. The other reports don't apply them.
| Filter | Narrows by |
|---|---|
country | Country (ISO-2 code, e.g. US) |
device | Device type (desktop / mobile / tablet) |
browser | Browser |
os | Operating system |
referrer (also ref) | Referring domain, for example google.com |
page | Page path (e.g. /pricing) |
utm_source | UTM source |
utm_medium | UTM medium |
utm_campaign | UTM campaign |
utm_term | UTM term |
utm_content | UTM content |
Choose how a filter matches with a prefix on its value. Separate several values with commas (up to 20 per filter). Matching is case-sensitive.
- Is (the default):
country=USorcountry=US,CA. Theis:prefix is optional. - Is not:
country=is_not:US. - Contains:
utm_campaign=contains:summer.
A filter the API can't apply is rejected with 400 unsupported_filter instead of being silently ignored, so you never get unfiltered numbers by mistake:
| Not supported | Why, and what to use |
|---|---|
region | Not recorded — location is captured at country level. Use country. |
city | Not recorded — location is captured at country level. Use country. |
source | Ambiguous. Use utm_source for the campaign source or referrer for the referring site. |
via | Ambiguous. Use referrer. |
entry_page | Entry page is worked out per session, so it can't filter individual rows. |
hostname | Use the /pixel/analytics/hostnames report, or filter by referrer. |
400 response for ?region=California
{
"status": "error",
"error": {
"code": "unsupported_filter",
"message": "region is not tracked at the pageview level. Filter by `country` instead.",
"details": {
"filter": "region",
"supported": [
"country",
"device",
"browser",
"os",
"referrer",
"page",
"utm_source",
"utm_medium",
"utm_campaign",
"utm_term",
"utm_content"
]
}
},
"meta": {
"request_id": "req_…"
}
}
Pagination
GET /pixel/websites returns up to limit websites (default 100, maximum 1,000), newest first. While pagination.has_more is true, send pagination.next_cursor back as cursor to get the next page. Treat cursors as opaque; an invalid cursor starts again from the first page.
Sending data from your server
Use the write endpoints where the browser pixel can't run. To tie a server-side record to the visitor the pixel saw, read the visitor ID in the browser with window.admaxxer.getVisitorId(), pass it to your server with the order or sign-up, and send it as visitor_id. Without a visitor_id, Admaxxer creates a new visitor for that record.
Copy website_id exactly
Write calls don't check
website_idagainst your workspace. A record sent with a mistyped website ID is accepted but won't appear in any report, so copy the ID fromGET /pixel/websites.
accepted: true means the record was queued for writing; it shows up in reports shortly afterwards. Timestamps take Unix time in milliseconds or an ISO-8601 string, and default to the time of the request.
POST /pixel/payments
| Field | Type | Notes |
|---|---|---|
website_id | string, required | Your admx_ website ID. |
transaction_id | string, required (1–255) | Your order or charge ID. Payments are de-duplicated on it, so re-sending the same payment doesn't count it twice. |
amount | number, required | In major currency units — 89.5, not 8950. |
currency | string, 3 letters | ISO code such as USD. Default USD. |
visitor_id | string, up to 128 | The pixel visitor ID, so the payment can be attributed to the visit behind it. |
timestamp | number or string | Unix milliseconds or ISO-8601. Default: now. |
Returns accepted, visitor_id and transaction_id.
POST /pixel/goals
| Field | Type | Notes |
|---|---|---|
website_id | string, required | Your admx_ website ID. |
goal_name | string, required (1–255) | The conversion's name, for example signup. |
visitor_id | string, up to 128 | The pixel visitor ID. |
properties | object | Extra detail about the conversion. Text values can be broken down with GET /pixel/goals/{goal_name}/metadata. |
timestamp | number or string | Unix milliseconds or ISO-8601. Default: now. |
Returns accepted, visitor_id and goal_name.
POST /pixel/events
| Field | Type | Notes |
|---|---|---|
website_id | string, required | Your admx_ website ID. |
name | pageview (default) or custom | To record a payment, use POST /pixel/payments — its transaction_id keeps every payment distinct. |
path | string, up to 2,048 | Page path. Default /. |
referrer | string, up to 2,048 | The referring URL. |
visitor_id, session_id | string, up to 128 | Generated for you if left out. |
ts | number or string | Unix milliseconds or ISO-8601. Default: now. |
properties | object | For custom events: goal_name sets the conversion's name (default custom_event), and the whole object is kept as its details. |
utm_source, utm_medium, utm_campaign, utm_term, utm_content | string, up to 255 | Campaign tags. |
Returns accepted, visitor_id and session_id.
POST /pixel/identify
| Field | Type | Notes |
|---|---|---|
website_id | string, required | Your admx_ website ID. |
visitor_id | string, required | The pixel visitor ID. |
external_id | string, required (up to 512) | Your identifier for the person, such as a user ID or email. Admaxxer stores a one-way hash of it, never the raw value. |
traits | object | Stored as sent — leave personal data out. |
Returns accepted and visitor_id.
Saved segments
Segments are named filter sets you store for a website and fetch back to reuse in report requests. Admaxxer keeps the filters object exactly as you send it.
Segments use the website's id
Segment calls identify the website by its
id(a UUID) fromGET /pixel/websites— not by theadmx_website ID the reports use. Passing theadmx_ID here returns an error.
GET /pixel/segments?website_id={id}— list a website's segments. Withoutwebsite_idthe call returns400 invalid_website.POST /pixel/segmentswithwebsite_id,name(1–200 characters, unique per website) andfilters(an object, default{}) — returns201and the new segment. A name already in use returns409 duplicate_name; a website outside your workspace returns404 not_found.PATCH /pixel/segments/{id}withname,filtersor both — sending neither returns400 empty_patch.DELETE /pixel/segments/{id}— returnsdeleted: trueand the segment'sid.POST /pixel/segments/{id}/apply— returns the storedfiltersfor you to turn into query parameters.
Examples
List your websites
curl "https://admaxxer.com/api/v1/pixel/websites?limit=1" \
-H "Authorization: Bearer $ADMAXXER_API_KEY"
{
"status": "success",
"data": [
{
"id": "6f1c2a7e-3b4d-4e5f-9a8b-1c2d3e4f5a6b",
"websiteId": "admx_Xq3vN8kLp2RtY7wZb4cD9eFg",
"allowedDomains": ["example.com"],
"createdAt": "2026-04-17T09:30:12.418Z"
}
],
"meta": { "request_id": "req_2b6f0a3e-5d1c-4e8b-9f7a-0c3d6e9b2a14" },
"pagination": { "has_more": true, "next_cursor": "eyJ0cyI6…" }
}
Top pages for US visitors, excluding newsletter traffic
curl "https://admaxxer.com/api/v1/pixel/analytics/pages?website_id=admx_your_site_id&from_date=2026-09-01&to_date=2026-09-30&country=US&utm_source=is_not:newsletter&limit=3" \
-H "Authorization: Bearer $ADMAXXER_API_KEY"
{
"status": "success",
"data": {
"data": [
{ "path": "/", "views": "4210", "sessions": "2984", "bounces": "1702", "bounce_rate": 57.04, "avg_time_seconds": 41.3 },
{ "path": "/pricing", "views": "1388", "sessions": "1017", "bounces": "402", "bounce_rate": 39.53, "avg_time_seconds": 68.9 },
{ "path": "/blog/attribution-guide", "views": "912", "sessions": "804", "bounces": "610", "bounce_rate": 75.87, "avg_time_seconds": 22.4 }
],
"meta": [],
"rows": 3,
"statistics": { "elapsed": 0.018, "rows_read": 61505, "bytes_read": 2471088 },
"data_status": "ok"
},
"meta": { "request_id": "req_8e3a1f6c-2b7d-4c09-a5e4-7f1b9d0c3e52" }
}
bounce_rate is a percentage and avg_time_seconds is in seconds. Counts such as views are strings so large values keep full precision.
Record a payment from your server
curl -X POST https://admaxxer.com/api/v1/pixel/payments \
-H "Authorization: Bearer $ADMAXXER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"website_id": "admx_your_site_id",
"transaction_id": "order_10482",
"amount": 89.5,
"currency": "USD",
"visitor_id": "3f9c1b2e-8a47-4d1e-9b6a-2c5e7f0d1a93"
}'
{
"status": "success",
"data": {
"accepted": true,
"visitor_id": "3f9c1b2e-8a47-4d1e-9b6a-2c5e7f0d1a93",
"transaction_id": "order_10482"
},
"meta": { "request_id": "req_1b7e9d42-6c3a-4f85-a0d2-8e4c7b9f1a36" }
}
Frequently asked questions
Q: Why do some numbers come back as strings?
Counts such as views and sessions are 64-bit integers, which some JSON parsers can't hold exactly, so they're sent as strings. Convert them with your language's number parser. Rates and averages, such as bounce_rate, are ordinary numbers.
Q: Can I send several events in one request?
No — each write call records one goal, payment, event or identity. Writes share the 60-requests-per-minute budget with reads; see Rate limits.
Q: Do filters work on every report?
They narrow the pages, referrers, countries, devices, browsers and operating-systems reports; the other reports don't apply them. Filters the API can't apply at all, such as region or city, return 400 unsupported_filter on every report.
Q: How do I get a visitor ID for server-side records?
In the browser, call window.admaxxer.getVisitorId() once the pixel has loaded, send the value to your server with the order or sign-up, and use it as visitor_id on the write call.
Q: Is the website list paginated?
GET /pixel/websites is — follow pagination.next_cursor while has_more is true. GET /pixel/analytics/metadata returns a single list of up to limit websites with no cursor.
Related guides
- Pixel API overview — Base URL, first request and response format.
- Authentication — API keys and the scope each endpoint needs.
- Rate limits — 60 requests per minute per workspace.
- Errors — Every error code these endpoints return.
- API keys guide — Step-by-step walkthrough of Settings › API Keys.
- Developer reference — The wider developer documentation for Admaxxer.