Authentication

Server integrations use OAuth2 client credentials: a client ID and secret exchanged for a short-lived bearer token. No person has to sign in.

1. Create an API client

A workspace admin opens API clients in FinAiQ (/app/api-clients), names the client and chooses what it may do. You get a client ID (fq_client_…) and a client secret (fq_secret_…). The secret is shown once — store it in your secret manager. Lost it? Create a new secret; the old one stops working immediately.

ScopeAllows
docs.readRead folders, documents and extracted data
document_type.viewRead document types
docs.uploadUpload documents and manage email imports
docs.editEdit and validate extracted data
docs.exportExport documents to the accounting system
docs.deleteDelete and archive documents
integration.viewRead webhooks and integrations
integration.connectCreate and change webhooks
integration.set_activeTurn webhooks on and off
integration.disconnectDelete webhooks

2. Get an access token

curl -s https://api.finaiq.ai/finaiq/api/v1/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
{
  "access_token": "eyJhbGciOiJSUzI1NiIs…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "docs.read docs.upload"
}

Authenticate with HTTP Basic (client_secret_basic) as above, or send client_id and client_secret in the form or a JSON body (client_secret_post). Add scope=docs.read (space-separated) to ask for less than the client is allowed. Any standard OAuth2 library works — point it at the token URL with the client-credentials grant.

3. Call the API

curl -s https://api.finaiq.ai/finaiq/api/v1/folders \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Tokens last an hour. There is no refresh token: when one expires (or you get 401), request a new one. Cache the token and reuse it until shortly before expires_in — the token endpoint is rate limited.

Errors

HTTPerrorMeaning
401invalid_clientUnknown client, wrong secret, or the client was revoked.
400unsupported_grant_typegrant_type must be client_credentials.
400invalid_scopeYou asked for a scope the client wasn't given.

Token errors use the standard OAuth2 shape ({"error": "…", "error_description": "…"}); every other endpoint uses the FinAiQ envelope.

Revoking

Revoking a client in FinAiQ stops it within seconds — including tokens already issued. A client acts in its workspace with only the permissions it was given, and never more than its creator's role allows.

Signing in as a user

Apps that act on behalf of a person (not a server integration) sign in with POST /api/v1/auth/login (email + password), choose a workspace with POST /api/v1/auth/select-tenant when the response's kind is SELECTION_REQUIRED, and renew with POST /api/v1/auth/refresh — refresh tokens rotate, so always keep the newest one.