Skip to content
Klozzo API
OpenAPI Postman

Public tracking

One endpoint, and it is not under /api. The browser beacon lives at POST /e on purpose: content blockers match by pattern, and the patterns they ship are the obvious words — track, collect, pixel, analytics. A one-character path on your own domain is not on anybody's filter list.

It is unauthenticated in the usual sense: what identifies the caller is the site's public write_key, which ships in your HTML, and what protects it is the domain allow-list you configure in the CRM. An origin that is not on that list is refused before the controller runs — fail closed, not fail open.

POST /e            the beacon the tracking script fires
OPTIONS /e         CORS preflight

You almost certainly do not want to call it by hand. The tracking script does it for you, batches the events, and carries the visitor's anonymous_id — which is the value that makes everything afterwards worth anything.

From your backend, not from a browser

For events your server knows about — a purchase, a refund, a subscription that renewed — use POST /api/v1/events instead. It is in the reference under Pixel · server events, and it authenticates with the site's secret key rather than the public write key.

Send the anonymous_id your form received in its hidden kz_anonymous_id field and the purchase joins up with the browsing that led to it. Without it the event still lands, but as an orphan: no source, no session, nothing to explain where the customer came from.

Rate limits

POST /api/v1/events is throttled by throttle:tracking — the budget is in the introduction, and every response carries X-RateLimit-Remaining. The browser beacon has its own per-site and per-visitor ceilings, configured in config/tracking.php.