Workflows
Automatizaciones alimentadas por los mismos eventos que disparan los webhooks. Define el grafo en JSON (o dibújalo en el editor visual del panel), nosotros lo ejecutamos con historial por nodo.
Modelo de un workflow
Un workflow tiene un trigger (manual, cron o evento) y un
grafo de nodos conectados por aristas en
definicion. Cada nodo persiste su input y output para que
puedas depurar la ejecución paso a paso.
{
"id": 42,
"nombre": "Notificar cuando se autoriza una factura",
"descripcion": null,
"activo": true,
"trigger_tipo": "evento",
"evento": "factura.autorizada",
"cron_expr": null,
"definicion": {
"nodes": [
{ "id": "t1", "type": "trigger.evento", "data": {} },
{
"id": "n1",
"type": "action.http",
"data": {
"method": "POST",
"url": "https://hooks.example.com/notificar",
"headers": { "Content-Type": "application/json" },
"body_template": { "mensaje": "Factura autorizada" }
}
}
],
"edges": [{ "source": "t1", "target": "n1" }]
},
"created_at": "2026-07-03T10:00:00",
"updated_at": "2026-07-03T10:00:00"
}Autenticación
Authorization: Bearer). Las API keys
(X-API-Key) están acotadas a comprobantes, clientes,
servicios, sucursales y eventos — no acceden a /workflows.
Tipos de trigger (trigger_tipo)
| Parámetro | Tipo | Descripción |
|---|---|---|
manual optional | string | Se ejecuta al llamar a POST /workflows/{id}/run. |
schedule optional | string | Programado por cron (campo cron_expr, sintaxis crontab de 5 campos, hora de Ecuador). Ej: '0 */6 * * *' = cada 6 horas. |
evento optional | string | Se dispara con un evento interno (campo evento). Catálogo: factura.creada/autorizada/rechazada/devuelta y sus equivalentes guia.* y retencion.*. Lista completa en GET /workflows/eventos. |
Tipos de nodo
El catálogo vivo (con los inputs de configuración de cada nodo) está en
GET /api/v1/workflows/nodos.
| Parámetro | Tipo | Descripción |
|---|---|---|
trigger.manual optional | trigger | Nodo de entrada para ejecuciones manuales (POST /run). |
trigger.schedule optional | trigger | Nodo de entrada para workflows programados por cron. |
trigger.evento optional | trigger | Nodo de entrada para workflows disparados por evento. |
action.http optional | acción | Llama a un endpoint HTTP externo (GET/POST/PUT/PATCH/DELETE) con headers y body configurables. Las URLs a redes internas se bloquean (anti-SSRF). |
action.webhook optional | acción | POST saliente con firma HMAC SHA-256 opcional (header X-Emitoo-Signature) y etiqueta de evento (X-Emitoo-Event). |
action.email optional | acción | Envía un correo usando el SMTP configurado de tu empresa. |
action.buscar optional | datos | Busca registros del tenant: personas/empresas, servicios, facturas, guías de remisión o retenciones. Devuelve {entidad, total, registros}. |
action.log optional | acción | Devuelve sus inputs como output. Útil para depurar el flujo. |
branch.if optional | lógica | Evalúa una condición (campo, operador, valor) sobre el payload y sigue la arista 'true' o 'false' (sourceHandle de la arista). |
transform optional | lógica | Mapea campos del input a un nuevo output ({destino: ruta-origen}), sin ejecutar código. |
Listar workflows
GET /api/v1/workflows — Lista los workflows de tu empresa
Crear un workflow
POST /api/v1/workflows — Crea un workflow a partir de un grafo
Body
| Parámetro | Tipo | Descripción |
|---|---|---|
nombre required | string | Nombre legible. Máx 160 caracteres. |
trigger_tipo required | string | 'manual', 'schedule' o 'evento'. |
cron_expr optional | string | Solo para trigger_tipo='schedule'. Crontab de 5 campos. |
evento optional | string | Solo para trigger_tipo='evento'. Nombre del evento (ej: 'factura.autorizada'). |
definicion optional | object | Grafo del workflow: { nodes: [{id, type, data}], edges: [{source, target, sourceHandle?}] }. Es el formato del editor visual (React Flow). |
descripcion optional | string | Descripción opcional. |
activo optional | boolean | Si false, el workflow se guarda pero no se ejecuta. Default: true. |
curl -X POST https://api.emitoo.io/api/v1/workflows \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"nombre": "Notificar facturas autorizadas",
"trigger_tipo": "evento",
"evento": "factura.autorizada",
"definicion": {
"nodes": [
{ "id": "t1", "type": "trigger.evento", "data": {} },
{
"id": "n1",
"type": "action.http",
"data": {
"method": "POST",
"url": "https://hooks.example.com/notificar"
}
}
],
"edges": [{ "source": "t1", "target": "n1" }]
}
}'Obtener / actualizar / eliminar
GET /api/v1/workflows/[id] — Devuelve un workflow con su definición
PUT /api/v1/workflows/[id] — Actualiza nombre, trigger, definición o estado activo
DELETE /api/v1/workflows/[id] — Borra el workflow y su historial
Ejecutar manualmente
POST /api/v1/workflows/[id]/run — Ejecuta el workflow y devuelve el run terminado (202)
Body
| Parámetro | Tipo | Descripción |
|---|---|---|
payload optional | object | Payload inicial que recibe el nodo trigger del grafo. |
curl -X POST https://api.emitoo.io/api/v1/workflows/42/run \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "payload": { "numero": "001-001-000000123" } }'Historial de ejecuciones
GET /api/v1/workflows/[id]/runs — Ejecuciones pasadas, más recientes primero (param limit, máx 50 por defecto)
GET /api/v1/workflows/runs/[run_id] — Detalle de un run, con input/output por nodo
Cada run incluye: estado (running, completed,
failed), payload del trigger, y por cada nodo su input,
output, error y duración en milisegundos.
Catálogos
GET /api/v1/workflows/nodos — Catálogo de tipos de nodo con sus inputs de configuración
GET /api/v1/workflows/eventos — Catálogo de eventos disponibles (filtro opcional ?documento=factura)
Cómo fluye el payload
action.http y action.webhook, si no
defines body_template se envía el input recibido tal cual;
si lo defines, se envía ese objeto literal.