API y webhooks
Si llevas la contabilidad o el ERP en otro programa y quieres que hable con Recua, lo haces con la API REST y los webhooks. Esta página es técnica: pásasela a quien te lleve la informática.
Dónde está
En el menú de tu cuenta, al pie de la barra de la izquierda.
- Pulsa el nombre de tu empresa, abajo del todo.
- Pulsa API e integraciones.
- Nueva API key: para que tu programa lea o cree portes.
- Tus claves, con su prefijo, sus permisos, el último uso y si están activas.
- Nuevo webhook: para que Recua avise a tu programa cuando pasa algo.
Cuándo usar cada cosa
- API (tu programa pregunta): tu ERP necesita la lista de portes o crear portes. Usa una API key.
- Webhooks (Recua avisa): quieres enterarte en tu sistema cuando un porte se asigna, se firma o se entrega. Usa un webhook.
Si solo quieres ver datos en otra herramienta, sin conexión en directo, exporta un CSV desde Analítica: es más sencillo.
Crear una API key
- Pulsa Nueva API key.
- Ponle un nombre que diga qué programa la usa.
- Marca los permisos.
- Pulsa Generar.
- Nombre: por ejemplo «ERP Sage 50» o «Power BI».
- Permisos:
portes:read(leer portes, marcado de serie) yportes:write(crear portes). Si necesitas otros (clientes, facturas), pídenoslo. - Pulsa Generar.
Al generarla, Recua te enseña el token completo UNA SOLA VEZ, algo como
ta_a1b2c3d4e5f6_<44 caracteres>, con un botón Copiar. Guárdalo en tu
gestor de secretos: Recua solo guarda una huella, así que si lo pierdes no
se puede recuperar y hay que generar otra.
Usar la API
Pasa la key en la cabecera Authorization: Bearer <token>:
curl -H "Authorization: Bearer ta_..." \
https://recua.app/api/v1/portes?desde=2026-05-01
Endpoints:
GET /api/v1/portes: lista los portes de tu empresa, los más recientes primero. Filtros:estado,desdeyhasta(sobre la fecha de carga) ylimit(50 por defecto, hasta 200).GET /api/v1/portes/{id}: el detalle de un porte, con conductor, cargador, destinatario, vehículo, sus eventos y las reservas (las observaciones sobre el estado de la mercancía, art. 8 del Convenio CMR).POST /api/v1/portes: crea un porte (necesitaportes:write). Son obligatoriosconductor_idy el peso:peso_bruto_kgo, si la mercancía no se puede pesar,volumen_m3(es dato obligatorio del documento de control).cargador_id,destinatario_idyvehiculo_idson opcionales, pero si los mandas tienen que ser de tu empresa. Si el vehículo circula con autorización especial, manda su número enautorizacion_especial.
Respuestas en JSON. Errores:
401: falta la cabecera, el token no tiene el formato o está revocado.402: tu empresa no puede operar ahora (prueba terminada o suscripción impagada o cancelada). Solo bloquea crear portes; leer sigue funcionando.403: el token no tiene el permiso que hace falta.404: el porte no existe o no es de tu empresa.422: falta el peso al crear un porte.
Revocar una API key
Si crees que la key se ha filtrado, o el programa que la usaba ya no
funciona, pulsa Revocar en su fila. Deja de valer al momento: las
siguientes llamadas dan 401. No se puede deshacer; si la necesitas,
genera otra.
Las revocadas siguen en la lista con la etiqueta Revocada, para que quede constancia de las claves que ha tenido la empresa.
Crear un webhook
- Pulsa Nuevo webhook.
- Escribe la URL de tu sistema.
- Marca los eventos que te interesan.
- Pulsa Crear webhook.
- URL de tu sistema (http o https). Tiene que ser pública: Recua no llama a
localhost, a direcciones privadas (192.168.x,10.x.x.x...) ni a las de metadatos de la nube. - Eventos suscritos:
porte.creado,porte.asignado,porte.cargando,porte.en_ruta,porte.descargando,porte.firmado,porte.entregado,porte.incidenciayporte.cancelado. - Pulsa Crear webhook.
Al crearlo, Recua te enseña el secret del webhook (empieza por
whsec_) una sola vez. Guárdalo: con él compruebas que cada aviso
viene de Recua (ver abajo).
Un webhook no se edita. Para cambiar la URL o los eventos, elimínalo y crea otro.
- El estado: Activo o Pausado. En Último envío ves la fecha y el código que devolvió tu servidor.
- Pausar o Reactivar: para los avisos sin borrar el webhook. Al lado, Eliminar lo borra.
porte.firmado llega más de una vez
Un porte lanza porte.firmado en cada firma: conductor en la recogida,
cargador, conductor en la entrega. El campo campo del mensaje dice cuál
fue.
Qué trae cada aviso
{
"evento": "porte.entregado",
"enviado_at": "2026-08-03T10:00:00.000Z",
"data": { "porte_id": "...", "campo": "firma_destinatario" }
}
El contenido de data cambia según el evento y de dónde venga: si viene de
POST /api/v1/portes trae el porte completo; si viene de una firma o de un
cambio de estado trae, como mínimo, porte_id.
Comprobar la firma del webhook
Recua manda la cabecera X-Recua-Signature con este formato:
t=<timestamp>,v1=<hmac>
Tu servidor:
- Lee
timestampyhmacde la cabecera. - Calcula
HMAC-SHA256(secret, timestamp + "." + body). - Si no coincide con
hmac, rechaza el aviso: no viene de Recua. - Si el
timestamptiene más de 5 minutos, recházalo también (evita que te reenvíen un aviso viejo).
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();
Sin reintentos
Recua intenta cada aviso una sola vez, con 5 segundos de margen. Si tu
servidor no contesta o devuelve un error, no se repite: solo se apuntan la
fecha y el código en Último envío. Contesta rápido con un 2xx y, si
tienes que hacer algo lento, déjalo en una cola y contesta enseguida.
Errores habituales
- «Último envío» tiene fecha pero ningún código: Recua no llegó a recibir respuesta. La URL estaba bloqueada (dirección privada), no se encontró el dominio, o tu servidor no contestó en 5 segundos o rechazó la conexión.
- El código sale en rojo: tu servidor contestó con un error (4xx o
5xx). Ese aviso no se repite: corrige tu servidor o consulta el porte con
GET /api/v1/portes/{id}. - Falta un aviso: como no hay reintentos, un fallo puntual de tu servidor lo pierde. Si no te lo puedes permitir, usa el webhook como señal para ir a buscar el estado real por la API.
¿Necesitas un permiso, un evento o un endpoint que no existe (clientes, facturas, cambiar un porte por API)? Cuéntanoslo en hola@recua.app.




