Skip to content

Events API

Send pageviews and custom events from your server, for visits the browser script can't see.

Updated 14 October 20264 min read

The Events API records what happens on your server: a sign-up confirmed by email, an API call from your app, a page served to a browser that blocks scripts. Events go through the same filters, sessions and attribution as the tracker's, so they show up in the same dashboard. It needs a key with the Send events permission (events:write); see API keys.

For payments, use the Payments API instead: it keeps refunds, renewals and duplicates in order, and refuses revenue sent as an event.

Send an event

POST https://api.traffic.cx/v1/events

bash

curl -X POST https://api.traffic.cx/v1/events \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "site": "tcx_yoursite",
    "name": "signup",
    "url": "https://example.com/welcome",
    "props": { "plan": "pro" },
    "visitor_ip": "203.0.113.7",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) …"
  }'

json

{ "result": "accepted" }
FieldRequiredMeaning
siteyesThe site's ID (tcx_…)
urlyesThe full address of the page the event belongs to
visitor_ipyesThe visitor's IP address, from your web server or proxy
user_agentyesThe visitor's User-Agent header
namenopageview (default) or your event's name, up to 120 characters
referrernoWhere the visitor came from, for a pageview
propsnoCustom properties: up to 30 keys, with text, number or true/false values
pageview_idnoTies a custom event to the pageview it happened on (16 hex characters)
tcx_vidnoThe tcx_vid cookie, for sites in cookie mode

The visitor's address and browser are what tell visitors apart. traffic.cx uses them the same way as for the tracker: the address is never stored, and in cookieless mode it only feeds a daily-rotating hash. Send the real visitor's values, not your server's, or every event looks like one visitor.

Results

Every event answers with what became of it. The request itself answers 202.

resultMeaning
acceptedRecorded
dropped:bot_ua, dropped:bot_datacenterFiltered as a bot, by its browser or its network
dropped:hostnameThe URL's hostname isn't this site's domain or an allowed hostname
dropped:spam_referrerThe referrer is a known spam domain
dropped:excludedThe address or path is excluded in the site's settings
dropped:duplicateThe same event arrived twice
dropped:rate_limitedToo many events from this visitor in the last minute
dropped:site_inactive, dropped:cap_reachedThe site isn't collecting: no plan, or the plan's limit is reached
invalid:…The event couldn't be read
error:unavailableCollection didn't answer; retry later

A pageview's answer also has its pageview_id. Send it with later events, and with payments, to tie them to that visit.

Several events at once

Send { "events": [ … ] } with up to 25 events. The answer is { "results": [ … ] }, one result per event, in the same order. Every event is checked first, so one with a missing field sends none and answers 400 with its place, such as events[3].visitor_ip.

Verify and troubleshoot

  1. Send a pageview with your own address and browser.
  2. Check that the answer is accepted, and that the visit appears in Realtime within a few seconds.
  3. Send a custom event with that pageview_id, and find it under Goals & events.

dropped:hostname usually means the url uses a different domain from the site's; add it to the site's allowed hostnames. dropped:bot_datacenter means visitor_ip belongs to a cloud network: check that you are sending the visitor's address, not your server's.

The routes, checks and forwarding to collection are covered by local tests. No request in this guide has been sent to a real customer account as part of publication.