NuminaDevelopers
Dashboard
Authentication

Authentication

Authenticate with an API key for your own company, or with OAuth 2.1 and PKCE for an app that other Numina companies connect to.

Every request carries a bearer token in the Authorization header. A token belongs to exactly one company, and every request reads and writes that company’s books only; there is no company ID in the URL.

HTTP
Authorization: Bearer numi_4f1c...
API key OAuth access token
For Your own company, scripts and back-office jobs Apps that other companies connect to
Acts as The company, with no user The user who approved the connection
Lifetime Until revoked 1 hour, refreshed with a rotating refresh token
Created in Settings → API & apps The consent screen in your app’s flow

Scopes

Both kinds of token carry scopes. Each names a resource and what may be done with it: read, write to create and change drafts and records, or book to post to the ledger. A request without the scope it needs fails with 403 insufficient_scope, and the error’s scope field names what the route asks for.

Resource Read Write Book
Company, accounting years, chart of accounts and VAT codes setup:read
Balances and trial balance reports:read
Journal entries and ledger entries journal:read journal:write journal:book
Invoices invoices:read invoices:write invoices:book, which also sends
Contacts contacts:read contacts:write
Products products:read products:write
Documents documents:read documents:write
Bank accounts and bank lines bank:read

Scopes are independent: journal:book does not include journal:write, and no write scope includes reading. Ask for every level you use, and no more. GET /v1/me shows what a token can do, and each endpoint in the API reference lists the scopes it accepts.

Booking scopes are for API keys, for your own app in your own company, and for reviewed partner apps. Booking through the API is your own approval of the entry: see Drafts and booking.

API keys

Create a key in Numina under Settings → API & apps and pick its permissions: read only, read and draft, or full access, which can also post to the ledger. Custom permissions set a level for each resource. Copy the key when it is shown: it is shown once. Keys start with numi_, and any member of the company can create them and revoke them from the same page.

OAuth

Numina is an OAuth 2.1 authorization server. Apps use the authorization code flow with PKCE (S256); the user signs in to Numina, picks the company to connect, and approves your scopes.

  1. Send the user to the authorization endpoint

    Generate a code_verifier, derive its code_challenge, and redirect:

    Text
    https://api.numina.app/oauth/authorize
      ?response_type=code
      &client_id=YOUR_CLIENT_ID
      &redirect_uri=https://yourapp.com/callback
      &scope=setup:read journal:read journal:write
      &state=RANDOM_STATE
      &code_challenge=CODE_CHALLENGE
      &code_challenge_method=S256
  2. Exchange the code for tokens

    Numina redirects back with code and your state. Exchange the code within a few minutes:

    cURL
    curl -X POST https://api.numina.app/oauth/token \
      -u YOUR_CLIENT_ID:YOUR_CLIENT_SECRET \
      -d grant_type=authorization_code \
      -d code=AUTHORIZATION_CODE \
      -d redirect_uri=https://yourapp.com/callback \
      -d code_verifier=CODE_VERIFIER

    Send the client ID and secret as HTTP Basic authentication, as -u does here. A secret in the request body is refused with invalid_client.

    The response holds an access_token valid for an hour and a refresh_token valid for 30 days.

  3. Refresh before the access token expires

    cURL
    curl -X POST https://api.numina.app/oauth/token \
      -u YOUR_CLIENT_ID:YOUR_CLIENT_SECRET \
      -d grant_type=refresh_token \
      -d refresh_token=REFRESH_TOKEN

    Refresh tokens rotate: every refresh returns a new one and retires the old. Store the new token before you use the access token. A retired refresh token used more than 30 seconds after its refresh ends the connection, and the user has to connect again.

The server’s endpoints are also published as metadata at /.well-known/oauth-authorization-server, so standard OAuth libraries can discover them.

Revocation

A user can disconnect your app in Numina at any time, which revokes its tokens immediately. Expect a 401 on any request and send the user through the flow again.