Cairos
Facturación
Programa de facturaciónPresupuestosFacturas recurrentesGastos y proveedoresCobros y tesorería
Contabilidad e impuestos
ContabilidadModelos de HaciendaLibros registroInmovilizadoIGIC y Canarias
Operaciones
Inventario y almacenesCRMControl horarioProyectosSubvenciones y ayudas
Cumplimiento
VeriFactuTicketBAIFactura electrónicaToda la normativaSeguridad y datos
Por tipo de negocio
AutónomosPymesAsesorías y gestoríasExtranjeros en EspañaStartupsComercios y tiendas
Por sector
Hostelería y restaurantesConstrucción y reformasServicios profesionalesComercio electrónicoTodos los sectores
Por forma jurídica
AsociacionesFundacionesCooperativasClubes deportivosTodas las formas jurídicas
Cambiar de programa
ComparativasAlternativa a HoldedMigrar tus datos
Herramientas gratis
Plantilla de facturaCalculadora de IVACalculadora de IRPFTodas las herramientas
Aprender
GuíasGlosarioCalendario fiscalBlog
Desarrolladores
API y documentaciónEmpezar en cinco minutosReferencia de recursosWebhooks
Ayuda
Centro de ayudaContacto
Precios
Empieza gratis Iniciar sesión
Automatización

n8n: HTTP Request para llamar y Code para verificar

Tampoco hay nodo oficial, y aquí importa menos que en ningún sitio: n8n tiene un nodo de código, y eso es lo que hace falta para comprobar la firma de un webhook antes de fiarse de él.

Credencial Header AuthFirma comprobada en un nodo CodePaginación por cursor

La API está en marcha. Esto es lo que hay hoy y lo que no

Funciona. Las rutas de esta documentación están desplegadas y respondiendo en https://erp.cairos.es/api/v1/. Los ejemplos de estas páginas se pueden copiar y ejecutar. La especificación completa está en openapi.json, que es lo que importan Make y n8n.

Las claves te las creas tú, desde Desarrolladores en tu cuenta de Cairos. Empieza con una cai_test_: trabaja contra tus datos de verdad pero no registra en VeriFactu ni envía correos, así que puedes montar tu integración sin ensuciar una serie de facturación.

Y lo que todavía NO hay, dicho sin adornos: ningún conector oficial. Ni app de Shopify, ni plugin de WooCommerce, ni módulo publicado en Make o n8n. Con la API y su especificación se pueden construir —para eso están las guías de esta sección— pero construirlos es trabajo, y ese trabajo no está hecho.

Si montas algo con esto, escríbenos a hola@cairos.es. Nos interesa especialmente lo que te falte del contrato: es lo que decide qué se amplía primero.

No hay nodo oficial de Cairos en n8n

No está publicado y no hay fecha. Lo que hay es la API y esta página, que te dice exactamente qué enganchar y con qué código. Es menos cómodo que instalar algo y es lo que hay hoy; decirlo así te ahorra buscar un conector que no existe.

La credencial, que se monta una vez

n8n no tiene nodo de Cairos, y no hace falta: el nodo HTTP Request llama a cualquier API. Lo que sí conviene montar bien desde el principio es la credencial, para no repetir la clave en cada nodo ni dejarla escrita en el flujo.

Se crea una credencial de tipo Header Auth con estos dos valores:

Credencial Header Auth
Name:  Authorization
Value: Bearer cai_live_TU_CLAVE

A partir de ahí, cada nodo HTTP Request usa esa credencial y no vuelve a saber nada de la clave. Cuando la rotes, se cambia en un sitio.

Llamar a Cairos

Un nodo HTTP Request por operación. Lo que hay que rellenar es siempre lo mismo:

Campo del nodoValor
MethodPOST
URLhttps://erp.cairos.es/api/v1/facturas
AuthenticationGenérica, con la credencial Header Auth de arriba
Send BodyActivado, en JSON
HeadersIdempotency-Key, con el identificador del pedido del nodo anterior

Y activa el reintento del propio nodo sólo si has puesto la llave de idempotencia. Un reintento de un POST sin llave es la forma más rápida de acabar con dos facturas.

El cuerpo, en modo JSON, con las expresiones de n8n para tomar los datos del nodo anterior:

Body · JSON
{
  "contacto_id": "{{ $json.id }}",
  "serie": "WEB",
  "fecha": "{{ $now.format('yyyy-MM-dd') }}",
  "lineas": [
    {
      "concepto": "{{ $('Pedido').item.json.titulo }}",
      "cantidad": 1,
      "precio": 180.00,
      "iva": 21
    }
  ]
}

Recibir sucesos de Cairos, que es donde n8n brilla

Aquí es donde n8n gana a las alternativas sin código: tiene un nodo de código donde se puede comprobar la firma de un webhook, que es lo único que no es negociable al abrir un extremo público.

El montaje son tres nodos:

#NodoQué hace
1WebhookRecibe el POST de Cairos. Hay que activar la opción de cuerpo sin procesar: sin ella no se puede comprobar la firma.
2CodeComprueba la firma con el secreto de la suscripción y corta si no cuadra.
3Lo que quierasAvisar por Slack, escribir en una hoja, actualizar el pedido en tu tienda.
Nodo Code · comprobar la firma
const crypto = require("crypto");

const secreto = $env.CAIROS_SECRETO;
const entrada = $input.first().json;

// El cuerpo CRUDO, tal y como llegó. Si aquí usas el JSON ya
// convertido, la firma no cuadrará nunca y perderás una tarde.
const crudo = entrada.rawBody || entrada.body;
const cabecera = entrada.headers["cairos-firma"] || "";

const partes = Object.fromEntries(
  cabecera.split(",").map((t) => t.trim().split("="))
);

const ahora = Math.floor(Date.now() / 1000);
if (!partes.t || Math.abs(ahora - Number(partes.t)) > 300) {
  throw new Error("Suceso caducado o sin marca de tiempo");
}

const esperada = crypto
  .createHmac("sha256", secreto)
  .update(partes.t + "." + crudo)
  .digest("hex");

if (esperada !== partes.v1) {
  throw new Error("Firma no valida");
}

return [{ json: JSON.parse(crudo) }];

Cómo se calcula esa firma y por qué la marca de tiempo va dentro está en webhooks. Y la dirección que te da el nodo Webhook es la que se registra con POST /webhooks.

Recorrer listas largas

Para leer todas las facturas de un año no vale una sola llamada: la API pagina con cursor. En n8n eso se monta con el paginado del propio nodo HTTP Request, o a mano con un bucle:

  • Pide con ?limite=200.
  • Guarda siguiente de la respuesta.
  • Vuelve a pedir con ?desde= y ese valor.
  • Para cuando siguiente venga a null, no cuando datos venga vacío.

El detalle de la paginación, con el bucle escrito en JavaScript y en PHP, está en errores y paginación.

Preguntas sobre n8n

No. Se usa el nodo HTTP Request con una credencial de tipo Header Auth. Para todo lo que describe esta documentación, es suficiente.
Con una credencial Header Auth: nombre Authorization y valor Bearer más la clave. Los nodos la referencian y no la contienen, así que al rotarla se cambia en un sitio.
Sí, y es donde n8n va mejor que las alternativas sin código: nodo Webhook con la opción de cuerpo sin procesar activada, y un nodo Code que comprueba la firma HMAC antes de seguir.
Casi siempre porque estás firmando contra el JSON ya convertido a objeto y vuelto a serializar, que no es idéntico al que llegó. Hay que activar el cuerpo sin procesar en el nodo Webhook y firmar contra eso.
Sí, pero sólo si mandas Idempotency-Key. Un reintento de un POST sin llave es exactamente cómo se acaba con dos facturas del mismo pedido.

Deja el flujo montado y espera la clave

Las rutas, las cabeceras y la firma son las definitivas. Cuando la API abra, sólo hay que rellenar la credencial.

HTTP Request · Header Auth · Cuerpo sin procesar en el Webhook

Soporte