Autenticación en la API de 4invoices

Cambia client_id y client_secret por un token Bearer de una hora, solo de servidor a servidor.

Cambia client_id y client_secret por un token Bearer de una hora, solo de servidor a servidor.

← Volver a la documentación de la API

Tu primera factura en 6 pasos

  1. Genera la credencial en el panel, en Facturación → Configuración → Acceso API, y copia el client_secret de inmediato: solo se muestra una vez.
  2. Envía POST /v1/auth/token con grant_type client_credentials, client_id y client_secret.
  3. Recibes access_token, token_type Bearer, expires_in 3600 y la lista de scopes concedidos.
  4. Incluye el token en una cabecera Authorization: Bearer <access_token> en todas las demás llamadas.
  5. Comprueba qué has obtenido realmente con GET /v1/me: tenant, scopes y los cupos de peticiones actuales.

Todos los endpoints

MétodoEndpointScopeIdempotency-KeyPeticiones / minuto
POST/auth/token
Cambiar las credenciales por un token de acceso
——120
GET/me
Tenant, scopes y límites actuales
invoices:read—120

Qué es la API de 4invoices

bash
curl -sS -X POST https://api.4invoices.net/v1/auth/token \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "cli_XXXXXXXXXXXX",
    "client_secret": "sec_XXXXXXXXXXXXXXXXXXXX"
  }'

# → {"access_token":"eyJ...","token_type":"Bearer","expires_in":3600,
#    "scope":"invoices:read invoices:write efactura:submit"}
bash
curl -sS https://api.4invoices.net/v1/me \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# → tenant, scopes concedidos y cupos de peticiones actuales
javascript
// Guarda el token en caché; no generes uno por petición.
let cached = { token: "", expiresAt: 0 };

async function getToken() {
  if (cached.token && Date.now() < cached.expiresAt - 60_000) return cached.token;

  const res = await fetch("https://api.4invoices.net/v1/auth/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "client_credentials",
      client_id: process.env.FOURINVOICES_CLIENT_ID,
      client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
    }),
  });
  if (!res.ok) throw new Error(`token ${res.status}`);

  const data = await res.json();
  cached = { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000 };
  return cached.token;
}

https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json

Scopes

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit
Solo servidor a servidor. Nunca llames a la API desde JavaScript de navegador: el client_secret llegaría al visitante y CORS bloquea cualquier origen de todos modos.

Errores

EstadoTipoCódigo
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
403permission_errorinsufficient_scope

Errores frecuentes

  • El endpoint de tokens tiene su propio límite por IP. Un token por proceso, renovado antes de que caduque, no uno por petición.
  • El client_secret se almacena solo como hash; si lo pierdes, generas una credencial nueva y revocas la anterior.
  • Emite credenciales distintas para el ERP, la tienda y los scripts internos, cada una con scopes mínimos. Revocar una no afecta a las demás.
  • CORS no admite ningún origen de navegador: la API es servidor a servidor por diseño.

Preguntas y respuestas para desarrolladores

¿Qué ocurre si el client_secret es incorrecto?

Recibes un 401 con el código invalid_client. Un secreto demasiado corto falla antes, en la validación, con 422 validation_failed y param client_secret.

¿Existe un entorno de pruebas aparte?

No. Hay un único host de producción. Prueba con proformas (document_kind proforma) y con /invoices/preview-totals, que no consume ningún número fiscal.

¿Puedo reducir los scopes de una credencial existente?

Sí, desde el panel. Los tokens ya emitidos conservan los scopes con los que se generaron hasta que caducan, en un plazo máximo de una hora.