Skip to content
Documentation
English
Open the app

Authentication

Get a session token with auth/login, create integration tokens with limited abilities and use them securely.

All API routes, apart from a few public ones (status, ping, pricing, auth/login, auth/demo), require a bearer token in the Authorization header.

GET /v1/auth/me HTTP/1.1
Host: api.novafisko.com
Authorization: Bearer 57|n8Yw2c0vXk4JrPq1LmZs
Accept: application/json

NovaFisko distinguishes two kinds of tokens.

Type Obtained through Scope Usage
Session token POST /v1/auth/login All of the user's rights NovaFisko applications, personal scripts
Integration token POST /v1/auth/tokens Chosen abilities: read, write, sync Connecting another solution, server to server

In both cases, the token acts on behalf of a user: it sees the firms and companies that user has access to, no more and no less. An inaccessible company responds 404, never 403, so as not to reveal its existence.

Session token

Log in

curl -X POST https://api.novafisko.com/v1/auth/login \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "email": "claire.dumont@fiduciaire-exemple.be",
    "password": "votre-mot-de-passe",
    "device_name": "script-export-mensuel"
  }'
Field Type Required Description
email string yes The user's address
password string yes Password
device_name string, 100 characters max no Name given to the token, api by default

Response 201:

{
  "token": "57|n8Yw2c0vXk4JrPq1LmZs",
  "user": {
    "id": 12,
    "name": "Claire Dumont",
    "email": "claire.dumont@fiduciaire-exemple.be",
    "locale": "fr",
    "is_platform_admin": false,
    "firms": [
      {"public_token": "Fd7hQ2mN8sXa", "name": "Fiduciaire Exemple", "role": "admin"}
    ],
    "managed_firms": [
      {"public_token": "Fd7hQ2mN8sXa", "name": "Fiduciaire Exemple"}
    ]
  }
}

Incorrect credentials return 422 with an error on the email field. The route is limited to 20 requests per minute and per IP address. After 10 failures, every attempt is refused for 5 minutes.

Note

Users of a Novadesko accounting firm log in with their Novadesko credentials. NovaFisko checks them in read-only mode, then mirrors the firm, its members and its companies at each login.

Get the current user

GET /v1/auth/me returns the same user object as the login, with the addition of is_demo (true for a user of the demo firm). It is the ideal call to check that a token is still valid.

Log out

POST /v1/auth/logout revokes the token used for the call and responds 204 with no body.

Integration tokens

An integration token is designed to be handed to another solution. It carries a name, a list of abilities, an optional expiry date and the date it was last used.

Abilities

Ability Allows
read All GET and HEAD requests
write POST, PUT, PATCH and DELETE requests
sync The companies/{company}/sync/* routes (bootstrap, pull, push, status, conflicts), whatever the method

The six offline synchronisation routes only require sync. A connector that merely follows changes with sync/pull therefore needs neither read nor write. The POST companies/{company}/sync/novadesko route, which reruns the import from Novadesko, is not one of them: it falls under write.

Create a token

Creation requires a session token: an integration token cannot create other tokens.

curl -X POST https://api.novafisko.com/v1/auth/tokens \
  -H "Authorization: Bearer 57|n8Yw2c0vXk4JrPq1LmZs" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Connecteur ERP Atelier",
    "abilities": ["read", "write"],
    "expires_in_days": 365
  }'
Field Type Required Description
name string, 100 characters max yes Readable name, shown in the list
abilities array yes, at least 1 value Among read, write, sync
expires_in_days integer from 1 to 730, or null no Lifetime; null or absent: no expiry

Response 201:

{
  "token": "83|4Hq7ZtVb2Mx9KcLp0RsWyE1uNaJd6FgT",
  "integration_token": {
    "id": 83,
    "name": "Connecteur ERP Atelier",
    "abilities": ["read", "write"],
    "created_at": "2026-10-05T08:30:11+00:00",
    "expires_at": "2027-10-05T08:30:11+00:00",
    "last_used_at": null
  }
}

A user can hold at most 50 integration tokens. Beyond that, creation responds 422 with the token_limit_reached code. The route is limited to 20 creations per minute.

Warning

The token value is shown only once, in this response. NovaFisko only keeps a hash of it. If you lose it, delete the token and create another one.

List tokens

curl https://api.novafisko.com/v1/auth/tokens \
  -H "Authorization: Bearer 57|n8Yw2c0vXk4JrPq1LmZs"
{
  "data": [
    {
      "id": 83,
      "name": "Connecteur ERP Atelier",
      "abilities": ["read", "write"],
      "created_at": "2026-10-05T08:30:11+00:00",
      "expires_at": "2027-10-05T08:30:11+00:00",
      "last_used_at": "2026-10-05T09:02:47+00:00"
    }
  ]
}

Only your own integration tokens are listed. The session tokens of the applications do not appear.

Revoke a token

curl -X DELETE https://api.novafisko.com/v1/auth/tokens/83 \
  -H "Authorization: Bearer 57|n8Yw2c0vXk4JrPq1LmZs"

The response is 204. The token stops working immediately. An unknown identifier, or one that is not one of your integration tokens, responds 404.

Authentication errors

Status code Cause What to do
401 absent Token missing, revoked or expired Get a new token
403 token_ability_missing The integration token lacks the required ability Create a token with the ability given in required_ability
403 session_token_required Route reserved for session tokens (auth/tokens) Use a token issued by auth/login
403 demo_mode External effect attempted from the demo firm Test this action on a real firm
422 token_limit_reached 50 integration tokens already exist Revoke unused tokens
422 absent Incorrect credentials or too many attempts Read errors.email

Example of a refusal for a missing ability:

{
  "message": "Ce jeton n'a pas la capacité requise pour cette action.",
  "code": "token_ability_missing",
  "required_ability": "write"
}

Best practices

  • One token per integration. You can revoke one without interrupting the others, and the last-used column stays readable.
  • As few abilities as possible. A reporting tool only needs read.
  • An expiry. Set expires_in_days and schedule the renewal before the deadline.
  • A dedicated user. Create a team member in the firm reserved for the integration, with the strictly necessary role. The history will clearly show what the integration did.
  • Encrypted storage. Keep the token in a secrets manager or an environment variable, never in source code, a Git repository or an application running in your customers' browser.
  • HTTPS only. Never send the token over an unencrypted connection and do not put it in a URL.
Tip

If a token may have leaked, revoke it right away with DELETE /v1/auth/tokens/{id}. Then check the History tab of the companies concerned to review the actions performed.

See also