API y webhooks

Si llevas tu contabilidad o tu CRM en otra herramienta y quieres que Recua se hable con esa otra herramienta, lo haces con la API pública REST y los webhooks salientes. Estan en Sistema → API e integraciones.

Cuando usar la API

  • Pull: tu ERP necesita listar portes o facturas de Recua → usa la API REST con una API key.
  • Push: cuando ocurre algo en Recua (porte entregado, factura emitida) quieres notificar a un sistema externo → usa webhooks.

Si solo quieres ver portes en otra herramienta sin sincronia real, exporta CSV desde Analitica — es mas simple.

Crear una API key

En API e integraciones → "Nueva API key":

  • Nombre: descripcion para que sepas que sistema la usa ("ERP Sage 50", "Power BI dashboard").
  • Scopes: que permisos tiene esta key. Las dos opciones actuales son:
    • portes:read — leer portes y sus eventos.
    • portes:write — crear y actualizar portes desde el ERP.
    • (mas scopes vendran con tiempo; pidenos si necesitas algo concreto).

Al crear la key, Recua te muestra el token completo UNA SOLA VEZ — algo como ta_a1b2c3d4e5f6_<44 chars>. Copialo y guardalo en tu gestor de secretos. Si lo pierdes, regenera la key.

Usar la API

Pasa la key en el header Authorization: Bearer <token>:

curl -H "Authorization: Bearer ta_..." \
  https://recua.app/api/v1/portes?desde=2026-05-01

Endpoints actuales:

  • GET /api/v1/portes — listar portes (con filtros por estado, fecha, cliente).
  • GET /api/v1/portes/{id} — detalle de un porte.
  • POST /api/v1/portes — crear porte (requiere scope portes:write).
  • PATCH /api/v1/portes/{id} — actualizar campos.

Respuestas en JSON estandar. Errores con codigo HTTP:

  • 401 token invalido o revocado.
  • 403 token sin el scope requerido.
  • 404 recurso no existe o no pertenece a tu empresa.
  • 429 rate limit (60 requests/min por defecto).

Revocar una API key

Si sospechas que la key se ha filtrado o el sistema que la usaba ya no opera, en la lista de keys pulsa "Revocar". La key queda invalida inmediatamente y los siguientes requests del sistema externo daran 401. No se puede deshacer — genera una key nueva si la necesitas.

Las keys revocadas se conservan en BD pero marcadas como inactivas (auditabilidad). No vuelven a aparecer en la lista activa.

Webhooks salientes

Si quieres que Recua te avise cuando pasa algo, en lugar de preguntar tu cada minuto:

"Nuevo webhook":

  • URL: el endpoint en tu sistema. Tiene que ser HTTPS y publica (Recua no resuelve URLs internas: cierra el acceso a metadata, redes privadas, etc.).
  • Eventos: a que cambios suscribirse. Disponibles:
    • porte.creado
    • porte.firmado_cargador
    • porte.firmado_destinatario
    • porte.entregado
    • factura.emitida
  • Secret: Recua firma cada peticion con HMAC SHA256 usando este secret. Verifica la firma en tu endpoint para asegurar que la peticion viene de Recua y no de un tercero.

Como verificar la firma del webhook

Recua envia un header X-Recua-Signature con formato:

t=<timestamp>,v1=<hmac>

Tu endpoint:

  1. Lee timestamp y hmac del header.
  2. Calcula hmac_esperado = HMAC-SHA256(secret, timestamp + "." + body).
  3. Si hmac_esperado != hmac, rechaza la peticion (probablemente no es de Recua).
  4. Si la diferencia entre timestamp y ahora supera 5 minutos, rechaza (proteccion contra replay).

Ejemplo en Node.js:

import { createHmac } from "node:crypto";

const [tsPart, sigPart] = req.headers["x-recua-signature"].split(",");
const ts = tsPart.split("=")[1];
const recibido = sigPart.split("=")[1];

const calculado = createHmac("sha256", SECRET)
  .update(`${ts}.${rawBody}`)
  .digest("hex");

if (calculado !== recibido) return res.status(401).end();
if (Date.now() / 1000 - parseInt(ts) > 300) return res.status(401).end();

Reintentos automaticos

Si tu endpoint devuelve un codigo de error (no 2xx), Recua reintenta hasta 3 veces con backoff exponencial (1 min, 5 min, 30 min). Despues marca el envio como fallido y aparece en la pestaña "Historial" del webhook con el ultimo body de respuesta y el codigo de error.

Si quieres reintentar manualmente despues de arreglar tu endpoint, en la fila del envio fallido pulsa "Reintentar".

Errores comunes

  • "URL no permitida": la URL es http://, localhost, metadatos cloud (169.254.169.254) o red privada (192.168.x, 10.x.x.x). Por seguridad Recua bloquea SSRF.
  • Webhook nunca llega: comprueba en "Historial" si Recua intento. Si no, comprueba que el evento esta en la suscripcion; si si, comprueba tu firewall o CORS.
  • Doble registro en tu sistema: usa idempotencia. Cada webhook incluye evento_id en el body — si tu sistema ya lo proceso, ignora el duplicado.

¿Necesitas un scope que no existe (clientes, facturas, gastos) o un evento nuevo? Cuentanoslo en hola@recua.app, va a la cola.