Ves al contingut

Autenticació i scopes ​

L'API pública (/api/v1/*) accepta claus API i tokens OAuth2 a la capçalera Authorization: Bearer. Fes servir una clau API per a una integració pròpia entre servidors; fes servir OAuth2 quan una altra aplicació necessiti que un usuari autoritzi l'accés a la seva empresa. La BFF (/app/*) fa servir la sessió del navegador amb cookie sobre HTTPS; els tokens OAuth2 no hi donen accés.

API key ​

L'API pública s'autentica amb una API key del tenant, enviada com a token Bearer:

Authorization: Bearer bk_live_xxxxxxxxxxxxxxxx
  • bk_live_… → tenant de producció.
  • bk_test_… → tenant de proves, que remet als serveis de test de l'AEAT. Consulta l'entorn de proves.

Una clau invàlida o absent retorna 401; una clau sense l'scope necessari retorna 403.

OAuth2 per a aplicacions externes ​

Les aplicacions externes també poden connectar-se amb authorization code i PKCE S256. Un administrador de Bilteo registra l'aplicació a l'admin amb el nom, les URL de retorn exactes i els scopes màxims. El client_id és públic; no hi ha client secret. L'usuari que autoritza necessita api_keys.admin al tenant escollit.

Genera un code_verifier aleatori de 43–128 caràcters, el seu code_challenge = base64url(SHA256(code_verifier)) sense padding, i un state aleatori d'almenys 16 caràcters. Redirigeix el navegador a la pàgina de l'app https://<host-app>/oauth/authorize amb response_type=code, client_id, redirect_uri, scope (separats per espais), state, code_challenge i code_challenge_method=S256. Després del consentiment, verifica state i bescanvia code una sola vegada abans de cinc minuts. Bilteo permet escollir el tenant; pots enviar tenant_id si ja el coneixes:

Si l'usuari rebutja l'accés, Bilteo torna a redirect_uri amb error=access_denied i el state original.

Exemple d'URL d'autorització (codifica cada paràmetre de consulta; a scope, els espais es codifiquen com %20):

text
https://<host-app>/oauth/authorize?response_type=code&client_id=<uuid>&redirect_uri=https%3A%2F%2Fapp.exemple.com%2Fcallback&scope=invoices%3Aread%20partners%3Aread&state=<valor-aleatori>&code_challenge=<desafiament-base64url>&code_challenge_method=S256

Bescanvia el codi rebut:

bash
curl -X POST https://api.test.bilteo.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'client_id=<uuid>' \
  --data-urlencode 'code=<codi-rebut>' \
  --data-urlencode 'redirect_uri=https://app.exemple.com/callback' \
  --data-urlencode 'code_verifier=<verifier-original>'

La resposta inclou access_token, token_type (Bearer), expires_in (900 segons), refresh_token i scope.

Envia Authorization: Bearer bo_at_... a /api/v1/*. L'access token dura 15 minuts. Renova'l amb POST /oauth/token, enviant grant_type=refresh_token, client_id i refresh_token=bo_rt_.... Desa el nou refresh token: cada ús el rota i reutilitzar-ne un d'antic revoca tota la connexió. El refresh token caduca als 30 dies. Per desconnectar, envia client_id i token (access o refresh) a POST /oauth/revoke com a formulari. La metadata és a /.well-known/oauth-authorization-server.

bash
curl -X POST https://api.test.bilteo.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'client_id=<uuid>' \
  --data-urlencode 'refresh_token=bo_rt_...'

curl -X POST https://api.test.bilteo.com/oauth/revoke \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'client_id=<uuid>' \
  --data-urlencode 'token=bo_rt_...'

OAuth2 i API keys fan servir exactament els mateixos scopes i endpoints. Cada token OAuth queda vinculat al tenant autoritzat: no facis servir X-Tenant per canviar-lo. Les credencials absents o caducades retornen 401; si falten scopes, 403. Consulta els errors d'autenticació.

Identitat de la credencial ​

GET /api/v1/me diu a quina empresa està vinculada la credencial. Funciona amb clau API i amb token OAuth i no necessita cap scope.

json
{
  "tenant": {
    "id": "…",
    "name": "Perruqueria Exemple SL",
    "issuer_name": "Perruqueria Exemple SL",
    "issuer_id_num": "B12345678",
    "livemode": true
  },
  "plan_code": "pro",
  "auth": { "type": "oauth", "scopes": ["invoices:read", "invoices:write"] }
}

livemode val false al tenant de proves. Amb OAuth, crida'l just després d'obtenir el token. L'usuari tria l'empresa a Bilteo i la resposta del token no la inclou.

Scopes ​

Cada clau API o connexió OAuth té un conjunt de scopes que limita què pot fer. Concedeix només els necessaris. Segueixen el patró recurs:acció; els catàlegs de només lectura exposen únicament :read.

ScopePermet
invoices:readLlegir factures i les seves línies
invoices:writeCrear i editar esborranys i línies, i crear rectificatives
invoices:issueEmetre factures: numerar-les i remetre-les a l'AEAT
invoices:cancelAnul·lar factures emeses
invoices:replace_simplifiedCrear o emetre F3 que substitueixen F2 i gestionar les relacions replace
invoices:fixSubsanar el registre Veri*Factu d'una factura emesa: la reobre (needs_fix) si mai ha estat acceptat, o encua la subsanació directament si ho ha estat; s'usa amb invoices:issue
verifactu:readConsultar registres Veri*Factu i factures externes de Verifactu Direct API
verifactu:writeRegistrar, anul·lar i subsanar factures externes a Verifactu Direct API
partners:read / partners:writeLlegir o gestionar clients
products:read / products:writeLlegir o gestionar productes
series:read / series:writeLlegir o gestionar sèries de numeració
economic_activities:read / economic_activities:writeLlegir o gestionar activitats econòmiques
taxes:readLlegir el catàleg d'impostos
fiscal_positions:readLlegir el catàleg de posicions fiscals
payment_terms:readLlegir les condicions de pagament (només lectura)
usage:readConsultar el pla efectiu, els límits i el consum actual
webhooks:readLlistar i consultar la configuració dels endpoints (sense el secret)
webhooks:writeCrear, editar i esborrar endpoints; regenerar-ne el secret

La font de veritat són les rutes

Cada operació de la referència de l'API declara l'scope que exigeix. Si aquesta taula i la referència no coincideixen, preval la referència, que es genera des del servei.

Subsanar també requereix emetre

POST /invoices/{id}/actions/request-fix exigeix invoices:fix i invoices:issue: reobrir només té sentit si la clau també pot tornar a emetre la subsanació. Consulta Subsanació.

Bilteo · Documentació