Authentication

The API accepts two kinds of sign-in: an API key for your own integrations and OAuth 2.0 for applications that connect to companies of other users.

API key

An administrator of the company creates the key in Settings › API keys. It is shown once; only its hash is stored. The key starts with abf_ and is sent in one of these ways:

Authorization: Bearer abf_YOUR_KEY
X-Api-Key: abf_YOUR_KEY

A key belongs to one company and acts as the user who created it. It may expire on a date and can be revoked at any time; a revoked key stops working at once.

A key is worth as much as a password. Never put it into code running in a browser or a mobile app; use OAuth 2.0 with PKCE there.

Permissions

Keys and OAuth programs have read and change permissions for each area separately. Changing includes reading. Reading allows GET, changing POST, PUT and DELETE.

AreaEndpointsOAuth scope
Issued invoices (Faktury vydané)/invoices including PDF, ISDOC, sending and the tax document on an advanceinvoices:read, invoices:write
Received invoices (Faktury přijaté)/received-invoicesreceived-invoices:read, received-invoices:write
Payments/invoices/{id}/payments and /received-invoices/{id}/paymentspayments:read, payments:write
Contacts/contactscontacts:read, contacts:write
Price list/productsproducts:read, products:write
Webhooks/webhookswebhooks:read, webhooks:write

A request outside the permissions ends with 403 ApiKeyScope before it is processed; detail names the missing permission, e.g. payments:write. To issue an invoice to a contact from the address book, invoices:write and contacts:read are enough.

The former shortcut scopes still work: read = read everything, invoices = everything but webhooks, full = everything.

OAuth 2.0

Register the program in Settings › API keys › OAuth applications. You get a client_id and, for a server program, a client_secret.

Authorizationhttps://api.abfaktura.cz/api/v1/oauth/authorize
Tokenhttps://api.abfaktura.cz/api/v1/oauth/token
ScopePermissions by area (e.g. invoices:write contacts:read) and offline_access for a refresh token. Without a scope the program gets everything it was allowed.
Token lifetime1 hour

Server program for your own company (client credentials)

curl https://api.abfaktura.cz/api/v1/oauth/token \
  -d grant_type=client_credentials \
  -d client_id=YOUR_CLIENT_ID \
  -d client_secret=YOUR_SECRET \
  -d "scope=invoices:write contacts:read"
{ "access_token": "eyJhbGciOi…", "token_type": "Bearer", "expires_in": 3600, "scope": "invoices:write contacts:read" }

Application for other users (authorization code + PKCE)

  1. Send the user to the authorization address with response_type=code, client_id, redirect_uri, scope (e.g. invoices:write payments:write offline_access), state, code_challenge and code_challenge_method=S256.
  2. The user signs in to abFaktura, picks the company and allows the access.
  3. The user returns to redirect_uri with code, which you exchange for a token:
curl https://api.abfaktura.cz/api/v1/oauth/token \
  -d grant_type=authorization_code \
  -d client_id=YOUR_CLIENT_ID \
  -d code=CODE_FROM_THE_REDIRECT \
  -d redirect_uri=https://your-app.example/oauth/callback \
  -d code_verifier=ORIGINAL_VERIFIER

With offline_access you also get a refresh_token for new access tokens (grant_type=refresh_token). The user can withdraw the access at any time in Settings › API keys › Allowed applications; the tokens stop working at once.