Factuarea API

Autenticación

API keys con prefijos fact_live_ / fact_test_, scopes granulares, rotación con periodo de gracia y lista de acceso por IP.

La API de Factuarea autentica cada request con una API key. Las claves son tokens opacos generados en el dashboard de desarrolladores (app.factuarea.com/settings/developers/api-keys) y vinculados a una empresa concreta. Cada request a https://api.factuarea.com/v1/* debe incluir una clave válida en uno de los dos formatos soportados.

Formato de la API key

fact_live_<24 alphanumeric characters>
fact_test_<24 alphanumeric characters>

Ejemplo:

fact_live_8KqW3pXnR2VbY7TcA9eFmN5z
fact_test_3pXnR2VbY7TcA9eFmN5z8KqW
  • Prefijo: determina el entorno. fact_live_ opera sobre tu empresa real (producción); fact_test_ opera sobre una empresa sandbox aislada con los efectos externos (VeriFactu → AEAT, FACe, emails, webhooks) desactivados. El prefijo te permite identificar el entorno sin decodificar la clave. Consulta Modo de prueba y sandbox.
  • Secreto: 24 caracteres base62 → ~143 bits de entropía. Se muestra solo una vez al crearla en el dashboard. Si la pierdes, debes rotarla.
  • Hash en BD: el backend solo almacena el hash bcrypt cost-12 del secreto. No hay forma de recuperarlo.

Todos los ejemplos de esta guía usan una clave fact_live_, pero el mismo request funciona con una clave fact_test_ — basta con cambiar el prefijo para operar sobre datos de sandbox. Crea y valida tu integración primero en test. Consulta Modo de prueba y sandbox.

Enviar la clave en cada request

La API acepta dos formatos equivalentes. Elige el que mejor encaje con tu cliente:

Authorization Bearer (recomendado)

curl https://api.factuarea.com/v1/clients \
  -H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Cabecera X-API-Key

curl https://api.factuarea.com/v1/clients \
  -H "X-API-Key: fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"

Envía solo una de las dos cabeceras. Si ambas están presentes, la cabecera Authorization: Bearer tiene prioridad.

Ejemplos por lenguaje

$client = new GuzzleHttp\Client([
    'base_uri' => 'https://api.factuarea.com/v1/',
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('FACTUAREA_API_KEY'),
        'Accept' => 'application/json',
    ],
]);

$response = $client->get('clients?limit=10');
$body = json_decode((string) $response->getBody(), true);
const res = await fetch('https://api.factuarea.com/v1/clients?limit=10', {
  headers: {
    Authorization: `Bearer ${process.env.FACTUAREA_API_KEY}`,
    Accept: 'application/json',
  },
});
const data = await res.json();
import os
import requests

resp = requests.get(
    'https://api.factuarea.com/v1/clients',
    params={'limit': 10},
    headers={
        'Authorization': f"Bearer {os.environ['FACTUAREA_API_KEY']}",
        'Accept': 'application/json',
    },
)
resp.raise_for_status()
data = resp.json()

Scopes

Cada API key se crea con uno o más scopes que limitan qué endpoints puede invocar. Los scopes son cadenas con la forma <resource>:<action>. El catálogo es cerrado: cualquier scope fuera del conjunto listado provoca invalid_scope al crear la clave.

ScopePermite
clients:readListar y consultar clientes.
clients:writeCrear y actualizar clientes.
clients:deleteEliminar clientes.
products:readListar y consultar productos.
products:writeCrear y actualizar productos.
products:deleteEliminar productos.
suppliers:readListar y consultar proveedores.
suppliers:writeCrear y actualizar proveedores.
suppliers:deleteEliminar proveedores.

Documentos de venta

ScopePermite
invoices:readListar y consultar facturas.
invoices:writeCrear y actualizar facturas (incluye duplicar y rectificativa).
invoices:deleteEliminar borradores de factura.
invoices:sendEnviar factura por email al cliente.
invoices:voidAnular una factura emitida.
quotes:readListar y consultar presupuestos.
quotes:writeCrear y actualizar presupuestos.
quotes:deleteEliminar presupuestos.
quotes:sendEnviar presupuesto por email.
quotes:transitionAceptar, rechazar o convertir presupuestos.
proformas:readListar y consultar facturas proforma.
proformas:writeCrear y actualizar facturas proforma.
proformas:deleteEliminar facturas proforma.
proformas:sendEnviar factura proforma por email.
proformas:transitionConvertir factura proforma en factura.
delivery_notes:readListar y consultar albaranes.
delivery_notes:writeCrear y actualizar albaranes.
delivery_notes:deleteEliminar albaranes.
delivery_notes:transitionMarcar como entregado/cancelado, firmar, convertir.
delivery_notes:gdpr_forgetBorrar la PII de auditoría de firma (RGPD Art. 17).

Compras y recurrentes

ScopePermite
purchase_invoices:readListar y consultar facturas de compra.
purchase_invoices:writeCrear y actualizar facturas de compra.
purchase_invoices:deleteEliminar facturas de compra.
purchase_invoices:transitionMarcar como pagada, recibida, contabilizada.
recurring_invoices:readListar y consultar plantillas recurrentes.
recurring_invoices:writeCrear y actualizar plantillas recurrentes.
recurring_invoices:deleteEliminar plantillas recurrentes.
recurring_invoices:transitionPausar, reanudar y emitir manualmente.

Catálogos y exportación

ScopePermite
taxes:readLeer el catálogo (global) de tipos impositivos.
taxes:writeCrear y actualizar tipos impositivos.
taxes:deleteEliminar tipos impositivos.
series:readListar series de numeración de facturas.
series:writeCrear y actualizar series de numeración de facturas.
pdfs:readDescargar PDFs de cualquier documento con el scope :read correspondiente.
tax_reports:readLeer informes fiscales (Modelo 303/347, etc.).
tax_reports:writeGenerar informes fiscales.
account:readLeer la cuenta autenticada (GET /v1/account).

VeriFactu y FacturaE

ScopePermite
verifactu:readLeer registros, eventos, certificados y configuración de VeriFactu.
verifactu:writeGestionar certificados, ajustes y reintentos de VeriFactu.
facturae:readDescargar el XML FacturaE de una factura y leer sus envíos a FACe.
facturae:writeEnviar facturas a FACe y solicitar la anulación de envíos.

Webhooks y eventos

ScopePermite
webhooks:readListar webhook endpoints y entregas.
webhooks:writeCrear, actualizar, rotar y hacer ping a webhook endpoints.
webhooks:deleteEliminar webhook endpoints.
events:readLeer el catálogo de eventos y eventos individuales.

Super-scope

ScopePermite
*Acceso total — equivalente a tener todos los demás scopes anteriores. Reservado para claves de owner / migraciones puntuales. Evita usarlo en integraciones de producción.

Si un request usa un endpoint que requiere un scope no concedido a la clave, la respuesta es 403 con type: authorization_error y code: insufficient_scope.

{
  "error": {
    "type": "authorization_error",
    "code": "insufficient_scope",
    "message": "La API key no tiene el scope requerido para esta operación.",
    "request_id": "req_01JBVH7..."
  }
}

Gestión de claves

Las API keys se gestionan desde el dashboard de desarrolladores (app.factuarea.com/settings/developers/api-keys), no a través de la API pública. Desde ahí puedes crear claves, rotar su secreto, revocarlas, configurar scopes, un expires_at opcional y una lista de acceso por IP.

Los metadatos de la clave autenticada (id, name, prefix, scopes, tier, last_used_at, expires_at) se pueden leer vía GET /v1/account — pero el secreto nunca se devuelve.

No hay ningún endpoint para "ver" el secreto. Solo se muestra una vez al crearlo. Si pierdes el valor debes rotar la clave en el dashboard y volver a desplegar el nuevo secreto. Es deliberado: minimiza la ventana de exposición.

Rotación y revocación

  • Rota desde el dashboard para emitir un secreto nuevo. Tanto el secreto antiguo como el nuevo siguen siendo válidos durante un periodo de gracia para que puedas desplegar el nuevo sin tiempo de inactividad.
  • Revoca para invalidar una clave al instante. Cualquier request posterior con ella falla con 401 api_key_revoked. Útil cuando sospechas de una filtración.

Lista de acceso por IP

Cada API key se puede restringir a una lista de IPs o rangos CIDR desde el dashboard. Si el request llega desde una IP fuera de la lista de acceso, la respuesta es 401 y el incidente se registra en el log de auditoría. Deja la lista de acceso vacía para permitir cualquier IP.

Errores de autenticación

Los fallos relacionados con la API key responden con HTTP 401 (o 403 para insufficient_scope) y el envoltorio de error estándar. El campo code distingue el caso:

codeHTTPCausa
missing_api_key401No se ha enviado ninguna cabecera de autenticación.
invalid_api_key401La clave no existe, tiene un formato incorrecto o el secreto no coincide con el hash almacenado.
api_key_revoked401La clave fue revocada o ha expirado. Crea una nueva en el dashboard.
too_many_auth_failures429Demasiados intentos de autenticación fallidos; espera antes de reintentar.
insufficient_scope403La clave carece del scope que requiere el endpoint.

Cada respuesta incluye un request_id único (también en la cabecera X-Request-Id) que puedes facilitar a soporte al investigar.

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "La API key proporcionada no es válida.",
    "request_id": "req_01JBVH7K9Y4N3CDQ2EHJB1AGSV",
    "doc_url": "https://docs.factuarea.com/guides/errors#invalid_api_key"
  }
}

Buenas prácticas

  • Nunca subas API keys a repositorios — usa variables de entorno o un gestor de secretos (AWS Secrets Manager, Doppler, 1Password Service Accounts).
  • Crea una clave por integración: facilita rotar y auditar el acceso sin afectar al resto.
  • Limita los scopes al mínimo necesario. Un script de exportación solo necesita scopes :read concretos.
  • Activa la lista de acceso por IP para integraciones servidor a servidor con IPs estables.
  • Configura expires_at para claves temporales (p. ej. consultorías, demos).
  • Audita el uso desde el dashboard: Developers > API Keys > Activity muestra IPs, rutas y errores por clave.

En esta página