Server-side collection
A server, a batch job or the backend of a mobile application can send its events directly, without a browser: it is the equivalent of Google Analytics’ Measurement Protocol. The most common case: the order confirmed by your server, once the payment is accepted.
POST https://stats.example.com/collect/serverAuthorization: Bearer eoas_…Content-Type: application/json
{ "events": [{ "type": "event", "name": "purchase", "at": "2026-10-04T14:12:00Z", "visitor": "3f9c0d2e8b7a4c1d9e0f1a2b3c4d5e6f.20260912", "props": { "transaction_id": "C-2026-10412", "value": 129.9, "currency": "EUR" }, "items": [{ "id": "KA2", "name": "Kerys Air 2", "price": 125, "quantity": 1 }] }]}The server key
Section titled “The server key”In the site’s Settings, Server keys section, create a key: eoas_….
- It is shown only once, then stored hashed.
- It is valid only for its site, and only for sending: it reads nothing.
- It can be revoked in one click; its last use is displayed, and its creation and revocation are recorded in the audit log.
Keep it on the server side, in your application’s configuration.
The payload
Section titled “The payload”A request carries up to 100 events. Each event:
| Field | Required | Role |
|---|---|---|
type | yes | pageview or event |
name | for event | the event name, same rules as track |
at | no | the time, in ISO 8601 format; at most 72 hours in the past; now by default |
url, referrer, title | no | the page concerned |
props, items | no | the properties and the items, as in the browser |
visitor | no | the value of the visitor’s _eoa cookie |
user_id | no | the visitor’s identity on your side (if the site accepts signed-in visitors) |
ip, user_agent | no | the visitor’s address and browser, for the daily hash |
language | no | the visitor’s language |
Omit a missing field: do not send null. There is no origin check and no bot filter: the key is
enough. The rate limit is specific to the key.
Attaching the event to the visit
Section titled “Attaching the event to the visit”For the order to land in the right visit, and be attributed to the right channel, the server relays what it knows about the visitor:
- in measurement cookie mode: the value of the
_eoacookie, which the browser sends with every request to your site; - otherwise: the visitor’s IP address and user agent, which give the same daily hash as the script. They are discarded immediately, as everywhere else.
With neither, the event is stored without a visitor (visitor_kind = none).
Node.js
Section titled “Node.js”await fetch('https://stats.example.com/collect/server', { method: 'POST', headers: { Authorization: `Bearer ${process.env.EODIA_SERVER_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ events: [{ type: 'event', name: 'purchase', visitor: req.cookies._eoa, // cookie mode ip: req.ip, user_agent: req.get('user-agent'), props: { transaction_id: order.id, value: order.total, currency: 'EUR' }, }], }),})<?php$event = [ 'type' => 'event', 'name' => 'purchase', 'ip' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'props' => ['transaction_id' => $order->id, 'value' => $order->total, 'currency' => 'EUR'],];if (isset($_COOKIE['_eoa'])) $event['visitor'] = $_COOKIE['_eoa']; // cookie mode$body = json_encode(['events' => [$event]]);$ch = curl_init('https://stats.example.com/collect/server');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('EODIA_SERVER_KEY'), 'Content-Type: application/json'], CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,]);curl_exec($ch);Python
Section titled “Python”import os, requests
event = { "type": "event", "name": "purchase", "ip": request.remote_addr, "user_agent": request.headers.get("User-Agent", ""), "props": {"transaction_id": order.id, "value": order.total, "currency": "EUR"},}if "_eoa" in request.cookies: # cookie mode event["visitor"] = request.cookies["_eoa"]
requests.post( "https://stats.example.com/collect/server", headers={"Authorization": f"Bearer {os.environ['EODIA_SERVER_KEY']}"}, json={"events": [event]}, timeout=5,)curl -X POST https://stats.example.com/collect/server \ -H "Authorization: Bearer $EODIA_SERVER_KEY" \ -H "Content-Type: application/json" \ -d '{"events":[{"type":"event","name":"invoice_paid","props":{"value":49,"currency":"EUR"}}]}'Erasing a person’s data
Section titled “Erasing a person’s data”The same key can request the erasure of a person’s data, so you can connect the requests your site receives:
curl -X POST https://stats.example.com/collect/server/erase \ -H "Authorization: Bearer $EODIA_SERVER_KEY" \ -H "Content-Type: application/json" \ -d '{"user_id":"client-1042"}'One of the two: user_id or visitor (the cookie value). See
data subject rights.
eodia analytics is free software by Eodia.