La API pública de FacturaDirecta soporta dos métodos de autenticación, OAuth2 y API key. Cada operación acepta ambos; tú eliges el que mejor encaje con tu integración. Ambos comparten los mismos scopes y operan sobre el mismo conjunto de endpoints.

Endpoint base

Todas las URLs de la API pública en producción tienen el prefijo:

text
https://app.facturadirecta.com/api

A partir de ahí, los paths que se documentan en cada recurso (por ejemplo /{companyId}/contacts) se concatenan a esta base.

Recursos auxiliares:

  • Referencia OpenAPI navegable (Swagger UI): https://www.facturadirecta.com/api
  • Especificación OpenAPI cruda (openapi.json): https://app.facturadirecta.com/openapi.json

OAuth2

Recomendado cuando un usuario conecta su propia empresa de FacturaDirecta a tu aplicación. Tú obtienes un token en su nombre y operas dentro de su empresa.

FacturaDirecta usa Keycloak como servicio de autorización, con realm facturadirecta. El flujo es authorizationCode estándar:

  1. Rediriges al usuario a la URL de autorización con client_id=facturadirecta-api y los scopes que necesitas.
  2. El usuario autentica y autoriza los scopes.
  3. Keycloak redirige a tu callback con un code.
  4. Intercambias code por access_token (y opcionalmente refresh_token) en el endpoint de token.
  5. Usas el access_token en el header Authorization: Bearer <token> para cada llamada a la API.

URLs del servicio de autorización en producción:

EndpointURL
Autorizaciónhttps://auth.facturadirecta.com/auth/realms/facturadirecta/protocol/openid-connect/auth
Tokenhttps://auth.facturadirecta.com/auth/realms/facturadirecta/protocol/openid-connect/token
Refreshhttps://auth.facturadirecta.com/auth/realms/facturadirecta/protocol/openid-connect/token

La fuente autoritativa es el openapi.json público en https://app.facturadirecta.com/openapi.json, sección components.securitySchemes.oAuth.flows.authorizationCode.

client_id para integraciones externas es facturadirecta-api y no requiere client_secret.

La API pública solo acepta tokens emitidos para clientes OAuth autorizados por FacturaDirecta. Los clientes gestionados por FacturaDirecta para integraciones propias, como conectores MCP autorizados y el CLI, pueden usar su propio client_id. Un token válido del realm no basta si el cliente OAuth que lo emitió no está autorizado para la API pública.

En esos clientes, el usuario elige además las empresas y los permisos de cada conexión. La autorización efectiva es la intersección entre lo que admite el token, lo concedido a la conexión, el rol actual del usuario y el plan de la empresa. Los cambios de Aplicaciones conectadas se aplican sin repetir el flujo OAuth.

offline_access como scope te permite obtener un refresh_token para operar sin nueva intervención del usuario.

Cerrar la sesión de la web o de la aplicación móvil no revoca los tokens del MCP, del CLI ni de las integraciones OAuth que el usuario ya ha autorizado. Estas autorizaciones se retiran desde Aplicaciones conectadas o por el mecanismo de revocación de la integración. Los tokens de la propia sesión web o móvil sí dejan de aceptarse al cerrar esa sesión.

Ejemplo de cabecera

http
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIi...

API key

Si tu integración solo necesita acceder a una empresa concreta que tú administras, puedes generar una API key desde Ajustes > Integraciones en la propia empresa de FacturaDirecta, o crearla por API desde POST /apiKeys.

Al crear una API key le asignas los scopes que va a poder usar (los mismos que están disponibles para OAuth2, salvo offline_access que para una API key no tiene sentido).

Ejemplo de cabecera

http
facturadirecta-api-key: aB3cD9.xY7zN2qK4mP8rT5sJ1hF6gL0vW3uE

Formato: <prefijo de 6 caracteres>.<sufijo de 32 caracteres>. Es lo que devuelve POST /apiKeys en el campo apiKey de la respuesta (solo visible en la creación; tras eso, FacturaDirecta solo conserva el hash). La API key se envía como header propio, no como Authorization: Bearer.

Versión de la API

Todas las peticiones aceptan el header accept-version con el número de versión de la API. Si no lo envías, se usa la versión vigente definida por el servidor. Para producción se recomienda fijarlo explícitamente:

http
accept-version: 1.0.10

El servidor solo aplica versiones que se hayan publicado. Si envías una versión desconocida o con un formato no válido, aplica la versión vigente. La cabecera X-Api-Version de la respuesta indica qué versión se ha aplicado.

Scopes

Cada operación de la API declara los scopes que requiere. Los scopes siguen el patrón <recurso>:<acción>:

  • <recurso>:read — permite leer (GET).
  • <recurso>:write — permite crear, modificar y borrar (POST, PUT, DELETE).

El conjunto exacto de scopes y su descripción está en el openapi público y en cada página de recurso de esta documentación. Pide siempre los scopes mínimos necesarios para la integración.

Dos scopes se salen del patrón y conviene conocerlos:

  • banks:readIban — scope adicional que añade el IBAN completo a las consultas de bancos y de métodos de pago. Ver Bancos.
  • files:write — permite subir archivos para adjuntarlos a documentos. Ver Uploads.

Los documentos del Módulo Inventario tienen sus propios scopes: clientOrders:read y clientOrders:write para pedidos, y purchaseOrders:read y purchaseOrders:write para órdenes de compra. Tener el scope no basta: también se aplican el rol del usuario y el plan de la empresa. En una aplicación conectada se comprueba además la empresa y el nivel concedido para el recurso.

Si el plan no incluye los documentos del Módulo Inventario, las escrituras responden 403. Las operaciones de stock de productos siguen usando products:read y products:write, y también dependen de que el plan incluya el control de stock.

Límite de peticiones

Cada empresa tiene un límite de peticiones por minuto que depende de su plan. El límite se cuenta por empresa (no por credencial) en ventanas de un minuto naturales, y solo se aplica al tráfico de integración: llamadas con API key y con clientes OAuth de integración.

PlanPeticiones por minuto
Gratis30
Bronce60
Plata120
Oro300
Diamante600

Esos son los valores de la familia de planes vigente. Algunas cuentas con planes anteriores o con condiciones particulares tienen otro límite: no lo supongas a partir del plan, léelo de la cabecera de la respuesta.

Cada respuesta incluye estas cabeceras:

http
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1789012860
  • X-RateLimit-Limit — peticiones permitidas en la ventana actual.
  • X-RateLimit-Remaining — peticiones que te quedan en esta ventana.
  • X-RateLimit-Reset — timestamp Unix (segundos) en que empieza la ventana siguiente.

Cuando una petición supera el límite, la respuesta añade además Retry-After con los segundos que faltan para la ventana siguiente. Hoy esa petición se sigue atendiendo: el exceso queda registrado pero no se rechaza. Aun así, diseña la integración para respetar el límite —lee X-RateLimit-Remaining y espacia las llamadas— y para tratar un 429 Too Many Requests con reintento tras Retry-After.

Errores de autenticación

  • 401 Unauthorized — token expirado, ausente, mal formado, emitido por un cliente OAuth no autorizado para la API pública, o API key inválida. Refresca el token (si tienes refresh_token), revisa el client_id o regenera la API key.
  • 403 Forbidden — la credencial es válida, pero falta un scope, el rol no permite la operación, el plan no incluye la API o la aplicación conectada no tiene concedida esa empresa o ese recurso.
  • 403 Forbidden con manageUrl — el usuario puede abrir esa página para ampliar la conexión y repetir la llamada sin volver a autorizar la aplicación.
  • 403 Forbidden con companyId ajeno — el token no tiene acceso a la empresa indicada en el path. En OAuth, el usuario solo accede a empresas en las que tiene rol y, cuando hay una conexión, a las que haya autorizado. Una API key solo accede a la empresa en la que se creó.

Para el formato general de errores ver Errores y validaciones.

Recomendaciones

  • No registres tokens ni API keys en logs, ni siquiera durante desarrollo.
  • Limita los scopes al mínimo necesario. Si solo lees contactos, no pidas contacts:write.
  • Una API key por integración. Si una integración deja de usarse, rota la API key antes de borrarla.
  • Para multi-tenant SaaS, OAuth2 con offline_access es el patrón correcto. API keys son por empresa y no escalan a “una clave para varias empresas”.

Empieza gratis y factura con flow

Únete a los más de 90.000 negocios que ya gestionan sus facturas de forma rápida y sencilla con FacturaDirecta
Empieza Gratis

Fácil de usar · Sin permanencia · Sin tarjeta de crédito