Web analytics without the script

POST /api/collect: the endpoint the analytics snippet reports to, for frameworks and servers that send events themselves.

Embed
Preview of the card
<a href="https://seolyticize.com/docs/collect-api"><img src="https://seolyticize.com/docs/_api/public/orgs/71cb2b7a-a719-4003-b3ea-6321dc1db8ab/spaces/3bf2dbf7-3faa-473c-ba3b-30588f5f8de4/pages/90a4b9d3-6182-4514-94e4-051b18b3b41d/social-card.svg?v=3e7ae33eec8b" alt="Web analytics without the script" width="600" height="315"></a>

The analytics snippet (<script defer data-site="KEY" src="https://seolyticize.com/a.js">) is the easy way in. Under it is one endpoint, which a framework, an edge function or a server can call directly.

The request

curl -X POST https://seolyticize.com/api/collect \
  -H "Content-Type: text/plain" \
  -d '{"k":"<site key>","n":"pageview","u":"https://example.com/pricing","r":"https://www.google.com/"}'

Field

k

required

The site key, from set_up_web_analytics or get_web_analytics_setup (16–64 characters).

n

required

"pageview", or a custom event's name (up to 64 characters).

u

required

The page's full URL, http or https, up to 2,048 characters. Its hostname must be one of the setup's hostnames.

r

optional

The referrer, on a visit's first pageview only. Send an origin (https://www.google.com/); nothing else of it is used.

p

optional

A custom event's properties: up to 10, keys up to 40 characters, string, number or boolean values (strings up to 200).

The body is JSON, at most 4 KB. Send it as text/plain from a browser so no CORS preflight is needed; application/json works from a server. Every accepted event answers 202 with no body.

What is kept

  • The path only. The query string and fragment are dropped, after the utm_* tags are read out of it. Send the URL without other parameters anyway: a reset token or an OAuth code should not travel at all.

  • The referrer's domain, as the visit's source.

  • No cookies, no stored identifier: a visitor is a hash of the site key, the address and the user agent with a salt that changes daily. The address is never stored.

  • Paths the setup excludes are dropped on arrival: set_up_web_analytics {clientId, excludePaths: ["/app/*", "/verify", "/reset"]}, or includePaths to record only those.

From a server

The visitor hash uses the address the request comes from. Sent from your own server, every event shares the server's address and counts as one visitor, so pass each visitor's real address the way your platform's proxy does, or send events from the browser. Requests from bots are accepted and quietly dropped; one visitor sending too fast is answered 429.

Answers

Status

Meaning

202

Accepted (or quietly dropped as a bot or an excluded path)

400

Not JSON, or a field out of bounds

403

The page's hostname, or the request's Origin, is not one of the setup's hostnames

404

No setup has that site key

413

Body over 4 KB

429

Too many from one visitor

Updated