Authentication
Every request to the API carries an API key. Keys are created in the dashboard, shown exactly once, and can be limited to a single site or given a lifetime.
The header
All tokens begin with stbl_. A request with no token, a token that does not start with stbl_, or one that is expired or revoked is rejected with 401:
Create a key
- Open Settings → API.
- Select Create API key.
Fill in the dialog:
Field What it does Name A label, 1 to 100 characters. Name it after whatever will hold the key, so a leak is traceable to one machine. Site access All sites, or one specific site. Permissions What the key may do. See Permissions below. Expires in Never, 30d,60d,90dor1y.Copy the token from the Your API key dialog.
The token appears once, at creation. Statable stores only a hash of it, so it cannot be shown again or recovered by support. If you lose it, rotate the key or create another.
You can hold up to 10 active keys at a time.
Permissions
Three permissions are offered when the key is created, and like site access they are fixed at creation. A key cannot be granted more later.
| Permission | What it allows |
|---|---|
| Read analytics | View visitors, pageviews, traffic sources and the rest of the analytics. Always on: a key without it could not read anything |
| Manage sites | Create and update sites, goals, funnels and tracking settings |
| Manage API keys | Create, rotate and revoke other keys |
Everything in this documentation needs only Read analytics. Grant the other two when something you are building genuinely writes, and not before: Manage sites can permanently delete a site's data and make its analytics publicly readable, and Manage API keys lets the holder mint further keys.
A key that reaches for something outside its permissions is refused with 403 and the code insufficient_scope, naming the permission it lacked.
The keys table shows what each key holds, as Read, Sites and API keys badges.
All sites or one
Access is fixed when the key is created and cannot be changed afterward.
| Access | GET /sites returns | site_id on /query |
|---|---|---|
| All sites | Every site you can read | Required |
| One site | That site alone | Optional. If you send it, it must match, or the request is rejected with 403 |
A key never reaches further than its owner. If your own access to a site ends, the key stops reading it too.
Expiry
A key either expires on a date or never does. Once past its expiry it authenticates as though it had never existed, so calls answer 401 rather than a specific "expired" error.
Expired keys stay in the table with Expired in the Expires column. They no longer work, but they still occupy one of your 10 slots until you revoke them.
Rotate and revoke
Both live in the row menu on Settings → API.
Rotate issues a new token for the same key. The name, access and expiry survive, and Last used resets. The old token stops working the moment the new one appears, so rotate when a token may have leaked, or on a schedule if your policy calls for one. The new token is shown once, exactly like a new key.
Revoke ends the key immediately and removes it from the table, freeing a slot.
Keep the token secret
An stbl_ key is a credential, not an identifier. Anyone holding it can read every site the key covers, for as long as it lives.
- Keep it in an environment variable or a secret store, never in a repository.
- Never put it in browser JavaScript. The API sends no CORS headers, so it cannot be used from a page anyway, but a key pasted into front-end code is exposed to every visitor regardless.
- Give each machine or job its own key. One leak then costs one rotation, not a rebuild of every integration.
Reading the table
The list on Settings → API shows what each key is and whether it is still earning its slot:
| Column | Shows |
|---|---|
| Name | The label you gave it, with the token's stbl_ prefix |
| Access | All sites, or the one site it is locked to |
| Created | When it was issued |
| Last used | Time since the last request, or Never |
| Expires | A date, Never, or Expired |
Last used is the useful one. A key that still says Never long after you created it is either misconfigured or forgotten, and a forgotten key is the one you will not notice leaking.
Next steps
- Query reference: run your first query
- Rate limits: how many requests a key gets per hour
- Errors: telling
401apart from403and404
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.