Skip to main content

Authentication and scopes

Partner API uses the OAuth2 Client Credentials grant (RFC 6749 §4.4). No user login, cookies, or sessions — every call is authenticated with your clientId / client secret pair.

Getting a token

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type = client_credentials
client_id = <your clientId>
client_secret = <your client secret>
org_id = <client org UUID> (optional)

There are two token flavors, both valid for 1 hour, with no refresh token (just call /oauth/token again):

Token typeorg_id sent?Use it for
App-onlyNoDiscovering authorized organizations only
Org-scopedYesAll invoice/signing endpoints, on behalf of that organization

Response:

{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "invoice:write invoice:read ttn:submit"
}

Send it as a bearer token on every subsequent call:

Authorization: Bearer <access_token>
Common errors
  • 401 invalid_client — wrong client_id/client_secret.
  • 403 access_deniedorg_id given but not authorized for your app (revoked, never granted, or inactive).
  • 429 TOO_MANY_REQUESTS — rate limit exceeded (see the Reference page).

Scopes

ScopeGrants
invoice:writeCreate, update, submit, duplicate, delete draft invoices; trigger sign-and-send
invoice:readList and retrieve invoices, statuses, PDFs, generated XML, jobs, activity
ttn:submitManually (re)submit to TTN — org-owned keys only, not partner tokens
seal:signTrigger SEAL signing as part of sign-and-send
digigo:signTrigger DigiGO signing as part of sign-and-send

A client only grants the scopes they're comfortable with — check allowedScopes before calling an endpoint that needs a scope you weren't granted, or you'll get a 403 INSUFFICIENT_SCOPES.

Discovering client organizations

Use your app-only token for these two endpoints:

GET /api/partner/authorized-orgs

Lists every organization currently authorizing your app (orgId, orgName, taxIdentifier, allowedScopes, authorizedAt).

GET /api/partner/resolve-org?taxId=<matricule>

Resolves a Tunisian tax ID (8- or 13-character format) to the corresponding orgId, restricted to organizations that authorize your app. Returns 404 ORG_NOT_FOUND if no match.

Once you have an orgId, request an org-scoped token (org_id=<orgId>) and move on to Invoices.