Skip to content
APIs / Events API

APIs

Events API

Send pageviews and custom events from your server, mobile app or anywhere else over HTTP.

The tracking script uses this same API. You can call it directly to record events from places the script can't run — a back end, a mobile app, a CLI or an email-open pixel service.

Endpoint

POST https://plainwebanalytics.com/api/event
Content-Type: application/json
User-Agent: <the visitor's user-agent>
X-Forwarded-For: <the visitor's IP address>

No API key is needed: events are matched to a site by its domain. text/plain and application/json bodies are both accepted, and CORS is open to all origins.

Headers matter. PlainAnalytics counts unique visitors from the IP address and user-agent (see the data policy). When calling from a server, forward the original visitor's User-Agent and put their IP address first in X-Forwarded-For; otherwise every event will look like it came from your server. Requests with an empty user-agent, or a user-agent that looks like a bot, are dropped.

Body

Field Required Description
name yes Event name, up to 120 characters. Use pageview for pageviews.
url yes Absolute URL of the page the event happened on, up to 2,000 characters.
domain yes The site's domain as configured in PlainAnalytics. A comma-separated list records the event for several sites.
referrer no The referring URL.
props no Up to 30 custom properties; scalar values only.
revenue no { "amount": 49.99, "currency": "GBP" } for revenue goals.
interactive no false for events that shouldn't affect bounce rate. Default true.

The short keys used by the script (n, u, d, r, p, $, i) are accepted too.

Example

curl -i -X POST https://plainwebanalytics.com/api/event \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0 Safari/537.36' \
  -H 'X-Forwarded-For: 203.0.113.7' \
  -H 'Content-Type: application/json' \
  --data '{"name":"Signup","url":"https://example.com/register","domain":"example.com","props":{"plan":"pro"}}'

Responses

Status Meaning
202 ok Accepted. Events that are deliberately dropped (bots, unknown domains, shields) also return 202, so the API can't be used to probe your settings.
400 Validation failed. The body is {"errors": {"field": ["message"]}}.
413 Body larger than 64 KB.

Debugging

Add the header X-Debug-Request: true and the response includes, for each domain, whether the event was accepted or dropped and the reason — for example an unknown domain, a bot user-agent or a shield rule.

Something unclear or missing? Tell us.