Appearance
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/jsonAny 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
| Field | Required | What it is |
|---|---|---|
writeKey | yes | The project's write key. |
client | yes | "web" or "extension". |
clientVersion | yes | What is sending: your own version string is fine. Up to 64 characters. |
appVersion | no | The version of the product being measured. Up to 64 characters. |
anonymousId | yes | One random identifier per install or browser, up to 64 characters. |
events | yes | 1 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
| Field | Required | What it is |
|---|---|---|
name | yes | Matches ^[a-z0-9_]{1,64}$. See naming. |
ts | yes | When it happened, as an ISO 8601 timestamp, within 7 days of now. |
id | no | A unique id for this event, up to 64 characters. Send the same id when you retry. |
props | no | An 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
| Status | Meaning | Retry? |
|---|---|---|
202 | Accepted. The body says what was kept and what was not. | No |
400 | The batch itself is malformed: no write key, a bad client, no events or more than 100. | No |
401 | Unknown write key: wrong, or rotated. | No |
408, 429, 5xx | Try 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" }]
}acceptedcounts the events stored by this request. A retried duplicate is not counted again.rejectedNamesare names refused because the project already has 200 distinct ones.invalidEventsare events that failed validation, by their position inevents.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'sOriginis 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-AgentandSec-CH-UAheaders, for a browser family, an operating system family and a device type, never a version. The headers themselves are not stored. - The
Accept-Languageheader, for the browser's primary language, such asptfrompt-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.