Skip to content

Authentication and API keys

Every call to the Clix API carries an API key as a bearer token:

Authorization: Bearer clix_A7bQ2xK_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

There is no X-API-Key header and no cookie-based access for integrations. A key sent in a cookie is deliberately rejected — that would be forgeable from a browser.

What a key looks like

clix_A7bQ2xK_<43 characters of secret>
└────┬────┘ └───────────┬───────────┘
  public id           secret

The 12-character prefix — clix_ plus a 7-character public id — is the key's public name. It identifies the key in listings and is what you pass when revoking. It shares no bytes with the secret, so it is safe to log and to put in a ticket.

Clix stores only a SHA-256 hash of the whole key. The full key is shown once, at creation. If you lose it, revoke it and issue another; nobody can recover it for you.

Issuing a key

Keys are created in the app, not through the API — a key cannot mint another key.

Who. An organisation Admin, under API Keys.

The create call returns the plaintext exactly once:

{
  "key_prefix_hint": "clix_A7bQ2xK",
  "name": "warehouse-sync",
  "role": "CreateInvoice",
  "scopes": [],
  "is_active": true,
  "created_at": "2026-09-27T09:00:00Z",
  "last_used_at": null,
  "revoked_at": null,
  "key": "clix_A7bQ2xK_…"
}

Afterwards, listings return only key_prefix_hint, created_at and last_used_at.

Roles a key may hold

A key carries exactly one role, and it is always less than an administrator:

Role A key with it can
ViewInvoice Read invoices, clients, items, devices
CreateInvoice The above, plus create invoices, notes, clients and items
Accountant The above

Admin cannot be given to a key. That is enforced at issuance, not by convention — so a leaked key can never manage users, devices, billing or other keys.

Scopes

Scopes narrow a key below its role; they never widen it. A key with role CreateInvoice and scopes ["invoice.get", "invoice.create"] can do those two things and nothing else the role would otherwise permit.

Give each integration the narrowest role and scope set that lets it do its job.

Reference-data endpoints ignore scopes

The code lists (/api/invoices/vat-categories/ and friends) are available to any authenticated caller. A narrowly-scoped key can still read them. They contain no customer data.

Revoking

Revoke by key_prefix_hint in the app. There is no cache in front of key resolution, so revocation takes effect on the very next request — no propagation delay.

Invoices already issued with a revoked key are unaffected. They are real invoices and stay cleared.

Two ways a valid key still gets refused

Response Cause
401 {"status": "false", "message": "Invalid or revoked API key"} Unknown, revoked, or belonging to a deactivated organisation
403 {"status": "false", "message": "API access is not included in your current plan."} The organisation's plan does not include API access

The second is checked on every request, not only at issuance. If a plan changes, existing keys stop working immediately without being revoked.

Handling keys safely

  • Store the key in a secret manager, never in a repository or a ticket.
  • One key per system, so one can be revoked without stopping the others.
  • Name keys for where they run — warehouse-sync, not key 1.
  • last_used_at is stamped at most once a minute; use it to find keys nothing uses any more.