Documentation menu

The read API

Query your analytics from your own code: authentication, endpoints, and the range parameters.

Authentication

The read surface lives under https://api.getopen.so/v1/read/ and takes a Bearer credential of either kind:

  • A read key, created per site in Settings, API. Shown once; treat it like a secret.
  • An OAuth token, which is how the CLI and MCP clients sign in. Tokens are scoped and revocable from Account, Connected apps.

Site-scoped calls name the site in an x-oa-site header. Leave the header off for calls that are not about one site; an empty value is refused rather than guessed.

A first request

terminal
curl "https://api.getopen.so/v1/read/analytics/overview?from=2026-08-01T00:00:00.000Z&to=2026-08-08T00:00:00.000Z&timezone=Europe/Istanbul" \
  -H "authorization: Bearer YOUR_READ_KEY" \
  -H "x-oa-site: YOUR_SITE_ID"
Ranges are full ISO-8601 UTC instants; date-only strings are a 400. timezone is an IANA name and decides how days are bucketed. Optional: compare=true for the preceding period, resolution (hour, day; the timeseries adds week) to pick the grain explicitly.

Endpoints

PathAnswers
GET /v1/read/sitesThe sites this credential can see: id, slug, name, status, role.
GET /v1/read/siteThe selected site's metadata, including its tracking key and script URL for installs.
GET /v1/read/analytics/overviewTotals for the range: events, pageviews, visitors.
GET /v1/read/analytics/timeseriesThe chart's series, at an honest grain; weekly uniques merged server-side.
GET /v1/read/analytics/pagesTop pages.
GET /v1/read/analytics/sourcesReferrers and campaigns.
GET /v1/read/analytics/geographyCountries and cities.
GET /v1/read/analytics/devicesDevice types, browsers, operating systems.
GET /v1/read/analytics/sessionsBounce rate and visit duration.
GET /v1/read/revenue/…Revenue aggregates (summary, timeseries), for the site owner.
POST /v1/read/realtime/tokenA short-lived token for the realtime stream (OAuth credentials only).

Errors and limits

  • Errors arrive as {"error":{"code","message"}} with the obvious statuses; a 429 carries Retry-After.
  • Reads are rate- and cost-limited per credential, generously for dashboards and scripts, visibly for runaway loops.
  • The realtime stream takes its token in the Authorization header; token-shaped query parameters are rejected by design.