Ingest API
The Ingest API accepts one event at a time over HTTPS. It's intentionally minimal so any platform with an HTTP client can publish events — including backends, IoT devices, mobile apps, and the web tracker itself.
Endpoint
POST https://tracera.eu/i
Content-Type: application/json
For first-party setups, replace the host with your reverse-proxy origin. The path must remain /i.
Authentication
The body's p field carries a public property key (pk_…). That key is safe to embed in client code and only authorises writes to its one property. No Authorization header is required.
Request body
{
"p": "pk_a3f09c2e71bd", // required — public property key
"t": "pageview", // required — "pageview" | "event" | "screen"
"u": "https://app.example.com/dashboard?id=42", // page URL (PII stripped server-side)
"r": "https://app.example.com/", // referrer (optional)
"n": "signup_completed", // event name (required when t=event)
"d": { "plan": "pro", "value": 49 }, // custom properties (optional)
"w": 1920, // viewport width (optional, rounded)
"h": 1080, // viewport height (optional, rounded)
"ts": 1730000000 // client timestamp in seconds (optional)
}
Server enrichment
Tracera adds these on the server side; you don't (and shouldn't) send them:
- server_ts — authoritative event time.
- country, region — resolved from an offline IP-to-geo database on the incoming IP, then the IP is discarded.
- device_type, browser, os — parsed from User-Agent. No fingerprinting hash.
- visitor_id —
sha256(daily_salt || domain || ip || ua), truncated to a 64-bit integer. - session_id — derived from
(visitor_id, 30-min inactivity).
Response
| Status | Body | Meaning |
|---|---|---|
| 204 | (empty) | Accepted & queued for processing. |
| 400 | {"error":"invalid_body"} | Body wasn't valid JSON or missed required fields. |
| 401 | {"error":"unknown_pk"} | Public key not recognised, revoked, or wrong tenant. |
| 403 | {"error":"origin_not_allowed"} | Origin header isn't in the property's allowed domains. |
| 413 | {"error":"too_large"} | Body exceeded the maximum size. |
| 429 | {"error":"rate_limited"} | You hit the per-IP-per-property rate cap (limits subject to change). |
curl example
curl -X POST https://tracera.eu/i \
-H 'Content-Type: application/json' \
-d '{
"p": "pk_a3f09c2e71bd",
"t": "event",
"n": "ci_build_finished",
"d": { "duration_s": 142, "status": "ok" }
}'
Reliability
The ingest layer is decoupled from the dashboard so dashboard downtime does not cause data loss.