The browser's way in: POST /px/e and GET /px.gif.
# router.ex
forward "/px", Pixelex.Plug.IngestOnly needed for what the server cannot see on its own — custom events from
a click, SPA navigation, screen size, scroll depth. Page views are already
counted by Pixelex.Plug with no JavaScript at all.
It answers the same way to everything
204 No Content for the POST, a 1×1 GIF for the pixel — whether the event
was recorded, dropped as a bot, refused for consent, rate-limited, or had a
name the site never allowed. A response that distinguishes those hands a
scanner the site's event catalogue and its consent posture for free.
Every outcome is still counted under [:pixelex, :pipeline, :drop], so the
silence is toward the caller, not toward the operator.
What bounds an unauthenticated endpoint
Not authentication — most of the clicks worth counting happen before anyone signs in. Four things, none of which is auth:
- the per-site event allowlist (
Pixelex.Sites) — the server decides what names exist - the consent gate, including
Sec-GPC - bot filtering
Pixelex.RateLimit, 120 events per minute per IP by default: far above a human, far below a script
GET /px.gif
For <noscript>, and for email. A GIF rather than 204 because a 204
response to an <img src> is not well-trodden ground across browsers,
which is the same conclusion Matomo reached. 43 bytes.
GET /px/pixelex.js
The tracker itself, from the host's own origin. 1.5KB gzipped.
The payload
Short keys, because this is on the wire on every event:
s site, n name, u url, r referrer, p props, t client time in ms.