---
title: "Workflow: API da plataforma"
description: "API da plataforma APIBrasil (Encadeamento de consultas em lote). Os endpoints abaixo são os da conta e da operação do gateway."
lang: pt-BR
canonical: https://doc.apibrasil.io/apis/plataforma/workflow
markdown: https://doc.apibrasil.io/apis/plataforma/workflow.md
source: apibrasil-documentation
---

# Workflow: API da plataforma

> API da plataforma APIBrasil (Encadeamento de consultas em lote). Os endpoints abaixo são os da conta e da operação do gateway.

- **Especificação OpenAPI:** https://doc.apibrasil.io/apis/plataforma/workflow/openapi.json

## Como chamar

**Endereço base:** `https://gateway.apibrasil.io/api/v2`

Com `homolog: true` no corpo, o gateway responde de uma base fixa, com a forma real da resposta, e não cobra. O CPF 00000000000 é dessa base e não é de ninguém: use-o nos testes, nunca em produção.

## Endpoints (39 endpoints)

**Sumário**

*Execução*

1. `POST /workflow` — Simular o lote (valida-workflow)
2. `POST /workflow` — Executar um lote simples (cria-workflow)
3. `POST /workflow` — Executar uma cadeia de etapas (cria-workflow com nodes)
4. `POST /workflow` — Executar um flow salvo (cria-workflow com flow_id)
5. `POST /workflow` — Acompanhar a execução (checa-workflow)
6. `GET /workflow/execucoes` — Listar as execuções da conta
7. `GET /workflow/{workflow}/corpo` — O corpo que cada etapa enviou ao fornecedor
8. `GET /workflow/{workflow}/relatorio/{node}` — Baixar o relatório em PDF de uma etapa
9. `GET /workflow/callback-secret` — O segredo que assina os seus callbacks
10. `GET /workflow/limites` — Consultar o teto de execuções simultâneas
11. `PUT /workflow/limites` — Ajustar o teto de execuções simultâneas

*Etapas da cadeia (nodes)*

12. `POST /workflow` — Etapa de consulta (kind: query)
13. `POST /workflow` — Etapa de variável (kind: variable)
14. `POST /workflow` — Etapa de condição (kind: condition)
15. `POST /workflow` — Etapa de validação de documento (kind: validate)
16. `POST /workflow` — Etapa de transformação (kind: transform)
17. `POST /workflow` — Etapa de CEP (kind: cep)
18. `POST /workflow` — Etapa de webhook (kind: webhook)
19. `POST /workflow` — Etapa de parada (kind: stop)
20. `POST /workflow` — Etapa de análise por IA (kind: ai)
21. `POST /workflow` — Etapa de relatório em PDF (kind: pdf)

*Flows salvos*

22. `GET /flows` — Listar flows
23. `POST /flows` — Salvar um flow
24. `GET /flows/{flow}` — Ver um flow
25. `PUT /flows/{flow}` — Editar um flow
26. `DELETE /flows/{flow}` — Apagar um flow
27. `POST /flows/{flow}/clonar` — Clonar um flow
28. `GET /flows/{flow}/execucoes` — Execuções de um flow

*Gatilhos (webhook de entrada)*

29. `GET /flows/{flow}/triggers` — Listar os gatilhos de um flow
30. `POST /flows/{flow}/triggers` — Criar um gatilho de webhook
31. `PUT /flows/{flow}/triggers/{trigger}` — Editar um gatilho
32. `DELETE /flows/{flow}/triggers/{trigger}` — Apagar um gatilho
33. `GET /flows/{flow}/triggers/{trigger}/segredo` — Ler o segredo e o comando de teste
34. `POST /flows/{flow}/triggers/{trigger}/rotacionar-segredo` — Rotacionar o segredo
35. `POST /flows/{flow}/triggers/{trigger}/testar` — Testar um gatilho
36. `POST /hooks/{slug}` — Disparar o flow pelo webhook (chamado pelo seu sistema)

*Callbacks (o gateway chama a sua URL)*

37. `POST /{callback_url}` — Evento workflow.finalizado (enviado ao seu callback_url)
38. `POST /{callback_url}` — Evento node.dispatched (callback_url da etapa)
39. `POST /{callback_url}` — Evento node.finalizado (callback_url da etapa)

### 1. POST /workflow — Simular o lote (valida-workflow)

Dry-run: responde o que cada consulta precisa, o que está faltando, o preço de cada uma e se o saldo cobre — sem cobrar e sem enfileirar nada. Sempre HTTP 200, inclusive quando o lote é inválido: valid=false é uma resposta, não um erro. Aceita o mesmo corpo do cria-workflow (queries, nodes ou flow_id). Envie inputs vazio ({}) para descobrir quais campos as consultas exigem (status missing_inputs traz o nome exato de cada campo). Status possíveis por consulta: ok, missing_inputs, invalid_input, not_found, no_access, maintenance, duplicated, unknown_requirements (avisa e não bloqueia), pending_upstream (vem de etapa anterior), invalid_mapping, homolog_unavailable, plan_mode_unsupported.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "valida-workflow",
  "inputs": {
    "cpf": "12345678909",
    "placa": "ABC1D23"
  },
  "queries": [
    "dados-cadastrais",
    "fipe",
    "debitos-v4"
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"valida-workflow","inputs":{"cpf":"12345678909","placa":"ABC1D23"},"queries":["dados-cadastrais","fipe","debitos-v4"]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "valid": false,
    "resumo": {
      "total": 3,
      "executaveis": 2,
      "bloqueadas": 1,
      "custo_estimado": 1.2,
      "saldo_disponivel": 57.4,
      "saldo_suficiente": true
    },
    "queries": [
      {
        "service": "dados-cadastrais",
        "status": "ok",
        "price": 0.7,
        "billing_mode": "credit",
        "usa": [
          "cpf"
        ]
      },
      {
        "service": "fipe",
        "status": "ok",
        "price": 0.5,
        "billing_mode": "credit",
        "usa": [
          "placa"
        ]
      },
      {
        "service": "debitos-v4",
        "status": "missing_inputs",
        "price": 0.9,
        "billing_mode": "credit",
        "missing": [
          [
            "placa",
            "renavam"
          ],
          [
            "chassi"
          ]
        ],
        "message": "Informe 'renavam' (junto com 'placa') ou 'chassi'."
      }
    ]
  }
}
```

### 2. POST /workflow — Executar um lote simples (cria-workflow)

Enfileira até 10 consultas sobre os mesmos inputs e devolve HTTP 202 com o workflow_id. O gateway revalida tudo antes de aceitar, reserva o custo estimado do saldo e libera o que não for usado ao final. Consulta que falhar não é cobrada (até 3 tentativas). strict=true recusa o lote inteiro (422) se qualquer consulta estiver bloqueada; sem strict, as bloqueadas são ignoradas e as demais rodam. homolog=true roda em sandbox, sem cobrar, nos serviços que oferecem homologação. callback_url recebe um POST assinado quando a execução terminar (ver Callbacks). O header Idempotency-Key evita executar duas vezes o mesmo pedido: a repetição devolve 200 com reaproveitado=true e o mesmo workflow_id. Erros: 402 insufficient_balance (com custo_estimado e saldo_disponivel), 422 grafo inválido, 429 too_many_inflight (acima de 5 execuções simultâneas).

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |
| `Idempotency-Key` | `pedido-8731` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909",
    "placa": "ABC1D23"
  },
  "queries": [
    "dados-cadastrais",
    "fipe"
  ],
  "strict": false,
  "homolog": false,
  "callback_url": "https://meusistema.com.br/webhooks/apibrasil"
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -H "Idempotency-Key: pedido-8731" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909","placa":"ABC1D23"},"queries":["dados-cadastrais","fipe"],"strict":false,"homolog":false,"callback_url":"https://meusistema.com.br/webhooks/apibrasil"}'
```

Este endpoint aceita `homolog: true` no corpo: a resposta volta com dados válidos, `api_limit_for` igual a `homolog` e sem tarifação.

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 2,
      "ignorados": 0
    },
    "total_nodes": 1,
    "custo_reservado": 1.2,
    "custo_e_teto": false,
    "saldo_disponivel": 56.2,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  },
  "402": {
    "error": true,
    "motivo": "insufficient_balance",
    "message": "Saldo insuficiente para reservar o custo do workflow.",
    "custo_estimado": 1.2,
    "custo_e_teto": false,
    "saldo_disponivel": 0.4
  },
  "429": {
    "error": true,
    "motivo": "too_many_inflight",
    "message": "Você já tem 5 workflows em execução. Aguarde algum terminar."
  }
}
```

### 3. POST /workflow — Executar uma cadeia de etapas (cria-workflow com nodes)

Em vez de queries no topo, envie nodes[]: até 8 etapas, executadas NA ORDEM DO ARRAY, com até 10 consultas cada e 40 no total. Uma etapa lê o retorno de uma anterior por inputs_from: campo → {node, service, path}, onde path é caminho de ponto no retorno do fornecedor (ex.: data.renavam). Referência para frente é recusada (422). on_error diz o que fazer quando a etapa anterior falha: if_mapped (padrão — pula só se dependia dela), stop, continue ou stop_if_all_failed. Numa cadeia o custo reservado é um TETO (custo_e_teto=true): etapa pulada devolve a reserva. nodes e flow_id são mutuamente exclusivos. Cada node aceita ainda homolog, params (corpo extra da consulta), device_id (mensageria) e callback_url próprio (eventos node.dispatched e node.finalizado). O custo total é limitado a R$ 250,00 por execução.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |
| `Idempotency-Key` | `lote-veiculo-4471` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "placa": "ABC1D23"
  },
  "nodes": [
    {
      "id": "placa",
      "queries": [
        "fipe"
      ]
    },
    {
      "id": "debitos",
      "queries": [
        "debitos-v4"
      ],
      "inputs_from": {
        "renavam": {
          "node": "placa",
          "service": "fipe",
          "path": "data.renavam"
        }
      },
      "on_error": "if_mapped"
    }
  ],
  "callback_url": "https://meusistema.com.br/webhooks/apibrasil"
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -H "Idempotency-Key: lote-veiculo-4471" \
  -d '{"tipo":"cria-workflow","inputs":{"placa":"ABC1D23"},"nodes":[{"id":"placa","queries":["fipe"]},{"id":"debitos","queries":["debitos-v4"],"inputs_from":{"renavam":{"node":"placa","service":"fipe","path":"data.renavam"}},"on_error":"if_mapped"}],"callback_url":"https://meusistema.com.br/webhooks/apibrasil"}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 2,
      "ignorados": 0
    },
    "total_nodes": 2,
    "custo_reservado": 1.4,
    "custo_e_teto": true,
    "saldo_disponivel": 56,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  },
  "422": {
    "error": true,
    "motivo": "invalid_mapping",
    "message": "O mapeamento de 'renavam' no node 'debitos' aponta para 'placa', que não vem antes dele.",
    "contexto": {
      "node": "debitos",
      "campo": "renavam"
    }
  }
}
```

### 4. POST /workflow — Executar um flow salvo (cria-workflow com flow_id)

Executa a receita salva em /flows com os inputs desta chamada. A execução de um flow é SEMPRE estrita: se qualquer consulta da receita estiver bloqueada (saiu do catálogo, sem acesso, em manutenção), a chamada é recusada com 422 em vez de executar pela metade. O callback_url da chamada tem precedência sobre o salvo no flow. A resposta traz flow_id e flow_version, para o extrato dizer qual versão da receita rodou. Os campos exigidos estão em required_inputs do flow.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
  "inputs": {
    "cpf": "12345678909"
  }
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","flow_id":"8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02","inputs":{"cpf":"12345678909"}}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 3,
      "ignorados": 0
    },
    "total_nodes": 3,
    "custo_reservado": 2.1,
    "custo_e_teto": true,
    "saldo_disponivel": 55.3,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 5. POST /workflow — Acompanhar a execução (checa-workflow)

Polling. workflow_id aceita uma string (resposta plana) ou um array de até 20 ids (resposta em {error, data: [...]}). Status do workflow: queued, running, completed, partial (alguma consulta falhou ou foi pulada) ou failed. Cada node traz progresso próprio e resultados: um objeto por serviço, com status (queued, running, success, failed, skipped), price cobrado, tentativas, duracao_ms, data (o retorno do fornecedor) ou error. Consulta pulada informa skip_reason (missing_inputs, invalid_input, not_found, no_access, maintenance, duplicated, upstream_failed, upstream_missing_field, condition_false, declared_stop). Workflow de outra conta responde 404. Recomendação: consulte a cada 3 a 5 segundos ou use callback_url.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "checa-workflow",
  "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01"
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"checa-workflow","workflow_id":"9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01"}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "completed",
    "progresso": {
      "total": 2,
      "concluidos": 2,
      "falhas": 0,
      "ignorados": 0,
      "pendentes": 0,
      "percentual": 100
    },
    "custo": {
      "reservado": 1.4,
      "cobrado": 1.2,
      "liberado": 0.2
    },
    "total_nodes": 2,
    "custo_e_teto": true,
    "criado_em": "2026-09-05T09:00:00-03:00",
    "finalizado_em": "2026-09-05T09:00:07-03:00",
    "duracao_segundos": 7,
    "nodes": [
      {
        "id": "placa",
        "position": 1,
        "kind": "query",
        "status": "completed",
        "skip_reason": null,
        "on_error": "if_mapped",
        "homolog": false,
        "progresso": {
          "total": 1,
          "concluidos": 1,
          "falhas": 0,
          "ignorados": 0,
          "pendentes": 0,
          "percentual": 100
        },
        "resultados": {
          "fipe": {
            "status": "success",
            "price": 0.5,
            "tentativas": 1,
            "tentativas_max": 3,
            "tentativas_label": "1/3",
            "iniciado_em": "2026-09-05T09:00:01-03:00",
            "finalizado_em": "2026-09-05T09:00:03-03:00",
            "duracao_ms": 1840,
            "data": {
              "renavam": "00123456789",
              "marca": "FIAT",
              "modelo": "ARGO 1.0",
              "valor": "R$ 62.000,00"
            }
          }
        }
      },
      {
        "id": "debitos",
        "position": 2,
        "kind": "query",
        "status": "completed",
        "skip_reason": null,
        "on_error": "if_mapped",
        "homolog": false,
        "progresso": {
          "total": 1,
          "concluidos": 1,
          "falhas": 0,
          "ignorados": 0,
          "pendentes": 0,
          "percentual": 100
        },
        "resultados": {
          "debitos-v4": {
            "status": "success",
            "price": 0.7,
            "tentativas": 1,
            "tentativas_max": 3,
            "tentativas_label": "1/3",
            "iniciado_em": "2026-09-05T09:00:04-03:00",
            "finalizado_em": "2026-09-05T09:00:07-03:00",
            "duracao_ms": 2910,
            "data": {
              "total_debitos": 0,
              "restricoes": []
            }
          }
        }
      }
    ]
  },
  "404": {
    "error": true,
    "message": "Workflow não encontrado."
  }
}
```

### 6. GET /workflow/execucoes — Listar as execuções da conta

Todas as execuções do usuário, com ou sem flow, paginadas. Query string: page, per_page (até 100), q (busca por id, serviço ou nome do flow), sort (criado_em, status, custo_cobrado) e dir (asc|desc). Cada item tem a mesma forma do checa-workflow, sem os resultados detalhados.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/execucoes`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/workflow/execucoes" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "data": [
      {
        "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
        "status": "completed",
        "total_nodes": 2,
        "custo": {
          "reservado": 1.4,
          "cobrado": 1.2,
          "liberado": 0.2
        },
        "criado_em": "2026-09-05T09:00:00-03:00",
        "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
        "flow_version": 3
      }
    ],
    "meta": {
      "page": 1,
      "per_page": 25,
      "total": 1,
      "last_page": 1
    }
  }
}
```

### 7. GET /workflow/{workflow}/corpo — O corpo que cada etapa enviou ao fornecedor

Reconstrói, etapa a etapa, o corpo exato com que cada consulta foi chamada — os inputs da chamada mais o que veio por inputs_from e params. Fica fora do polling de propósito, porque é dado pessoal e o checa-workflow roda a cada poucos segundos. Use para depurar por que uma consulta respondeu diferente do esperado.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/{workflow}/corpo`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/workflow/{workflow}/corpo" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "etapas": [
      {
        "id": "placa",
        "position": 1,
        "servicos": [
          "fipe"
        ],
        "corpo": {
          "placa": "ABC1D23"
        },
        "corpo_por_consulta": {
          "fipe": {
            "placa": "ABC1D23"
          }
        },
        "mapeamentos": null,
        "homolog": false,
        "device_id": null
      },
      {
        "id": "debitos",
        "position": 2,
        "servicos": [
          "debitos-v4"
        ],
        "corpo": {
          "placa": "ABC1D23",
          "renavam": "00123456789"
        },
        "corpo_por_consulta": {
          "debitos-v4": {
            "placa": "ABC1D23",
            "renavam": "00123456789"
          }
        },
        "mapeamentos": {
          "renavam": {
            "node": "placa",
            "service": "fipe",
            "path": "data.renavam"
          }
        },
        "homolog": false,
        "device_id": null
      }
    ]
  }
}
```

### 8. GET /workflow/{workflow}/relatorio/{node} — Baixar o relatório em PDF de uma etapa

Devolve o arquivo (Content-Type: application/pdf) gerado por uma etapa kind=pdf; {node} é o id da etapa na cadeia. É um LINK DE CAPACIDADE, sem token: a URL sai no recibo da etapa e no callback de conclusão e abre direto no navegador (<a href>), onde não há header de autorização. O que protege o acesso é o id do workflow (UUID v4, impossível de enumerar) e a retenção: passado o prazo, o link morre sozinho. Trate a URL como credencial — quem a tiver lê o documento, que carrega o que a cadeia consultou; não a repasse em logs nem em webhooks para terceiros. 404, sem distinguir o caso, quando o workflow não existe, a etapa não é de PDF, o arquivo não chegou a ser gerado ou já expirou (o recibo no checa-workflow continua disponível).

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/{workflow}/relatorio/{node}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Accept` | `application/pdf` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/workflow/{workflow}/relatorio/{node}" \
  -H "Accept: application/pdf"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "_binario": "application/pdf"
  },
  "404": {
    "error": true,
    "message": "Esta execução não tem uma etapa de relatório com esse identificador."
  }
}
```

### 9. GET /workflow/callback-secret — O segredo que assina os seus callbacks

O segredo, por conta, com que o gateway assina cada POST enviado ao seu callback_url (workflow.finalizado, node.dispatched, node.finalizado). É estável: pode ser lido quantas vezes precisar. Valide a assinatura calculando HMAC-SHA256 do corpo cru com este segredo e comparando com o header X-APIBrasil-Signature em tempo constante (hash_equals). O header pode vir com ou sem o prefixo sha256=.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/callback-secret`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/workflow/callback-secret" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "secret": "whsec_0f3a9c…",
    "header": "X-APIBrasil-Signature",
    "algoritmo": "HMAC-SHA256 sobre o corpo cru da requisição",
    "aviso": "Compare com hash_equals (comparação constante). A assinatura pode vir com ou sem o prefixo 'sha256='."
  }
}
```

### 10. GET /workflow/limites — Consultar o teto de execuções simultâneas

Quantas execuções podem estar em andamento ao mesmo tempo nesta conta, quantas estão agora e até onde o próprio cliente pode subir o teto (20). Acima disso é pedido ao suporte.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/limites`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/workflow/limites" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "max_inflight": 5,
    "padrao": 5,
    "maximo_ajustavel": 20,
    "em_execucao": 1,
    "acima_do_ajustavel": false
  }
}
```

### 11. PUT /workflow/limites — Ajustar o teto de execuções simultâneas

max_inflight inteiro entre 1 e 20. A resposta é a mesma do GET, já com o valor novo. Execuções acima do teto recebem 429 too_many_inflight no cria-workflow.

- **Método:** `PUT`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow/limites`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "max_inflight": 10
}
```

**Em cURL**

```bash
curl -X PUT "https://gateway.apibrasil.io/api/v2/workflow/limites" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"max_inflight":10}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "max_inflight": 10,
    "padrao": 5,
    "maximo_ajustavel": 20,
    "em_execucao": 1,
    "acima_do_ajustavel": false
  },
  "422": {
    "error": true,
    "message": "O máximo que dá para ajustar por aqui é 20 execuções simultâneas. Para mais que isso, fale com o suporte."
  }
}
```

### 12. POST /workflow — Etapa de consulta (kind: query)

A etapa padrão — kind pode ser omitido. Lista em queries os serviços do catálogo (o service_name usado em /consulta/{service}) que rodam em paralelo sobre os mesmos inputs. É a única etapa que vira item cobrado, junto com ai e pdf. Campos: id (até 40 caracteres, opcional — sem ele o gateway gera n1, n2…), queries, inputs_from, on_error, homolog, params (campos extras enviados ao fornecedor, até 20 chaves), device_id (o dispositivo de mensageria de onde a etapa sai) e callback_url (eventos de ciclo de vida desta etapa).

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "kind": "query",
      "queries": [
        "dados-cadastrais",
        "score-serasa"
      ],
      "on_error": "if_mapped",
      "homolog": false,
      "params": {
        "detalhado": true
      },
      "callback_url": "https://meusistema.com.br/webhooks/etapa"
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","kind":"query","queries":["dados-cadastrais","score-serasa"],"on_error":"if_mapped","homolog":false,"params":{"detalhado":true},"callback_url":"https://meusistema.com.br/webhooks/etapa"}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 1,
    "custo_reservado": 1.9,
    "custo_e_teto": false,
    "saldo_disponivel": 55.5,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 13. POST /workflow — Etapa de variável (kind: variable)

Captura UM valor escalar do retorno de uma etapa anterior e o publica como {{nome}}, para ser interpolado nos params das etapas seguintes. Ferramenta: não cobra, não vira item e não conta no teto de consultas. tool_config: nome (o identificador da variável) e de {node, service, path}. A origem precisa vir antes.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "nome_cliente",
      "kind": "variable",
      "tool_config": {
        "nome": "nome",
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais",
          "path": "data.nome"
        }
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"nome_cliente","kind":"variable","tool_config":{"nome":"nome","de":{"node":"consulta","service":"dados-cadastrais","path":"data.nome"}}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 2,
    "custo_reservado": 0.7,
    "custo_e_teto": true,
    "saldo_disponivel": 56.7,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 14. POST /workflow — Etapa de condição (kind: condition)

Compara um campo do retorno anterior com um valor e decide por onde a cadeia segue. tool_config: de {node, service, path}, operador (igual, diferente, maior, menor, existe, vazio), valor (obrigatório, exceto em existe/vazio) e senao — o id de uma etapa POSTERIOR para onde pular quando a condição for falsa. Sem senao, condição falsa encerra a cadeia: as etapas seguintes viram skipped com skip_reason condition_false e a reserva delas é devolvida. Ferramenta: não cobra.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "so_se_ativo",
      "kind": "condition",
      "tool_config": {
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais",
          "path": "data.situacao"
        },
        "operador": "igual",
        "valor": "REGULAR",
        "senao": "aviso"
      }
    },
    {
      "id": "score",
      "queries": [
        "score-serasa"
      ]
    },
    {
      "id": "aviso",
      "kind": "webhook",
      "tool_config": {
        "url": "https://meusistema.com.br/hooks/cpf-irregular"
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"so_se_ativo","kind":"condition","tool_config":{"de":{"node":"consulta","service":"dados-cadastrais","path":"data.situacao"},"operador":"igual","valor":"REGULAR","senao":"aviso"}},{"id":"score","queries":["score-serasa"]},{"id":"aviso","kind":"webhook","tool_config":{"url":"https://meusistema.com.br/hooks/cpf-irregular"}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 4,
    "custo_reservado": 1.9,
    "custo_e_teto": true,
    "saldo_disponivel": 55.5,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 15. POST /workflow — Etapa de validação de documento (kind: validate)

Confere documentos LOCALMENTE (dígito verificador e formato) antes de gastar consulta com eles. Tipos: cpf, cnpj, cep, cnh, rg, renavam, chassi, placa. tool_config: de {node, service} (a origem dos campos), documentos [{tipo, path}] e senao (id de etapa posterior para onde pular se algum reprovar; sem senao a cadeia para). Ferramenta: não cobra. Use como primeira etapa lendo os inputs da chamada para barrar CPF ou placa inválidos antes da primeira consulta.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909",
    "placa": "ABC1D23"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "portao",
      "kind": "validate",
      "tool_config": {
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais"
        },
        "documentos": [
          {
            "tipo": "cpf",
            "path": "data.cpf"
          },
          {
            "tipo": "cnpj",
            "path": "data.empregador.cnpj"
          }
        ],
        "senao": ""
      }
    },
    {
      "id": "veiculo",
      "queries": [
        "fipe"
      ]
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909","placa":"ABC1D23"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"portao","kind":"validate","tool_config":{"de":{"node":"consulta","service":"dados-cadastrais"},"documentos":[{"tipo":"cpf","path":"data.cpf"},{"tipo":"cnpj","path":"data.empregador.cnpj"}],"senao":""}},{"id":"veiculo","queries":["fipe"]}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 3,
    "custo_reservado": 1.2,
    "custo_e_teto": true,
    "saldo_disponivel": 56.2,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 16. POST /workflow — Etapa de transformação (kind: transform)

Reescreve o retorno de uma etapa anterior na forma que a próxima espera, sem sair da máquina: renomeia chaves e limpa pontuação. tool_config: de {node, service} e campos [{para, path}] — cada campo produzido fica disponível em data.{para}, e a etapa seguinte o lê por inputs_from com service "transform". Ferramenta: não cobra.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "123.456.789-09"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "limpa",
      "kind": "transform",
      "tool_config": {
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais"
        },
        "campos": [
          {
            "para": "cpf_limpo",
            "path": "data.cpf"
          },
          {
            "para": "nome",
            "path": "data.nome"
          }
        ]
      }
    },
    {
      "id": "score",
      "queries": [
        "score-serasa"
      ],
      "inputs_from": {
        "cpf": {
          "node": "limpa",
          "service": "transform",
          "path": "data.cpf_limpo"
        }
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"123.456.789-09"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"limpa","kind":"transform","tool_config":{"de":{"node":"consulta","service":"dados-cadastrais"},"campos":[{"para":"cpf_limpo","path":"data.cpf"},{"para":"nome","path":"data.nome"}]}},{"id":"score","queries":["score-serasa"],"inputs_from":{"cpf":{"node":"limpa","service":"transform","path":"data.cpf_limpo"}}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 3,
    "custo_reservado": 1.9,
    "custo_e_teto": true,
    "saldo_disponivel": 55.5,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 17. POST /workflow — Etapa de CEP (kind: cep)

Deriva UF e região de um CEP pela faixa dos Correios, sem consulta paga. Não devolve cidade nem logradouro — para isso continue usando a consulta de CEP do catálogo. tool_config: de {node, service, path} apontando para o campo com o CEP. A saída fica em data.uf, data.regiao e data.valido, lida por inputs_from ou por uma condição com service "cep". Ferramenta: não cobra.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "estado",
      "kind": "cep",
      "tool_config": {
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais",
          "path": "data.endereco.cep"
        }
      }
    },
    {
      "id": "so_sp",
      "kind": "condition",
      "tool_config": {
        "de": {
          "node": "estado",
          "service": "cep",
          "path": "data.uf"
        },
        "operador": "igual",
        "valor": "SP"
      }
    },
    {
      "id": "score",
      "queries": [
        "score-serasa"
      ]
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"estado","kind":"cep","tool_config":{"de":{"node":"consulta","service":"dados-cadastrais","path":"data.endereco.cep"}}},{"id":"so_sp","kind":"condition","tool_config":{"de":{"node":"estado","service":"cep","path":"data.uf"},"operador":"igual","valor":"SP"}},{"id":"score","queries":["score-serasa"]}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 4,
    "custo_reservado": 1.9,
    "custo_e_teto": true,
    "saldo_disponivel": 55.5,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 18. POST /workflow — Etapa de webhook (kind: webhook)

Chama um endpoint SEU no meio da cadeia, enviando o que as etapas anteriores produziram, e usa a resposta JSON como dado da etapa (lida pelas seguintes com service "webhook"). tool_config: url (https, host público). Espera até 15s e aceita até 256 KB de resposta; fora disso a etapa falha e on_error das seguintes decide. A chamada vai assinada com X-APIBrasil-Signature (ver workflow/callback-secret). Ferramenta: não cobra.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "enriquece",
      "kind": "webhook",
      "tool_config": {
        "url": "https://meusistema.com.br/hooks/enriquecer"
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"enriquece","kind":"webhook","tool_config":{"url":"https://meusistema.com.br/hooks/enriquecer"}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 2,
    "custo_reservado": 0.7,
    "custo_e_teto": true,
    "saldo_disponivel": 56.7,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 19. POST /workflow — Etapa de parada (kind: stop)

Encerra a cadeia dizendo POR QUÊ. Use como destino do senao de uma condição ou validação: as etapas seguintes viram skipped (skip_reason declared_stop, reserva devolvida) e o motivo viaja para o histórico e para o callback — não é falha, é o fluxo decidindo não seguir. tool_config: motivo (até 140 caracteres). Ferramenta: não cobra.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "tem_obito",
      "kind": "condition",
      "tool_config": {
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais",
          "path": "data.obito"
        },
        "operador": "vazio",
        "senao": "para"
      }
    },
    {
      "id": "score",
      "queries": [
        "score-serasa"
      ]
    },
    {
      "id": "para",
      "kind": "stop",
      "tool_config": {
        "motivo": "Titular com registro de óbito — análise encerrada."
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"tem_obito","kind":"condition","tool_config":{"de":{"node":"consulta","service":"dados-cadastrais","path":"data.obito"},"operador":"vazio","senao":"para"}},{"id":"score","queries":["score-serasa"]},{"id":"para","kind":"stop","tool_config":{"motivo":"Titular com registro de óbito — análise encerrada."}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 4,
    "custo_reservado": 1.9,
    "custo_e_teto": true,
    "saldo_disponivel": 55.5,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 20. POST /workflow — Etapa de análise por IA (kind: ai)

Manda o retorno de uma etapa anterior para um agente de IA e guarda a análise como resposta desta etapa (lida pelas seguintes com service "ai", em data.analise). COBRA como uma consulta e usa a credencial de IA cadastrada na sua conta. tool_config: agent (o agente configurado), prompt (a instrução), provider (openai por padrão) e de {node, service, path} — path opcional para recortar só um trecho do retorno.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais"
      ]
    },
    {
      "id": "analise",
      "kind": "ai",
      "tool_config": {
        "agent": "analista-de-credito",
        "prompt": "Resuma os riscos deste cadastro em até 5 linhas.",
        "provider": "openai",
        "de": {
          "node": "consulta",
          "service": "dados-cadastrais",
          "path": "data"
        }
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais"]},{"id":"analise","kind":"ai","tool_config":{"agent":"analista-de-credito","prompt":"Resuma os riscos deste cadastro em até 5 linhas.","provider":"openai","de":{"node":"consulta","service":"dados-cadastrais","path":"data"}}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 2,
    "custo_reservado": 1.2,
    "custo_e_teto": true,
    "saldo_disponivel": 56.2,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 21. POST /workflow — Etapa de relatório em PDF (kind: pdf)

Pega TUDO o que as etapas anteriores produziram (o dossiê da execução), pede ao modelo um relatório e gera um PDF. É a única etapa sem "de": ela lê a cadeia inteira. COBRA como uma consulta e usa a sua credencial de IA. tool_config: titulo, instrucao (o que o relatório deve destacar), emitente (true para imprimir os dados da sua empresa no cabeçalho) e provider. O arquivo sai por GET workflow/{workflow}/relatorio/{node} — um link sem token, que vai no recibo da etapa (data.arquivo, data.paginas, data.resumo no checa-workflow) e no evento workflow.finalizado do callback_url. Quem tiver a URL lê o documento até a retenção expirar: trate-a como credencial.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/workflow`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "tipo": "cria-workflow",
  "inputs": {
    "cpf": "12345678909"
  },
  "nodes": [
    {
      "id": "consulta",
      "queries": [
        "dados-cadastrais",
        "score-serasa"
      ]
    },
    {
      "id": "relatorio",
      "kind": "pdf",
      "tool_config": {
        "titulo": "Dossiê cadastral",
        "instrucao": "Destaque pendências financeiras e divergências de endereço.",
        "emitente": true,
        "provider": "openai"
      }
    }
  ],
  "callback_url": "https://meusistema.com.br/webhooks/apibrasil"
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/workflow" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"tipo":"cria-workflow","inputs":{"cpf":"12345678909"},"nodes":[{"id":"consulta","queries":["dados-cadastrais","score-serasa"]},{"id":"relatorio","kind":"pdf","tool_config":{"titulo":"Dossiê cadastral","instrucao":"Destaque pendências financeiras e divergências de endereço.","emitente":true,"provider":"openai"}}],"callback_url":"https://meusistema.com.br/webhooks/apibrasil"}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
    "status": "queued",
    "itens": {
      "enfileirados": 1,
      "ignorados": 0
    },
    "total_nodes": 2,
    "custo_reservado": 2.4,
    "custo_e_teto": true,
    "saldo_disponivel": 55,
    "reaproveitado": false,
    "consultar_em": "/api/v2/workflow (tipo: checa-workflow)"
  }
}
```

### 22. GET /flows — Listar flows

Os seus flows e os flows de sistema (modelos prontos, is_system=true, que só podem ser executados ou clonados). Query string: scope (all|mine|system), q (busca em nome e descrição), sort (name, version, runs_count, updated_at, created_at), dir, page e per_page. meta.categories agrupa a contagem por categoria. Cada item traz health (saudável ou com serviço que saiu do catálogo), required_inputs (os campos que a execução exige) e tools (as ferramentas usadas), sem o grafo.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/flows" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "data": [
      {
        "id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
        "name": "Análise veicular",
        "description": "FIPE e débitos a partir da placa",
        "category": "veicular",
        "is_system": false,
        "owner_id": 4471,
        "version": 3,
        "cloned_from_id": null,
        "required_inputs": [
          "placa"
        ],
        "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
        "total_nodes": 2,
        "total_queries": 2,
        "tools": [],
        "health": "healthy",
        "health_reason": null,
        "health_node": null,
        "health_checked_at": "2026-09-05T08:58:00-03:00",
        "runs_count": 12,
        "last_run_at": "2026-09-05T09:00:00-03:00",
        "created_at": "2026-08-20T14:12:00-03:00"
      }
    ],
    "meta": {
      "page": 1,
      "per_page": 25,
      "total": 1,
      "last_page": 1,
      "categories": {
        "veicular": 1
      }
    }
  }
}
```

### 23. POST /flows — Salvar um flow

Guarda a FORMA da cadeia (nodes com o mesmo contrato do cria-workflow), nunca os dados de um caso: os inputs vêm a cada execução. required_inputs é derivado do grafo e não é aceito do cliente. Campos: name (único por conta, até 120), description, callback_url (aviso padrão das execuções deste flow — é o que dá destino ao callback quando quem dispara é um gatilho), nodes, e os campos de desenho do canvas: annotations (post-its, até 30), groups (molduras, até 12) e layout (posição de cada cartão). Limite de 50 flows por conta. Um flow salvo é executado por cria-workflow com flow_id.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "name": "Análise veicular",
  "description": "FIPE e débitos a partir da placa",
  "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
  "nodes": [
    {
      "id": "placa",
      "queries": [
        "fipe"
      ]
    },
    {
      "id": "debitos",
      "queries": [
        "debitos-v4"
      ],
      "inputs_from": {
        "renavam": {
          "node": "placa",
          "service": "fipe",
          "path": "data.renavam"
        }
      }
    }
  ],
  "annotations": [
    {
      "id": "a1",
      "texto": "Rodar só em dias úteis",
      "x": 40,
      "y": 20,
      "cor": "amarelo"
    }
  ],
  "groups": [
    {
      "id": "g1",
      "titulo": "Veículo",
      "x": 0,
      "y": 0,
      "largura": 640,
      "altura": 320,
      "cor": "azul"
    }
  ],
  "layout": {
    "placa::fipe": {
      "x": 40,
      "y": 80
    },
    "debitos::debitos-v4": {
      "x": 360,
      "y": 80
    }
  }
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/flows" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"name":"Análise veicular","description":"FIPE e débitos a partir da placa","callback_url":"https://meusistema.com.br/webhooks/apibrasil","nodes":[{"id":"placa","queries":["fipe"]},{"id":"debitos","queries":["debitos-v4"],"inputs_from":{"renavam":{"node":"placa","service":"fipe","path":"data.renavam"}}}],"annotations":[{"id":"a1","texto":"Rodar só em dias úteis","x":40,"y":20,"cor":"amarelo"}],"groups":[{"id":"g1","titulo":"Veículo","x":0,"y":0,"largura":640,"altura":320,"cor":"azul"}],"layout":{"placa::fipe":{"x":40,"y":80},"debitos::debitos-v4":{"x":360,"y":80}}}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "201": {
    "error": false,
    "flow": {
      "id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "name": "Análise veicular",
      "description": "FIPE e débitos a partir da placa",
      "category": "veicular",
      "is_system": false,
      "owner_id": 4471,
      "version": 3,
      "cloned_from_id": null,
      "required_inputs": [
        "placa"
      ],
      "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
      "total_nodes": 2,
      "total_queries": 2,
      "tools": [],
      "health": "healthy",
      "health_reason": null,
      "health_node": null,
      "health_checked_at": "2026-09-05T08:58:00-03:00",
      "runs_count": 12,
      "last_run_at": "2026-09-05T09:00:00-03:00",
      "created_at": "2026-08-20T14:12:00-03:00",
      "nodes": [
        {
          "id": "placa",
          "kind": "query",
          "queries": [
            "fipe"
          ],
          "on_error": "if_mapped",
          "inputs_from": []
        },
        {
          "id": "debitos",
          "kind": "query",
          "queries": [
            "debitos-v4"
          ],
          "on_error": "if_mapped",
          "inputs_from": {
            "renavam": {
              "node": "placa",
              "service": "fipe",
              "path": "data.renavam"
            }
          }
        }
      ],
      "annotations": [
        {
          "id": "a1",
          "texto": "Rodar só em dias úteis",
          "x": 40,
          "y": 20,
          "cor": "amarelo"
        }
      ],
      "groups": [
        {
          "id": "g1",
          "titulo": "Veículo",
          "x": 0,
          "y": 0,
          "largura": 640,
          "altura": 320,
          "cor": "azul"
        }
      ],
      "layout": {
        "placa::fipe": {
          "x": 40,
          "y": 80
        },
        "debitos::debitos-v4": {
          "x": 360,
          "y": 80
        }
      }
    }
  },
  "422": {
    "error": true,
    "message": "Você já tem um flow com esse nome."
  }
}
```

### 24. GET /flows/{flow} — Ver um flow

O flow completo, com o grafo (nodes), as anotações, as molduras e o layout do canvas. Flow de outra conta responde 404.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/flows/{flow}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "flow": {
      "id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "name": "Análise veicular",
      "description": "FIPE e débitos a partir da placa",
      "category": "veicular",
      "is_system": false,
      "owner_id": 4471,
      "version": 3,
      "cloned_from_id": null,
      "required_inputs": [
        "placa"
      ],
      "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
      "total_nodes": 2,
      "total_queries": 2,
      "tools": [],
      "health": "healthy",
      "health_reason": null,
      "health_node": null,
      "health_checked_at": "2026-09-05T08:58:00-03:00",
      "runs_count": 12,
      "last_run_at": "2026-09-05T09:00:00-03:00",
      "created_at": "2026-08-20T14:12:00-03:00",
      "nodes": [
        {
          "id": "placa",
          "kind": "query",
          "queries": [
            "fipe"
          ],
          "on_error": "if_mapped",
          "inputs_from": []
        },
        {
          "id": "debitos",
          "kind": "query",
          "queries": [
            "debitos-v4"
          ],
          "on_error": "if_mapped",
          "inputs_from": {
            "renavam": {
              "node": "placa",
              "service": "fipe",
              "path": "data.renavam"
            }
          }
        }
      ],
      "annotations": [
        {
          "id": "a1",
          "texto": "Rodar só em dias úteis",
          "x": 40,
          "y": 20,
          "cor": "amarelo"
        }
      ],
      "groups": [
        {
          "id": "g1",
          "titulo": "Veículo",
          "x": 0,
          "y": 0,
          "largura": 640,
          "altura": 320,
          "cor": "azul"
        }
      ],
      "layout": {
        "placa::fipe": {
          "x": 40,
          "y": 80
        },
        "debitos::debitos-v4": {
          "x": 360,
          "y": 80
        }
      }
    }
  },
  "404": {
    "error": true,
    "message": "Flow não encontrado."
  }
}
```

### 25. PUT /flows/{flow} — Editar um flow

Mesmo corpo do POST, com todos os campos opcionais. Mudar o grafo (nodes) incrementa version — as execuções guardam a versão que rodou. Mudar só anotações, molduras ou layout não cria versão nova. Flows de sistema não podem ser editados: clone primeiro (403).

- **Método:** `PUT`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "name": "Análise veicular completa",
  "nodes": [
    {
      "id": "placa",
      "queries": [
        "fipe"
      ]
    },
    {
      "id": "debitos",
      "queries": [
        "debitos-v4",
        "multas"
      ],
      "inputs_from": {
        "renavam": {
          "node": "placa",
          "service": "fipe",
          "path": "data.renavam"
        }
      }
    }
  ]
}
```

**Em cURL**

```bash
curl -X PUT "https://gateway.apibrasil.io/api/v2/flows/{flow}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"name":"Análise veicular completa","nodes":[{"id":"placa","queries":["fipe"]},{"id":"debitos","queries":["debitos-v4","multas"],"inputs_from":{"renavam":{"node":"placa","service":"fipe","path":"data.renavam"}}}]}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "flow": {
      "id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "name": "Análise veicular completa",
      "description": "FIPE e débitos a partir da placa",
      "category": "veicular",
      "is_system": false,
      "owner_id": 4471,
      "version": 4,
      "cloned_from_id": null,
      "required_inputs": [
        "placa"
      ],
      "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
      "total_nodes": 2,
      "total_queries": 3,
      "tools": [],
      "health": "healthy",
      "health_reason": null,
      "health_node": null,
      "health_checked_at": "2026-09-05T08:58:00-03:00",
      "runs_count": 12,
      "last_run_at": "2026-09-05T09:00:00-03:00",
      "created_at": "2026-08-20T14:12:00-03:00",
      "nodes": [
        {
          "id": "placa",
          "kind": "query",
          "queries": [
            "fipe"
          ],
          "on_error": "if_mapped",
          "inputs_from": []
        },
        {
          "id": "debitos",
          "kind": "query",
          "queries": [
            "debitos-v4"
          ],
          "on_error": "if_mapped",
          "inputs_from": {
            "renavam": {
              "node": "placa",
              "service": "fipe",
              "path": "data.renavam"
            }
          }
        }
      ],
      "annotations": [
        {
          "id": "a1",
          "texto": "Rodar só em dias úteis",
          "x": 40,
          "y": 20,
          "cor": "amarelo"
        }
      ],
      "groups": [
        {
          "id": "g1",
          "titulo": "Veículo",
          "x": 0,
          "y": 0,
          "largura": 640,
          "altura": 320,
          "cor": "azul"
        }
      ],
      "layout": {
        "placa::fipe": {
          "x": 40,
          "y": 80
        },
        "debitos::debitos-v4": {
          "x": 360,
          "y": 80
        }
      }
    }
  },
  "403": {
    "error": true,
    "message": "Flows de sistema não podem ser editados. Clone-o primeiro para ter uma cópia sua."
  }
}
```

### 26. DELETE /flows/{flow} — Apagar um flow

Remove a receita. As execuções já feitas continuam disponíveis em workflow/execucoes. Os gatilhos do flow deixam de disparar. Flows de sistema não podem ser apagados (403).

- **Método:** `DELETE`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X DELETE "https://gateway.apibrasil.io/api/v2/flows/{flow}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "message": "Flow removido. As execuções já feitas continuam disponíveis."
  }
}
```

### 27. POST /flows/{flow}/clonar — Clonar um flow

Cria uma cópia sua (version 1, cloned_from_id apontando para o original) — é o caminho para personalizar um flow de sistema ou receber gatilhos nele. O nome recebe um sufixo quando já existe.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/clonar`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/flows/{flow}/clonar" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "201": {
    "error": false,
    "flow": {
      "id": "6a0c9d8d-4f1b-4d5e-8b9f-2c3d4e5f6a04",
      "name": "Análise veicular (cópia)",
      "description": "FIPE e débitos a partir da placa",
      "category": "veicular",
      "is_system": false,
      "owner_id": 4471,
      "version": 1,
      "cloned_from_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "required_inputs": [
        "placa"
      ],
      "callback_url": "https://meusistema.com.br/webhooks/apibrasil",
      "total_nodes": 2,
      "total_queries": 2,
      "tools": [],
      "health": "healthy",
      "health_reason": null,
      "health_node": null,
      "health_checked_at": "2026-09-05T08:58:00-03:00",
      "runs_count": 0,
      "last_run_at": null,
      "created_at": "2026-08-20T14:12:00-03:00",
      "nodes": [
        {
          "id": "placa",
          "kind": "query",
          "queries": [
            "fipe"
          ],
          "on_error": "if_mapped",
          "inputs_from": []
        },
        {
          "id": "debitos",
          "kind": "query",
          "queries": [
            "debitos-v4"
          ],
          "on_error": "if_mapped",
          "inputs_from": {
            "renavam": {
              "node": "placa",
              "service": "fipe",
              "path": "data.renavam"
            }
          }
        }
      ],
      "annotations": [
        {
          "id": "a1",
          "texto": "Rodar só em dias úteis",
          "x": 40,
          "y": 20,
          "cor": "amarelo"
        }
      ],
      "groups": [
        {
          "id": "g1",
          "titulo": "Veículo",
          "x": 0,
          "y": 0,
          "largura": 640,
          "altura": 320,
          "cor": "azul"
        }
      ],
      "layout": {
        "placa::fipe": {
          "x": 40,
          "y": 80
        },
        "debitos::debitos-v4": {
          "x": 360,
          "y": 80
        }
      }
    }
  }
}
```

### 28. GET /flows/{flow}/execucoes — Execuções de um flow

As execuções DESTE flow, paginadas (page, per_page). Mesma forma de workflow/execucoes, que lista todas as execuções da conta.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/execucoes`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/flows/{flow}/execucoes" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "data": [
      {
        "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
        "status": "completed",
        "total_nodes": 2,
        "custo": {
          "reservado": 1.4,
          "cobrado": 1.2,
          "liberado": 0.2
        },
        "criado_em": "2026-09-05T09:00:00-03:00",
        "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
        "flow_version": 3
      }
    ],
    "meta": {
      "page": 1,
      "per_page": 25,
      "total": 1,
      "last_page": 1
    }
  }
}
```

### 29. GET /flows/{flow}/triggers — Listar os gatilhos de um flow

Os gatilhos do flow, com contadores (calls_count, runs_count), o resultado da última execução e o motivo de um eventual desligamento automático (disabled_reason — após 10 falhas seguidas o gatilho é desligado). O segredo NÃO vem aqui.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "data": [
      {
        "id": "7b1d0e9e-5a2c-4e6f-9c0f-3d4e5f6a7b03",
        "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
        "kind": "webhook_in",
        "enabled": true,
        "last_run_at": "2026-09-05T09:00:00-03:00",
        "last_workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
        "last_status": "completed",
        "failure_count": 0,
        "last_failure_reason": null,
        "disabled_reason": null,
        "calls_count": 38,
        "runs_count": 37,
        "created_at": "2026-08-21T10:00:00-03:00",
        "slug": "wf_3f9a1c2b4d5e6f70a1b2c3d4",
        "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
        "auth_mode": "hmac",
        "input_mapping": {
          "cpf": "cliente.documento"
        }
      }
    ]
  }
}
```

### 30. POST /flows/{flow}/triggers — Criar um gatilho de webhook

Cria uma URL (hooks/{slug}) que executa o flow quando um sistema seu faz POST nela. kind: webhook_in (o único tipo; cron foi removido — agende no seu lado e chame a URL). input_mapping é obrigatório na criação, podendo ser {}: mapeia campo do flow → caminho no corpo recebido (ex.: cpf → cliente.documento). Vazio, o corpo passa direto com os nomes que vier. auth_mode: hmac (padrão — o header carrega a assinatura HMAC-SHA256 do corpo) ou secret (o header carrega o próprio segredo). O segredo é devolvido AQUI e pode ser relido em /segredo. Flows de sistema não aceitam gatilhos: clone antes. Limite de 10 gatilhos por flow.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "kind": "webhook_in",
  "enabled": true,
  "auth_mode": "hmac",
  "input_mapping": {
    "cpf": "cliente.documento"
  }
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"kind":"webhook_in","enabled":true,"auth_mode":"hmac","input_mapping":{"cpf":"cliente.documento"}}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "201": {
    "error": false,
    "trigger": {
      "id": "7b1d0e9e-5a2c-4e6f-9c0f-3d4e5f6a7b03",
      "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "kind": "webhook_in",
      "enabled": true,
      "last_run_at": "2026-09-05T09:00:00-03:00",
      "last_workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
      "last_status": "completed",
      "failure_count": 0,
      "last_failure_reason": null,
      "disabled_reason": null,
      "calls_count": 38,
      "runs_count": 37,
      "created_at": "2026-08-21T10:00:00-03:00",
      "slug": "wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "auth_mode": "hmac",
      "input_mapping": {
        "cpf": "cliente.documento"
      },
      "secret": "whsec_4b2c9e1f7a3d5e6f8091a2b3c4d5e6f7a8b9c0d1e2f3a4b5",
      "exemplo": {
        "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
        "corpo": "{\"cliente\":{\"documento\":\"12345678909\"}}",
        "assinatura": "a3f1…",
        "curl": "curl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H 'X-APIBrasil-Signature: sha256=a3f1…' --data '{\"cliente\":{\"documento\":\"12345678909\"}}'",
        "curl_editavel": "SECRET='whsec_…'\nBODY='{\"cliente\":{\"documento\":\"12345678909\"}}'\nSIG=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hmac \"$SECRET\" -r | cut -d' ' -f1)\ncurl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H \"X-APIBrasil-Signature: sha256=$SIG\" --data \"$BODY\"",
        "aviso": "Este comando EXECUTA o flow de verdade e cobra da sua conta. Para conferir sem gastar, use 'valida-workflow'. Se editar o corpo, use o comando editável — a assinatura cobre os bytes exatos."
      },
      "aviso": "Guarde este segredo. Ele pode ser lido depois em GET /api/v2/flows/8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02/triggers/7b1d0e9e-5a2c-4e6f-9c0f-3d4e5f6a7b03/segredo."
    }
  },
  "403": {
    "error": true,
    "message": "Flows de sistema não aceitam gatilhos. Clone o flow primeiro para configurá-lo."
  }
}
```

### 31. PUT /flows/{flow}/triggers/{trigger} — Editar um gatilho

Liga/desliga (enabled), troca o input_mapping ou o auth_mode. kind não pode ser alterado — apague e crie outro. Religar um gatilho desligado por falhas zera o contador.

- **Método:** `PUT`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Corpo da requisição**

```json
{
  "enabled": false,
  "input_mapping": {
    "cpf": "documento"
  }
}
```

**Em cURL**

```bash
curl -X PUT "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -d '{"enabled":false,"input_mapping":{"cpf":"documento"}}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "trigger": {
      "id": "7b1d0e9e-5a2c-4e6f-9c0f-3d4e5f6a7b03",
      "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
      "kind": "webhook_in",
      "enabled": false,
      "last_run_at": "2026-09-05T09:00:00-03:00",
      "last_workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
      "last_status": "completed",
      "failure_count": 0,
      "last_failure_reason": null,
      "disabled_reason": null,
      "calls_count": 38,
      "runs_count": 37,
      "created_at": "2026-08-21T10:00:00-03:00",
      "slug": "wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "auth_mode": "hmac",
      "input_mapping": {
        "cpf": "cliente.documento"
      }
    }
  }
}
```

### 32. DELETE /flows/{flow}/triggers/{trigger} — Apagar um gatilho

A URL hooks/{slug} deixa de existir imediatamente (404 para quem chamar).

- **Método:** `DELETE`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X DELETE "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "message": "Gatilho removido."
  }
}
```

### 33. GET /flows/{flow}/triggers/{trigger}/segredo — Ler o segredo e o comando de teste

O segredo do gatilho (só o dono lê), a URL do webhook e um exemplo de chamada pronto: curl com a assinatura já calculada sobre um corpo de exemplo, e a versão editável que recalcula a assinatura com openssl. Atenção: o exemplo executa o flow de verdade e cobra.

- **Método:** `GET`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/segredo`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X GET "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/segredo" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "secret": "whsec_4b2c9e1f7a3d5e6f8091a2b3c4d5e6f7a8b9c0d1e2f3a4b5",
    "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
    "header": "X-APIBrasil-Signature",
    "algoritmo": "HMAC-SHA256 sobre o corpo cru da requisição",
    "exemplo": {
      "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "corpo": "{\"cliente\":{\"documento\":\"12345678909\"}}",
      "assinatura": "a3f1…",
      "curl": "curl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H 'X-APIBrasil-Signature: sha256=a3f1…' --data '{\"cliente\":{\"documento\":\"12345678909\"}}'",
      "curl_editavel": "SECRET='whsec_…'\nBODY='{\"cliente\":{\"documento\":\"12345678909\"}}'\nSIG=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hmac \"$SECRET\" -r | cut -d' ' -f1)\ncurl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H \"X-APIBrasil-Signature: sha256=$SIG\" --data \"$BODY\"",
      "aviso": "Este comando EXECUTA o flow de verdade e cobra da sua conta. Para conferir sem gastar, use 'valida-workflow'. Se editar o corpo, use o comando editável — a assinatura cobre os bytes exatos."
    }
  }
}
```

### 34. POST /flows/{flow}/triggers/{trigger}/rotacionar-segredo — Rotacionar o segredo

Gera um segredo novo e invalida o anterior NA HORA — quem chama a URL precisa ser atualizado antes. A URL (slug) não muda.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/rotacionar-segredo`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/rotacionar-segredo" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "200": {
    "error": false,
    "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
    "secret": "whsec_9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b",
    "exemplo": {
      "url": "https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4",
      "corpo": "{\"cliente\":{\"documento\":\"12345678909\"}}",
      "assinatura": "a3f1…",
      "curl": "curl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H 'X-APIBrasil-Signature: sha256=a3f1…' --data '{\"cliente\":{\"documento\":\"12345678909\"}}'",
      "curl_editavel": "SECRET='whsec_…'\nBODY='{\"cliente\":{\"documento\":\"12345678909\"}}'\nSIG=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hmac \"$SECRET\" -r | cut -d' ' -f1)\ncurl -X POST 'https://gateway.apibrasil.io/api/v2/hooks/wf_3f9a1c2b4d5e6f70a1b2c3d4' -H 'Content-Type: application/json' -H \"X-APIBrasil-Signature: sha256=$SIG\" --data \"$BODY\"",
      "aviso": "Este comando EXECUTA o flow de verdade e cobra da sua conta. Para conferir sem gastar, use 'valida-workflow'. Se editar o corpo, use o comando editável — a assinatura cobre os bytes exatos."
    },
    "aviso": "O segredo anterior deixou de valer. Atualize o sistema que chama esta URL."
  }
}
```

### 35. POST /flows/{flow}/triggers/{trigger}/testar — Testar um gatilho

Não há simulação de gatilho de webhook: testar é fazer um POST real na URL (que executa e cobra). Esta rota responde 422 trigger_test_unavailable e aponta para o exemplo de chamada em /segredo. Para conferir a receita sem gastar, use valida-workflow com flow_id.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/testar`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `Authorization` | `Bearer $APIBRASIL_TOKEN` |

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/flows/{flow}/triggers/{trigger}/testar" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $APIBRASIL_TOKEN"
```

**Resposta de exemplo, do catálogo**

```json
{
  "422": {
    "error": true,
    "motivo": "trigger_test_unavailable",
    "message": "Gatilhos de webhook são testados enviando um POST real para a URL, com o corpo assinado. Use o exemplo de /segredo."
  }
}
```

### 36. POST /hooks/{slug} — Disparar o flow pelo webhook (chamado pelo seu sistema)

A URL que o gatilho cria. FORA da autenticação por token: quem chama é um sistema de terceiro, autenticado pelo par slug secreto + header X-APIBrasil-Signature (modo hmac: sha256= + HMAC-SHA256 do corpo cru com o segredo; modo secret: o próprio segredo). O corpo JSON é lido conforme o input_mapping e vira os inputs da execução; campo mapeado ausente responde 422 webhook_missing_field e NADA é executado. Idempotency-Key opcional; sem ele, o hash do corpo evita executar duas vezes o mesmo reenvio. Limite de 10 chamadas por minuto por gatilho (429 com retry_after). Responde 202 com o workflow_id; acompanhe pelo checa-workflow ou pelo callback_url do flow.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/hooks/{slug}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `X-APIBrasil-Signature` | `sha256=HMAC_SHA256_DO_CORPO` |
| `Idempotency-Key` | `pedido-8731` |

**Corpo da requisição**

```json
{
  "cliente": {
    "documento": "12345678909",
    "nome": "Maria"
  }
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/hooks/{slug}" \
  -H "Content-Type: application/json" \
  -H "X-APIBrasil-Signature: sha256=HMAC_SHA256_DO_CORPO" \
  -H "Idempotency-Key: pedido-8731" \
  -d '{"cliente":{"documento":"12345678909","nome":"Maria"}}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "202": {
    "error": false,
    "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01"
  },
  "401": {
    "error": true,
    "motivo": "assinatura_invalida",
    "message": "A assinatura não confere com o corpo recebido.",
    "dica": "Assine os bytes EXATOS do corpo enviado, sem reformatar o JSON."
  },
  "422": {
    "error": true,
    "motivo": "webhook_missing_field",
    "message": "O campo 'cliente.documento' não veio no payload (mapeado para 'cpf'). Nada foi executado."
  },
  "429": {
    "error": true,
    "message": "Muitas chamadas para este gatilho. Tente novamente em instantes.",
    "retry_after": 41
  }
}
```

### 37. POST /{callback_url} — Evento workflow.finalizado (enviado ao seu callback_url)

Enviado UMA vez, quando a execução fecha (completed, partial ou failed), para o callback_url da chamada ou, na falta dele, o do flow. O corpo é o mesmo do checa-workflow mais event; se os resultados excederem o tamanho máximo, vêm sem data e resultados_truncados=true — busque pelo checa-workflow. Assinado com X-APIBrasil-Signature usando o segredo de workflow/callback-secret. Responda 2xx em até 10s; fora disso o gateway tenta de novo até 5 vezes, com espera crescente. Hosts privados e redirecionamentos são recusados. Só https e http em host público.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/{callback_url}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `X-APIBrasil-Signature` | `sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET` |

**Corpo da requisição**

```json
{
  "event": "workflow.finalizado",
  "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
  "status": "completed",
  "progresso": {
    "total": 2,
    "concluidos": 2,
    "falhas": 0,
    "ignorados": 0,
    "pendentes": 0,
    "percentual": 100
  },
  "custo": {
    "reservado": 1.4,
    "cobrado": 1.2,
    "liberado": 0.2
  },
  "total_nodes": 2,
  "custo_e_teto": true,
  "criado_em": "2026-09-05T09:00:00-03:00",
  "finalizado_em": "2026-09-05T09:00:07-03:00",
  "duracao_segundos": 7,
  "flow_id": "8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02",
  "flow_version": 3,
  "nodes": {
    "...": "mesma forma do checa-workflow"
  },
  "resultados_truncados": false
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/{callback_url}" \
  -H "Content-Type: application/json" \
  -H "X-APIBrasil-Signature: sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET" \
  -d '{"event":"workflow.finalizado","workflow_id":"9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01","status":"completed","progresso":{"total":2,"concluidos":2,"falhas":0,"ignorados":0,"pendentes":0,"percentual":100},"custo":{"reservado":1.4,"cobrado":1.2,"liberado":0.2},"total_nodes":2,"custo_e_teto":true,"criado_em":"2026-09-05T09:00:00-03:00","finalizado_em":"2026-09-05T09:00:07-03:00","duracao_segundos":7,"flow_id":"8c2e1a0f-6b3d-4f7a-8d10-4e5f6a7b8c02","flow_version":3,"nodes":{"...":"mesma forma do checa-workflow"},"resultados_truncados":false}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "2xx": {
    "_esperado": "qualquer corpo; só o status importa"
  }
}
```

### 38. POST /{callback_url} — Evento node.dispatched (callback_url da etapa)

Enviado ao callback_url declarado NO NODE quando a etapa entra em execução. É o sinal de progresso: traz o node e o progresso do workflow, sem resultados (a etapa ainda não os tem). Mesma assinatura e mesmas regras de entrega do workflow.finalizado.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/{callback_url}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `X-APIBrasil-Signature` | `sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET` |

**Corpo da requisição**

```json
{
  "event": "node.dispatched",
  "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
  "workflow_status": "running",
  "node": {
    "id": "debitos",
    "position": 2,
    "kind": "query",
    "status": "running",
    "skip_reason": null,
    "ferramenta": null,
    "on_error": "if_mapped",
    "homolog": false,
    "device_id": null,
    "progresso": {
      "total": 1,
      "concluidos": 0,
      "falhas": 0,
      "ignorados": 0,
      "pendentes": 1
    },
    "dispatched_at": "2026-09-05T09:00:04-03:00",
    "finished_at": null
  },
  "progresso": {
    "total": 2,
    "concluidos": 1,
    "falhas": 0,
    "ignorados": 0
  },
  "consultar_em": "/api/v2/workflow (tipo: checa-workflow)",
  "resultados_truncados": false
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/{callback_url}" \
  -H "Content-Type: application/json" \
  -H "X-APIBrasil-Signature: sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET" \
  -d '{"event":"node.dispatched","workflow_id":"9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01","workflow_status":"running","node":{"id":"debitos","position":2,"kind":"query","status":"running","skip_reason":null,"ferramenta":null,"on_error":"if_mapped","homolog":false,"device_id":null,"progresso":{"total":1,"concluidos":0,"falhas":0,"ignorados":0,"pendentes":1},"dispatched_at":"2026-09-05T09:00:04-03:00","finished_at":null},"progresso":{"total":2,"concluidos":1,"falhas":0,"ignorados":0},"consultar_em":"/api/v2/workflow (tipo: checa-workflow)","resultados_truncados":false}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "2xx": {
    "_esperado": "qualquer corpo; só o status importa"
  }
}
```

### 39. POST /{callback_url} — Evento node.finalizado (callback_url da etapa)

Enviado ao callback_url do node quando a etapa fecha, com o status dela (completed, partial, failed ou skipped) e os resultados por serviço — a mesma forma de resultados no checa-workflow. Permite reagir etapa a etapa sem esperar a cadeia inteira.

- **Método:** `POST`
- **Endereço:** `https://gateway.apibrasil.io/api/v2/{callback_url}`
- **Versão da rota:** v2

**Cabeçalhos**

| Cabeçalho | Valor |
| --- | --- |
| `Content-Type` | `application/json` |
| `X-APIBrasil-Signature` | `sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET` |

**Corpo da requisição**

```json
{
  "event": "node.finalizado",
  "workflow_id": "9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01",
  "workflow_status": "running",
  "node": {
    "id": "debitos",
    "position": 2,
    "kind": "query",
    "status": "completed",
    "skip_reason": null,
    "ferramenta": null,
    "on_error": "if_mapped",
    "homolog": false,
    "device_id": null,
    "progresso": {
      "total": 1,
      "concluidos": 1,
      "falhas": 0,
      "ignorados": 0,
      "pendentes": 0
    },
    "dispatched_at": "2026-09-05T09:00:04-03:00",
    "finished_at": "2026-09-05T09:00:07-03:00"
  },
  "progresso": {
    "total": 2,
    "concluidos": 2,
    "falhas": 0,
    "ignorados": 0
  },
  "resultados": {
    "debitos-v4": {
      "status": "success",
      "price": 0.7,
      "tentativas": 1,
      "tentativas_max": 3,
      "tentativas_label": "1/3",
      "iniciado_em": "2026-09-05T09:00:04-03:00",
      "finalizado_em": "2026-09-05T09:00:07-03:00",
      "duracao_ms": 2910,
      "data": {
        "total_debitos": 0,
        "restricoes": []
      }
    }
  },
  "consultar_em": "/api/v2/workflow (tipo: checa-workflow)",
  "resultados_truncados": false
}
```

**Em cURL**

```bash
curl -X POST "https://gateway.apibrasil.io/api/v2/{callback_url}" \
  -H "Content-Type: application/json" \
  -H "X-APIBrasil-Signature: sha256=HMAC_SHA256_DO_CORPO_COM_O_SEU_CALLBACK_SECRET" \
  -d '{"event":"node.finalizado","workflow_id":"9d3f2b1a-7c4e-4a8b-9e21-5f6a7b8c9d01","workflow_status":"running","node":{"id":"debitos","position":2,"kind":"query","status":"completed","skip_reason":null,"ferramenta":null,"on_error":"if_mapped","homolog":false,"device_id":null,"progresso":{"total":1,"concluidos":1,"falhas":0,"ignorados":0,"pendentes":0},"dispatched_at":"2026-09-05T09:00:04-03:00","finished_at":"2026-09-05T09:00:07-03:00"},"progresso":{"total":2,"concluidos":2,"falhas":0,"ignorados":0},"resultados":{"debitos-v4":{"status":"success","price":0.7,"tentativas":1,"tentativas_max":3,"tentativas_label":"1/3","iniciado_em":"2026-09-05T09:00:04-03:00","finalizado_em":"2026-09-05T09:00:07-03:00","duracao_ms":2910,"data":{"total_debitos":0,"restricoes":[]}}},"consultar_em":"/api/v2/workflow (tipo: checa-workflow)","resultados_truncados":false}'
```

**Resposta de exemplo, do catálogo**

```json
{
  "2xx": {
    "_esperado": "qualquer corpo; só o status importa"
  }
}
```

## Ver também

- Especificação OpenAPI: https://doc.apibrasil.io/apis/plataforma/workflow/openapi.json
- Catálogo de APIs: [Catálogo de APIs](https://doc.apibrasil.io/apis.md)
- SDKs oficiais: [SDKs oficiais](https://doc.apibrasil.io/sdks.md)
- Índice da documentação: https://doc.apibrasil.io/llms.txt
- Versão HTML desta página: https://doc.apibrasil.io/apis/plataforma/workflow
