Skip to main content

POST /api/event

Ingests a single analytics event. The server assigns a UUID and a UTC timestamp before persisting the record. Any string property values longer than 200 characters are silently truncated to 200 characters followed by ....
The Iris SDK sends events using navigator.sendBeacon when available (fire-and-forget, survives page unloads). It falls back to fetch with keepalive: true. You can call this endpoint directly if you need server-side or non-browser tracking.

Request body

The body must be a JSON object matching the EventPayload shape. Keys are intentionally short to minimise wire size.
n
string
required
Event name. Built-in events use a $ prefix (e.g. $pageview, $click, $web_vital). Custom events can be any string.
u
string
required
Full URL of the page where the event occurred (e.g. https://example.com/pricing).
d
string
required
Domain (hostname) the event belongs to (e.g. example.com). This is the primary multi-tenancy axis for all read queries.
r
string | null
Referrer URL, or null if there is none. Used by /api/referrers.
w
number
required
Visitor’s viewport width in pixels (window.innerWidth). Used by /api/devices to bucket into Mobile / Tablet / Desktop.
s
string
required
Site ID configured in IrisConfig.siteId. Stored for future multi-site use.
sid
string
required
Session ID — a UUID stored in sessionStorage (iris_sid). Unique per browser tab; cleared when the tab closes.
vid
string
required
Visitor ID — a UUID stored in localStorage (iris_vid). Persists across sessions on the same browser. No cookies are used.
p
object
Optional map of custom properties (Record<string, any>). String values longer than 200 characters are truncated server-side. Used to carry web vital metrics ($name, $val, $rating) and autocapture click metadata ($tag, $id, $class, $text, $href).

Server-assigned fields

The following fields are never sent by the client — the server generates them:
FieldTypeValue
idstringUUID v4 generated via google/uuid
tsstringUTC timestamp at time of ingestion (time.Now().UTC())

Response

Returns 202 Accepted with an empty body on success.
StatusMeaning
202 AcceptedEvent saved successfully
400 Bad RequestRequest body is not valid JSON
500 Internal Server ErrorDatabase write failed

EventPayload JSON shape

{
  "n":   "$pageview",
  "u":   "https://example.com/pricing",
  "d":   "example.com",
  "r":   "https://google.com",
  "w":   1440,
  "s":   "my-site",
  "sid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "vid": "f0e1d2c3-b4a5-6789-0123-456789abcdef",
  "p": {
    "plan": "pro",
    "experiment": "cta-v2"
  }
}

Examples

curl -X POST https://your-iris-host/api/event \
  -H "Content-Type: application/json" \
  -d '{
    "n":   "$pageview",
    "u":   "https://example.com/pricing",
    "d":   "example.com",
    "r":   "https://google.com",
    "w":   1440,
    "s":   "my-site",
    "sid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "vid": "f0e1d2c3-b4a5-6789-0123-456789abcdef"
  }'

POST /api/events

Ingests a batch of events in a single request. Accepts an array of EventPayload objects. The server assigns a UUID and the same UTC timestamp to every event in the batch before persisting them in a single transaction.
Batches larger than 50 events are rejected with 413 Request Entity Too Large. Split larger batches into multiple requests.

Request body

An array of EventPayload objects. Each object has the same fields as the single-event endpoint above.
[
  {
    "n": "$pageview",
    "u": "https://example.com/",
    "d": "example.com",
    "r": null,
    "w": 390,
    "s": "my-site",
    "sid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "vid": "f0e1d2c3-b4a5-6789-0123-456789abcdef"
  },
  {
    "n": "signup",
    "u": "https://example.com/register",
    "d": "example.com",
    "r": null,
    "w": 390,
    "s": "my-site",
    "sid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "vid": "f0e1d2c3-b4a5-6789-0123-456789abcdef",
    "p": { "plan": "pro" }
  }
]

Response

Returns 202 Accepted with an empty body on success.
StatusMeaning
202 AcceptedAll events saved (or array was empty)
400 Bad RequestRequest body is not valid JSON
413 Request Entity Too LargeBatch exceeds 50 events
500 Internal Server ErrorDatabase write failed

Examples

curl -X POST https://your-iris-host/api/events \
  -H "Content-Type: application/json" \
  -d '[{"n":"$pageview","u":"https://example.com/","d":"example.com","r":null,"w":1440,"s":"my-site","sid":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","vid":"f0e1d2c3-b4a5-6789-0123-456789abcdef"}]'
The Iris SDK has built-in batching support. Pass a batching config to new Iris({...}) to queue events and flush them automatically via this endpoint instead of /api/event.

Build docs developers (and LLMs) love