Skip to content

Collector HTTP API ​

The SDKs are the supported way to send events, and they handle queueing, retries and deduplication for you. This page is for everything else: a desktop app, a server, a platform there is no SDK for yet, or checking by hand that a write key works.

POST /v1/collect ​

POST https://analyticstrend.com/v1/collect
Content-Type: application/json

Any origin may call it from a browser; the write key is the only credential, and it can only write.

bash
curl https://analyticstrend.com/v1/collect \
  -H "content-type: application/json" \
  -d '{
    "writeKey": "wk_your_key_here",
    "client": "web",
    "clientVersion": "my-app-1.0.0",
    "anonymousId": "5f0c6c0e-7f7e-4a51-9d0b-1f9f3c1b2a77",
    "events": [
      { "id": "0b6f4c2e-1", "name": "settings_opened", "ts": "2026-09-28T14:03:11.000Z", "props": { "tab": "privacy" } }
    ]
  }'

The batch ​

FieldRequiredWhat it is
writeKeyyesThe project's write key.
clientyes"web" or "extension".
clientVersionyesWhat is sending: your own version string is fine. Up to 64 characters.
appVersionnoThe version of the product being measured. Up to 64 characters.
anonymousIdyesOne random identifier per install or browser, up to 64 characters.
eventsyes1 to 100 events.

anonymousId is how AnalyticsTrend counts people, so generate it once, randomly, store it, and send the same one every time. Never use an email address, an account id or anything else that identifies a person: it would make your data personal data, and it can be joined with other data in a way a random value cannot.

Each event ​

FieldRequiredWhat it is
nameyesMatches ^[a-z0-9_]{1,64}$. See naming.
tsyesWhen it happened, as an ISO 8601 timestamp, within 7 days of now.
idnoA unique id for this event, up to 64 characters. Send the same id when you retry.
propsnoAn object of your own properties, up to 2048 bytes as JSON.

Delivery over a network is at-least-once: a request can succeed and its answer still be lost. With an id, the collector stores the event once however many times it arrives, so always send one and keep it the same across retries.

Keys starting with $ are reserved for what the SDKs capture themselves. Only the documented ones, such as $path and $referrer, are accepted; any other $ key rejects the event.

Responses ​

StatusMeaningRetry?
202Accepted. The body says what was kept and what was not.No
400The batch itself is malformed: no write key, a bad client, no events or more than 100.No
401Unknown write key: wrong, or rotated.No
408, 429, 5xxTry again later, with the same event ids.Yes

A 202 is not proof every event was kept. One bad event does not reject the batch:

json
{
  "accepted": 1,
  "rejectedNames": ["event_number_201"],
  "invalidEvents": [{ "index": 2, "error": "event ts must be an ISO timestamp for event opened" }]
}
  • accepted counts the events stored by this request. A retried duplicate is not counted again.
  • rejectedNames are names refused because the project already has 200 distinct ones.
  • invalidEvents are events that failed validation, by their position in events.
  • filtered: "bot" means the request came from a crawler or a headless browser, and nothing in it was stored. A request from an HTTP library such as curl or Node is never treated as a bot, since sending from a server is supported; it just records no browser or device.
  • filtered: "origin" means the project lists who may send it events, and this request's Origin is not on the list, or it had none. Nothing in it was stored. See Limit which sites can send events.

GET /v1/uninstall ​

Used by the extension SDK as the page a browser opens when an extension is removed, with k set to the write key and u to the anonymous id. It always answers 204, whatever it is given, so it cannot be used to test which keys exist.

What the collector works out from each request ​

Besides the batch, the collector reads three things from a request, keeps only what it works out from them, and discards the rest:

  • The IP address, for a country, and in 21 countries a region: a state, province or territory from a fixed list, never a town. The address itself is not stored.
  • The User-Agent and Sec-CH-UA headers, for a browser family, an operating system family and a device type, never a version. The headers themselves are not stored.
  • The Accept-Language header, for the browser's primary language, such as pt from pt-BR,pt;q=0.9, from a fixed list of codes. The header itself is not stored.

Nothing else about the request is kept. The request log records its method and route only. The full list of what is collected is in What it collects.

Limits ​

Every limit the collector enforces is on the limits page.

Data hosted in Canada. No cookies, no fingerprinting, no personal data. IP Geolocation by DB-IP.