# Pixel · server events Report conversions from your own backend, so the ones an ad blocker eats in the browser still reach Klozzo. Authenticate with your site's **secret key** as a Bearer token. It is shown once, when the site is created, and only its hash is stored — if it is lost it can be reissued, never recovered. > **Send the visitor's `anonymous_id` and everything changes.** The pixel > puts it into every form on your site as a hidden `kz_anonymous_id` field, > so your backend already receives it with the submission — store it with the > order and send it back here. Without it the event still lands, but as an > orphan: a purchase with no browsing behind it, no source, no session, > nothing to explain where the customer came from. This is the single most > common way a server-side integration ends up worth half of what it could be. ## Report events from a server `POST /api/v1/events` Reports events your own server knows about — a purchase, a refund, a renewal — up to 500 in one batch. Unlike the browser endpoint, a batch is **not** rejected as a whole: the valid events are accepted and the rest are reported back with the reason. A backend can act on a partial answer; a browser cannot, which is why the two behave differently. ### Body parameters - `anonymous_id` (string) — The visitor's id, from the hidden `kz_anonymous_id` field your form received. - `events` (object[], required) — The events to record. - `event_id` (string, required) — Your id for this event; the same value the browser used, if it also reported it. - `action_source` (string, required) — Always `server`. - `name` (string, required) - `anonymous_id` (string) — Must be a valid UUID. - `occurred_at` (string) — When it happened. Within 7 days past and 5 minutes future. - `url` (string) — The full URL where it happened. - `path` (string) — The path alone, if you would rather not send the query string. - `value` (number) — The amount, for monetary events. - `currency` (string) — ISO 4217. - `properties` (object) — Anything else about the event. - `traits` (object) — Identity fields (`email`, `phone`, `first_name`, `last_name`, `company`). ### Example request ```bash curl --request POST \ "https://klozzo.com/api/v1/events" \ --header "Authorization: Bearer {YOUR_API_TOKEN}" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data "{ \"anonymous_id\": \"0d5b6b6e-3e1f-4a5e-9a0a-6c4b0e4b1a2c\", \"events\": [ { \"event_id\": \"ord_10293\", \"action_source\": \"server\", \"name\": \"purchase\", \"anonymous_id\": \"6b72fe4a-5b40-307c-bc24-f79acf9a1bb9\", \"occurred_at\": \"2026-08-02T18:04:00-06:00\", \"url\": \"https:\\/\\/example.com\\/checkout\\/gracias\", \"path\": \"\\/checkout\\/gracias\", \"value\": 1899.5, \"currency\": \"MXN\", \"properties\": { \"order_id\": \"ORD-10293\" }, \"traits\": { \"email\": \"ana@tienda.test\" } } ] }" ``` ### Response `202` ```json { "received": 2, "rejected": 1, "errors": { "1": [ "`purchase` needs a `value`." ] } } ``` ### Response `401` — No key, or a key that does not exist ```json { "message": "A Bearer token with your site secret key is required." } ``` ### Response `422` — An empty batch ```json { "message": "Falta events.", "errors": { "events": [ "Falta events." ] } } ``` ### Response `422` — More than 500 events in one call ```json { "message": "Events no puede tener más de 500 elementos.", "errors": { "events": [ "Events no puede tener más de 500 elementos." ] } } ``` ### Response `429` — Over the site's budget ```json { "message": "Too Many Attempts." } ```