API authentication

API keys, scopes, and the workspace a request acts on.

Every /api route answers to an API key sent as Authorization: Bearer fk_..., or to a member's session cookie. A key is personal: it is minted by a member and acts on the workspace they belong to.

Create a key

POST /api/keys mints a key. The secret is shown in full exactly once, in that answer. You choose the scopes at creation; the key's stored scopes stay the audit record.

sh
curl -X POST http://127.0.0.1/api/keys \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer fk_<key>' \
  -d '{"name":"staging","scopes":["conversations:read","conversations:write","contacts:read"]}'

The key looks like fk_<32 hex workspace id>_<43 base64url characters>. The workspace id inside the key is what lets the api enter the right tenant before it looks anything up.

Use the key
curl http://127.0.0.1/api/conversations \
  -H 'authorization: Bearer fk_<key>'

Minting or rotating a key needs a session minted in the last fifteen minutes, which is also what stops one key from minting another. POST /api/keys/{id}/rotate replaces a key with a new secret carrying the same scopes; DELETE /api/keys/{id} revokes one.

Scopes

A key never grants more than its owner's role grants today. On every request the api takes the intersection of the key's stored scopes with what the member's current role allows, so demoting a member narrows their keys in the same breath.

ScopeGrants
conversations:readList and read conversations, parts and views.
conversations:writeReply, note, snooze, tag and reassign conversations.
conversations:deleteUnsend and redact.
contacts:readList and read contacts and companies.
contacts:writeCreate and change contacts and companies.
contacts:deleteErase a contact.
contacts:exportQueue a subject-access export.
settings:readRead workspace configuration.
settings:writeChange workspace configuration.
members:readRead members and teams.
members:inviteInvite and remove members, move rosters.
events:readRead the change feed.
api_keys:createMint keys.
api_keys:revoke_ownRevoke your own keys.
api_keys:revoke_anyRevoke any key in the workspace.

Roles are owner, admin, agent and viewer. An agent holds read and write on conversations and contacts but no settings or member changes. A viewer holds read only.

Naming the workspace

With a session cookie, a request claims its workspace through the X-Fikadesk-Workspace header or a workspace query parameter. With a bearer key there is no header to send: the key's own workspace is the one the request acts on.