Server-side events
POST https://api.snowanalytics.app/api/v1/eventsSend custom events from your server, a backend job, a webhook handler, or an AI agent. Anywhere there’s no browser. Authenticated with a server API key.
Authentication
Authorization: Bearer snw_live_your_keyCreate a server API key (scope events:write) in the dashboard under
API keys.
Request body
Only the event name is required. Most fields accept either snake_case or
camelCase.
| Field | Type | Notes |
|---|---|---|
name / event_name | string | Required. Up to 128 chars. |
value / event_value | number | string | Optional event value. |
properties / metadata / event_properties | object | Custom properties. |
visitor_id / visitorId | string | Optional. Link to a known visitor (≤ 64 chars). |
session_id / sessionId | string | Optional (≤ 64 chars). |
user_id / userId | string | Optional (≤ 256 chars). If this user was already identified from the browser, the event links to their visitor. |
external_id / externalId | string | Optional (≤ 256 chars). Stored as an event property only; does not attribute the event to a visitor. |
idempotency_key / idempotencyKey | string | Optional. Safe-retry key (see below). |
timestamp | string | number | ISO 8601 string or Unix milliseconds. Defaults to now. |
context | object | url, pathname, hostname, referrer, ip, user_agent, device_type, platform. |
url / pathname / hostname / referrer | string | Top-level shortcuts for the same context fields. |
If you don’t pass a visitor_id, the event is recorded anonymously. Country, city,
browser, and device are derived from the context.ip / context.user_agent you
supply (or the request itself).
To attribute a server event to a person, pass a visitor_id, or a user_id that
was already identified from the browser via identify. Note that
external_id does not link the event to a visitor: it is stored as an event
property only.
Idempotency
Pass an idempotency_key to make retries safe. If Snow has already seen that key
for your site in the last 24 hours, the duplicate is ignored. Keys match
^[A-Za-z0-9_.:-]{1,128}$.
Example
curl -X POST https://api.snowanalytics.app/api/v1/events \
-H "Authorization: Bearer snw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "subscription_created",
"value": 49,
"user_id": "user_12345",
"properties": { "plan": "pro" },
"idempotency_key": "evt_9f8c7b6a"
}'Responses
| Status | Body | Meaning |
|---|---|---|
202 Accepted | { "status": "success", "data": { "accepted": true } } | Event queued. |
200 OK | { "status": "success", "data": { "accepted": false, "duplicate": true } } | Idempotency key already seen, ignored. |
400 Bad Request | { "status": "error", "error": { "code": 400, "message": … } } | Invalid event name, idempotency key, or properties. |
401 Unauthorized | { "status": "error", "error": { … } } | Missing or invalid API key. |
403 Forbidden | { "status": "error", "error": { "code": 403, "message": "API key does not have events:write scope" } } | The key is valid but lacks the events:write scope. |
429 Too Many Requests | (no body) | Rate limit exceeded. |