Authentication
API keys, what each scope unlocks, and limiting a key to certain projects.
Every request except /health needs an API key, sent as a bearer token:
Authorization: Bearer gim_live_...There is no other way in. No cookies, no session, no query-string key.
Getting a key
Product OS → Settings → API keys. Super Admin only, and only on Pro or legacy licences.
A key belongs to your company, not to the person who created it, so it keeps working after that person leaves. It also means the key can only ever see your company's data: the tenant is baked into the key when it is minted and is never read from anything you send us.
Keeping it safe
- We store only a SHA-256 hash. The raw key is shown once and cannot be recovered.
- Treat it like a password. Never commit it, never put it in front-end code, never email it.
- Revoking is instant and takes effect on the very next request.
- If a key leaks, revoke it and mint a new one. There is no way to rotate in place.
Scopes
A key carries an explicit list of scopes and can do nothing that is not on it. Nothing is granted by default: whoever creates the key ticks exactly what it needs.
| Scope | Unlocks |
|---|---|
projects:read | List projects, get one project |
locations:read | List locations, get one location |
tables:read | Read a table, for a project or a location |
map:read | Site boundaries, location groups, and marker styling on locations |
A request missing the right scope returns 403 insufficient_scope, naming
the scope it wanted.
/me needs no scope at all, so a key with nothing ticked can still confirm it
is valid.
Limiting a key to certain projects
A key can be restricted to named projects when you create it. This is a second, independent limit on top of the company boundary: the company decides whose data, the project list decides which of it.
A restricted key sees its allow-list as the whole world. /projects returns
only those projects, with no hint that others exist.
Note
A project outside the allow-list returns 404, not 403. That is deliberate. A 403 would confirm the project exists, which would let a restricted key probe for what else you hold. "Not yours" and "does not exist" are indistinguishable from outside.
This is the right tool for giving a client, a subcontractor or a one-off script access to a single job without handing over everything.
Choosing how many keys to have
One key per integration, not one per company. Separate keys for your Power BI
sync and your GIS script means you can revoke one without breaking the other,
and lastUsedAt tells you which is which.
What we log
Every authenticated request is recorded: which key, which project, the path, the method and the client IP. Records are kept for 400 days.
Key creation and revocation are also written to your organisation's audit log in Product OS, alongside every other org action.
This exists so that when your own client asks "who accessed our data, and when", you can answer it. Attempts are logged as well as successes, so a key probing for projects it cannot reach leaves a trail even though every one of those requests is refused.
We log the path, never the query string.
Expiry
Keys can be given an optional expiry when minted. An expired key returns 401 exactly like a revoked one.
Last updated 26 August 2026