OAuth — Connect with eFaktúra

For apps that act on behalf of eFaktúra users (e-shop, ERP, CRM, invoicing tool). The user signs in to eFaktúra, picks a company and approves what your app may do. You get a token bound to that company — nobody has to create or share an API key.

OAuth or API key?

SituationUse
Your app connects accounts of many companies (a “Connect eFaktúra” button)OAuth
Integrating one company of your own (script, internal system)API key
White-label partner and its client companiesPartner key

Flow

1. Register your app (Dynamic Client Registration, once). List the Agent API in resources — without it you only get MCP tokens.

curl -X POST https://api.efaktura.sk/api/auth/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My e-shop",
    "redirect_uris": ["https://my-shop.example/efaktura/callback"],
    "token_endpoint_auth_method": "client_secret_basic",
    "grant_types": ["authorization_code", "refresh_token"],
    "response_types": ["code"],
    "resources": ["https://api.efaktura.sk/v1/agent"]
  }'

The response carries a client_id (and a client_secret for a server-side app). A mobile or desktop app uses "token_endpoint_auth_method": "none".

2. Send the user to consent. PKCE (S256) is required.

https://api.efaktura.sk/api/auth/oauth2/authorize
  ?response_type=code
  &client_id=<client_id>
  &redirect_uri=https://my-shop.example/efaktura/callback
  &scope=openid offline_access invoice:read invoice:create invoice:send
  &state=<random value>
  &code_challenge=<S256(code_verifier)>
  &code_challenge_method=S256
  &resource=https://api.efaktura.sk/v1/agent

The user signs in, picks a company and approves the scopes. We then send them back to redirect_uri with code and state.

3. Exchange the code for a token.

curl -X POST https://api.efaktura.sk/api/auth/oauth2/token \
  -u "<client_id>:<client_secret>" \
  -d grant_type=authorization_code \
  -d code=<code> \
  -d redirect_uri=https://my-shop.example/efaktura/callback \
  -d code_verifier=<code_verifier> \
  -d resource=https://api.efaktura.sk/v1/agent

4. Call the Agent API with the token. The company is in the token, so no X-Organization-Id is needed. If you send it, it must match.

curl https://api.efaktura.sk/v1/agent/invoices \
  -H "Authorization: Bearer <access_token>"

5. Refresh the token before it expires (valid for 1 h) with grant_type=refresh_token. You get a refresh token when you asked for the offline_access scope.

Technical parameters

ParameterValue
Authorization server metadatahttps://api.efaktura.sk/.well-known/oauth-authorization-server
Resource (audience)https://api.efaktura.sk/v1/agent
FlowOAuth 2.1, authorization code + PKCE (S256), refresh token
Access tokenJWT, valid for 1 h, org_id claim
ScopesThe API key scopes, plus openid, profile, email, offline_access
Limits and quotasPer the company's plan, same as an API key

The scope list is in API keys & scopes.

What a token may do

RuleBehavior
One companyThe token sees only the company chosen on consent; GET /v1/agent/organizations returns just that one.
ScopesThe intersection of the approved scopes and the user's role in the company.
RevocationThe user revokes it in Settings → Integrations → API keys; later calls get 401.
Separate from MCPMCP tokens and Agent API tokens have different audiences and do not work for each other.
AuditEvery call is written to the API logs, like an API key call.

Errors

SituationResponse
Invalid, expired or foreign token401 + WWW-Authenticate header (invalid_token)
The user revoked the connection401, error_description connection_revoked
X-Organization-Id differs from the token403 Token je viazaný na inú organizáciu
Missing scope403 API key does not have scope: …
The connection also shows up for the user in Settings → Integrations, and we e-mail them about every new connection.