Authentication

One mechanism: a bearer key in the Authorization header. There is no second way in.

The header

http
Authorization: Bearer fg_live_8Kq2vR7pLm...

The scheme is matched case-insensitively; everything after the first space is the key. Nothing else is read — not a query parameter, not a custom header, not a cookie.

A browser session is not a key
If you are signed in to FixGrid in the same browser, /api/v1 still answers 401. The session cookie authenticates the application, never this namespace. There is also no CORS header on these responses, so the API is not callable from a page in a browser — call it from your server.

Scopes

A key carries exactly one scope, chosen when it is created. Scope is derived from the key alone — never from who is signed in, never from a parameter.

ScopeStateWhat it opens
readliveEvery list and fetch on this host: tickets, properties, units, assets, vendors, inspections, turns, meters and a meter's readings. It also reads the webhook subscription list, which takes any active key.
writeliveAlso satisfies read and webhook_only. Opens POST /tickets, PATCH /tickets/{ticket_id}, POST /units/{unit_id}/notice and POST /units/{unit_id}/move-in.
webhook_onlyliveManages webhook subscriptions over the API and nothing else: create, list, delete. It opens no object route. Pausing, resuming and rotating a signing secret stay on the Integrations page.
Ask for the narrowest scope that works
Most integrations only ever read. Asking an administrator for write when you read is a question you will be asked to justify, probably in a security review.

When it fails

Every failure on this namespace answers in one shape, with a sentence that names the cause and the remedy:

401 · no key, a malformed header, or a revoked key
json
{
        "error": {
          "code": "unauthorized",
          "message": "Send a valid API key as `Authorization: Bearer <key>`; create one on the Integrations page."
        }
      }

A 401 also carries WWW-Authenticate: Bearer.

403 · the key is valid but not allowed
json
{
        "error": {
          "code": "insufficient_scope",
          "message": "This key's scope does not allow that. Create a key with the write scope on the Integrations page."
        }
      }

There are two 401 codes and two 403 codes; Errors lists all nineteen and what each one means.

Transport
https only
Send the key in the header, over TLS. Never in a URL.
Caching
no-store
Every response on the namespace. Do not cache to disk.
Browsers
No CORS
Server-to-server by design. A key in front-end code is a leaked key.