Skip to content

Stats API

Read your analytics over HTTP. The same numbers the dashboard draws, as JSON, for a scheduled job, a warehouse load, or a report you assemble yourself.

Everything documented here is read-only. Queries return counts and rates; nothing you send changes your data or your settings. The API does have a write surface, for managing sites and keys, and it needs permissions this documentation's endpoints never ask for. The OpenAPI spec is the reference for it.

Base URL

https://statable.com/api/v1

Every path below is relative to it. Requests and responses are JSON.

Authentication

Each request carries a bearer key, created in the dashboard under Settings → API:

Authorization: Bearer stbl_<secret>

A request without a valid key is rejected with 401. See Authentication for creating keys, choosing their permissions, limiting one to a single site, and expiry.

Server-side only

An stbl_ key is a secret. Anyone holding it can read every site the key covers, so it belongs on a server, in a scheduled job, or in a local script, never in browser JavaScript where every visitor can read it.

The API enforces this: /api/v1 sends no CORS headers, so a cross-origin browser request cannot read the response. There is no browser-based flow in v1.

Endpoints

MethodPathReturns
GET/sitesThe sites this key can read
POST/queryOne analytics query: totals, a time series, or a breakdown
GET/current-visitorsVisitors active in the last five minutes
GET/propsCustom property keys a site has recorded
GET/funnelsSaved funnels for a site
POST/funnels/{id}/reportOne saved funnel, step by step
GET/subscriptionThe account's plan state, in one line

POST /query carries most of the surface. Metrics, dimensions, filters and date ranges all live there, and the other endpoints are narrower reads around it. Full grammar: Query reference.

First request

Start by discovering what the key can see:

curl -s https://statable.com/api/v1/sites \
  -H "Authorization: Bearer stbl_YOUR_KEY"
{
  "sites": [
    {
      "site_id": 3093477,
      "name": "https://example.com/",
      "timezone": "Europe/Amsterdam",
      "stats_start_date": "2026-04-07",
      "created_at": "2026-02-21T12:52:54Z"
    }
  ]
}

Take site_id from there and ask a question:

curl -s -X POST https://statable.com/api/v1/query \
  -H "Authorization: Bearer stbl_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "site_id": 3093477,
        "metrics": ["visitors", "pageviews"],
        "date_range": "7d"
      }'
{
  "results": [
    { "metrics": { "visitors": 2491, "pageviews": 3506 } }
  ]
}

Dates and time buckets follow the site's own timezone, the one reported by /sites and set under Site settings → General.

Machine-readable spec

An OpenAPI 3.1 description of the API is served at:

https://statable.com/api/v1/openapi.yaml

It needs no key. Import it into Postman or Insomnia by URL, feed it to a client generator, or open it in an editor. Where prose and spec disagree, the spec is the contract.

Not in v1

Named so the boundaries are unambiguous:

  • One site per query. No cross-site aggregation.
  • One dimension per query at most.
  • No bulk export. There is no CSV or archive download.
  • Saved funnels only. POST /funnels/{id}/report runs a funnel that already exists; it takes an id, not a definition.
  • No cursor pagination. Breakdowns page with limit and offset.

Next steps


Ready to take control of your web analytics? Try Statable free for 30 days. No credit card required, full feature access, built for GDPR. Start your free trial or view a live demo.