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.
Clientes y catálogo
| Scope | Permite |
|---|---|
clients:read | Listar y consultar clientes. |
clients:write | Crear y actualizar clientes. |
clients:delete | Eliminar clientes. |
products:read | Listar y consultar productos. |
products:write | Crear y actualizar productos. |
products:delete | Eliminar productos. |
suppliers:read | Listar y consultar proveedores. |
suppliers:write | Crear y actualizar proveedores. |
suppliers:delete | Eliminar proveedores. |
Documentos de venta
| Scope | Permite |
|---|---|
invoices:read | Listar y consultar facturas. |
invoices:write | Crear y actualizar facturas (incluye duplicar y rectificativa). |
invoices:delete | Eliminar borradores de factura. |
invoices:send | Enviar factura por email al cliente. |
invoices:void | Anular una factura emitida. |
quotes:read | Listar y consultar presupuestos. |
quotes:write | Crear y actualizar presupuestos. |
quotes:delete | Eliminar presupuestos. |
quotes:send | Enviar presupuesto por email. |
quotes:transition | Aceptar, rechazar o convertir presupuestos. |
proformas:read | Listar y consultar facturas proforma. |
proformas:write | Crear y actualizar facturas proforma. |
proformas:delete | Eliminar facturas proforma. |
proformas:send | Enviar factura proforma por email. |
proformas:transition | Convertir factura proforma en factura. |
delivery_notes:read | Listar y consultar albaranes. |
delivery_notes:write | Crear y actualizar albaranes. |
delivery_notes:delete | Eliminar albaranes. |
delivery_notes:transition | Marcar como entregado/cancelado, firmar, convertir. |
delivery_notes:gdpr_forget | Borrar la PII de auditoría de firma (RGPD Art. 17). |
Compras y recurrentes
| Scope | Permite |
|---|---|
purchase_invoices:read | Listar y consultar facturas de compra. |
purchase_invoices:write | Crear y actualizar facturas de compra. |
purchase_invoices:delete | Eliminar facturas de compra. |
purchase_invoices:transition | Marcar como pagada, recibida, contabilizada. |
recurring_invoices:read | Listar y consultar plantillas recurrentes. |
recurring_invoices:write | Crear y actualizar plantillas recurrentes. |
recurring_invoices:delete | Eliminar plantillas recurrentes. |
recurring_invoices:transition | Pausar, reanudar y emitir manualmente. |
Catálogos y exportación
| Scope | Permite |
|---|---|
taxes:read | Leer el catálogo (global) de tipos impositivos. |
taxes:write | Crear y actualizar tipos impositivos. |
taxes:delete | Eliminar tipos impositivos. |
series:read | Listar series de numeración de facturas. |
series:write | Crear y actualizar series de numeración de facturas. |
pdfs:read | Descargar PDFs de cualquier documento con el scope :read correspondiente. |
tax_reports:read | Leer informes fiscales (Modelo 303/347, etc.). |
tax_reports:write | Generar informes fiscales. |
account:read | Leer la cuenta autenticada (GET /v1/account). |
VeriFactu y FacturaE
| Scope | Permite |
|---|---|
verifactu:read | Leer registros, eventos, certificados y configuración de VeriFactu. |
verifactu:write | Gestionar certificados, ajustes y reintentos de VeriFactu. |
facturae:read | Descargar el XML FacturaE de una factura y leer sus envíos a FACe. |
facturae:write | Enviar facturas a FACe y solicitar la anulación de envíos. |
Webhooks y eventos
| Scope | Permite |
|---|---|
webhooks:read | Listar webhook endpoints y entregas. |
webhooks:write | Crear, actualizar, rotar y hacer ping a webhook endpoints. |
webhooks:delete | Eliminar webhook endpoints. |
events:read | Leer el catálogo de eventos y eventos individuales. |
Super-scope
| Scope | Permite |
|---|---|
* | 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:
code | HTTP | Causa |
|---|---|---|
missing_api_key | 401 | No se ha enviado ninguna cabecera de autenticación. |
invalid_api_key | 401 | La clave no existe, tiene un formato incorrecto o el secreto no coincide con el hash almacenado. |
api_key_revoked | 401 | La clave fue revocada o ha expirado. Crea una nueva en el dashboard. |
too_many_auth_failures | 429 | Demasiados intentos de autenticación fallidos; espera antes de reintentar. |
insufficient_scope | 403 | La 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
:readconcretos. - Activa la lista de acceso por IP para integraciones servidor a servidor con IPs estables.
- Configura
expires_atpara claves temporales (p. ej. consultorías, demos). - Audita el uso desde el dashboard:
Developers > API Keys > Activitymuestra IPs, rutas y errores por clave.
Inicio rápido
Tu primera factura en 5 minutos — verifica tu key, consigue una serie y un impuesto, crea un cliente, emite una factura y envíala. Una sola secuencia de copiar y pegar contra una key fact_test_.
Modo de prueba y sandbox
Crea tu integración de forma segura con claves fact_test_ — datos de sandbox aislados y AEAT, email y webhooks desactivados.