API keys and authentication
One mechanism: an API key sent as a bearer token. A key belongs to your organisation, does only what its scopes allow, and can be revoked in one click. There is no OAuth dance and nothing to refresh.
Sending the key
Put the key in the Authorization header of every request. Keys look like fh_live_ followed by 43 characters.
curl https://fullhall.au/api/v1/contacts \ -H "Authorization: Bearer fh_live_..."
Keys never go in a URL, and the API sends no CORS headers on purpose: a key is a server-side secret, like a database password, and must not ship in a browser or a mobile app. Call the API from your backend, a scheduled job, or a tool that runs server-side.
Creating and revoking keys
Admins manage keys in the dashboard under Settings, then Developer. Creating a key means naming it for what it does ("Website sync"), picking its access, and choosing an expiry (90 days is the default; "never" is available). The key shows once, at creation. After that the dashboard shows only its last four characters, when it was last used, and from roughly where.
Revoking takes effect immediately. To rotate a key, create its replacement first, move your integration over, then revoke the old one; both work during the changeover. A key also stops working if the admin who created it loses admin access, so an integration outlives staff only if an active admin recreates its key.
Scopes
A key holds one or more scopes, named resource:action. Write includes read. Grant only what the integration uses.
| Scope | Allows |
|---|---|
| contacts:read | List and view contacts and labels. |
| contacts:write | Create, edit, and delete contacts and labels. |
| groups:read | List groups and their members. |
| groups:write | Create and edit groups, and change their members. |
| files:read | List files and fetch download links. |
| files:write | Upload and delete files. |
When authentication fails
A missing, malformed, revoked, or expired key gets a 401 with code: "unauthorized". A valid key without the scope an endpoint needs gets a 403 with code: "forbidden" naming the missing scope. Errors follow RFC 9457:
{
"type": "https://fullhall.au/docs/api/errors#forbidden",
"title": "Forbidden",
"status": 403,
"code": "forbidden",
"detail": "This API key doesn't have the contacts:write scope. …",
"request_id": "0b7c9e2a-…"
}If a key leaks
Revoke it in the dashboard straight away and create a replacement. Keys are stored hashed on our side, so a leaked key can't be recovered from fullhall; anywhere it was pasted is the risk. The dashboard's last-used column helps you spot use you don't recognise.
Back to the API overview and quickstart.