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?
| Situation | Use |
|---|---|
| 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 companies | Partner 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/agentThe 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/agent4. 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
| Parameter | Value |
|---|---|
| Authorization server metadata | https://api.efaktura.sk/.well-known/oauth-authorization-server |
| Resource (audience) | https://api.efaktura.sk/v1/agent |
| Flow | OAuth 2.1, authorization code + PKCE (S256), refresh token |
| Access token | JWT, valid for 1 h, org_id claim |
| Scopes | The API key scopes, plus openid, profile, email, offline_access |
| Limits and quotas | Per the company's plan, same as an API key |
The scope list is in API keys & scopes.
What a token may do
| Rule | Behavior |
|---|---|
| One company | The token sees only the company chosen on consent; GET /v1/agent/organizations returns just that one. |
| Scopes | The intersection of the approved scopes and the user's role in the company. |
| Revocation | The user revokes it in Settings → Integrations → API keys; later calls get 401. |
| Separate from MCP | MCP tokens and Agent API tokens have different audiences and do not work for each other. |
| Audit | Every call is written to the API logs, like an API key call. |
Errors
| Situation | Response |
|---|---|
| Invalid, expired or foreign token | 401 + WWW-Authenticate header (invalid_token) |
| The user revoked the connection | 401, error_description connection_revoked |
| X-Organization-Id differs from the token | 403 Token je viazaný na inú organizáciu |
| Missing scope | 403 API key does not have scope: … |