Docs
...

Integração de Apps do Marketplace

Se você está desenvolvendo um aplicativo e deseja integrá-lo ao Workflow, esta documentação mostra como fazer isso.

Um app se integra ao Workflow publicando um manifesto de ações (iugu.actions/v1): um documento JSON com as ações (actions) que o Workflow pode chamar e os gatilhos (triggers) que podem iniciar um fluxo. O mesmo manifesto é lido pelo Iugu for AI (onde cada ação vira uma ferramenta) e pela CLI iugu — você descreve sua API uma vez só.

Para que o Workflow encontre o seu app, são necessárias duas coisas no Console:

  1. o entitlement actions_provider no app (Apps › Entitlements, ou iugu app entitlements set actions_provider);
  2. a service_api_url do app apontando para a base da sua API. O manifesto fica em GET {service_api_url}/actions.

Compatibilidade: apps publicados antes desta especificação definiram service_api_url como a própria rota do manifesto (…/service/workflow/actions). Quando service_api_url já termina em /actions, o Workflow a busca como está; caso contrário, acrescenta /actions. Um manifesto que responde um array de ações (sem actions/triggers) também continua sendo lido; um manifesto sem o bloco authorization é aceito com um aviso no log do Workflow.


Transformando funções do seu app em actions ou triggers

Nem toda funcionalidade precisa ser reescrita para ser integrada ao Workflow. Muitas vezes, você já possui métodos prontos que podem ser adaptados com facilidade para funcionar como actions ou triggers.


Exemplo 1 — Transformando uma função “baixa em conta corrente” em uma action

Suponha que você tenha a seguinte função no seu backend:

func BaixarConta(id string, valor float64) error {
    // lógica de baixa no sistema financeiro
}

Para que essa funcionalidade seja exposta ao Workflow como uma action, você deve:

  1. Criar uma rota HTTP, por exemplo: /api/contas/:id/baixa
  2. Estruturar os parâmetros como ParamInput, indicando se vêm do path, query ou body
  3. Declarar em authorization a permissão (<tag>:<ação>) que quem chama precisa ter no workspace — uma das implemented_actions do seu app no Console — e, se for o caso, o nível de autenticação exigido (acr)
  4. Adicionar essa definição em actions do JSON servido em {service_api_url}/actions:
{
  "name": "baixar_conta",
  "title": "Baixar Conta Corrente",
  "label": "Realiza a baixa de uma conta corrente no sistema financeiro",
  "description": "Baixa o saldo devedor de uma conta corrente. O valor é em reais e a operação não pode ser desfeita.",
  "icon": "https://seusistema.com/icons/finance.svg",
  "authorization": { "action": "seusistema:contas.baixar", "acr": "informations" },
  "url": "https://seusistema.com/api/contas/:id/baixa",
  "method": "POST",
  "parameters": [
    {
      "name": "id",
      "type": "string",
      "required": true,
      "direction": "ParamInput",
      "description": "ID da conta a ser baixada",
      "source": "path"
    },
    {
      "name": "valor",
      "type": "number",
      "required": true,
      "direction": "ParamInput",
      "description": "Valor a ser baixado",
      "source": "body"
    },
    {
      "name": "mensagem",
      "type": "string",
      "required": false,
      "direction": "ParamOutput",
      "description": "Confirmação de baixa"
    }
  ]
}

📬 Exemplo 2 — Transformando uma função “ao receber mensagem” em um trigger

Se o seu app já possui uma funcionalidade que recebe mensagens (via webhook ou API), você pode transformá-la em um trigger para o Workflow.

Função original:

func ReceberMensagem(mensagem string) {
    // salva no banco, envia alerta, etc.
}

O que você precisa fazer:

  1. Quando a mensagem for recebida, envie um evento para o Workflow:
POST https://workflow.iugu.com/services/event
Authorization: Bearer <access_token com audience Iugu.Platform.3X3OZfVdfhohOZfO2f2Ndq>
Content-Type: application/json
{
  "event": "on_new_message",
  "workspace_id": "<short id do workspace>",
  "payload": {
    "message": "Texto da mensagem recebida"
  }
}
  1. Exponha esse trigger em triggers do manifesto:
{
  "name": "on_new_message",
  "title": "Ao receber nova mensagem",
  "label": "Dispara quando uma nova mensagem for recebida",
  "icon": "https://seusistema.com/icons/chat.svg",
  "authorization": { "action": "seusistema:mensagens.ler" },
  "parameters": [
    {
      "name": "message",
      "type": "string",
      "required": true,
      "direction": "ParamOutput",
      "description": "Conteúdo da mensagem recebida"
    }
  ]
}

🧠 Resumo

Tipo Definição
Action Executa uma operação mediante chamada do Workflow com inputs definidos.
Trigger Emite um evento do seu sistema para o Workflow com dados de saída (output).

Onde o manifesto fica

  Regra
Endereço GET {service_api_url}/actions. Se a service_api_url cadastrada no Console já termina em /actions, ela mesma é o manifesto (apps antigos).
Requisição Accept: application/json. O Workflow envia Authorization: Bearer <token client_credentials com aud Iugu.Platform.<seu app>>; o manifesto deve ser público (não coloque segredos nele) — o token só permite personalizar ou limitar a resposta.
Cache Envie Cache-Control: max-age=300 e ETag. O Workflow guarda o manifesto em memória por pelo menos 60 s (5 min quando você não diz nada, no máximo 1 h), revalida com If-None-Match e, se o seu app não responder, continua usando a última cópia boa. O manifesto nunca é buscado a cada execução de fluxo.
Limites Resposta de até 256 KB em até 4 s; redirecionamentos só são seguidos dentro da mesma origem.

Um exemplo real e público: o manifesto da Central de cobranças (Billing), com 21 ações — 🔗 https://billing.iugu.com/api/actions.


Estrutura do manifesto

{
  "spec": "iugu.actions/v1",
  "app": {
    "client_id": "1qwBQ0DnzRCgtUOItzxMl1",
    "tag": "seusistema",
    "name": "Seu Sistema",
    "icon": "https://seusistema.com/icon.png",
    "service_api_url": "https://seusistema.com/api",
    "docs_url": "https://seusistema.com/docs"
  },
  "actions": [ /* lista de ações disponíveis */ ],
  "triggers": [ /* lista de eventos disponíveis */ ]
}
Campo Obrigatório Descrição
spec Sim Sempre iugu.actions/v1. Mudanças dentro da v1 são apenas aditivas; consumidores ignoram chaves desconhecidas.
app Recomendado client_id, tag, name, icon, service_api_url, docs_url do seu app.
actions Sim (pode ser vazio) Operações que o Workflow poderá executar.
triggers Sim (pode ser vazio) Eventos que poderão iniciar um fluxo.

Campos de uma ação

Campo Obrigatório Descrição
name Sim Identificador estável, snake_case, único no manifesto (ex.: insert_data). É por ele que o Workflow encontra a ação de um fluxo salvo — mude a url à vontade, não mude o name.
title Sim Nome curto para exibição (Title Case).
label Sim Descrição de uma linha, mostrada nas listas.
description Não Texto longo, mostrado no inspetor do nó e usado como descrição da ferramenta pelo Iugu for AI.
icon Não URL absoluta de um ícone SVG/PNG.
authorization Sim action: permissão GIA <tag>:<ação> que quem chama precisa ter no workspace (uma das implemented_actions do app). acr (opcional): informations (padrão), config ou transfers — nível de autenticação que a pessoa precisa ter. Veja Autorização.
url Sim URL absoluta, na mesma origem da service_api_url (o Workflow recusa qualquer outra). Use :nome para parâmetros com source: path.
method Sim GET, POST, PUT, PATCH ou DELETE. Sem method, o Workflow assume POST.
annotations Não Anotações de ferramenta MCP (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), usadas pelo Iugu for AI.
parameters Sim Entradas e saídas (abaixo).
input_schema, output_schema Não JSON Schema que substitui a derivação a partir de parameters (para corpos que não são objetos planos). O Workflow não os usa.

Campos de um trigger

name (é o valor de event que o app envia em POST /services/event), title, label, icon, description, authorization.action (permissão que o workspace concede ao app para o evento ser aceito — informativo na v1) e parameters, todos ParamOutput.


Detalhamento dos parâmetros (parameters)

Cada item de parameters define um campo necessário para execução da ação ou um dado do evento gerado pelo trigger.

Campo Obrigatório Descrição
name Sim Nome interno, snake_case (ex.: spreadsheet_id). Para source: path, corresponde ao :name da url.
type Sim string · textarea · number · integer · boolean · datetime · json · select · color · lookup (tabela abaixo).
required Sim Indica se o campo é obrigatório.
direction Sim ParamInput ou ParamOutput.
description Sim Explicação do que o parâmetro representa.
source Só em ParamInput query, path ou body. Quando omitido: body (ou query em ações GET).
default Não Valor inicial do campo no editor (value é aceito como sinônimo).
options Em select [{ "value", "label" }].
lookup Em lookup { "endpoint", "method", "params" } — opções dinâmicas, consultadas com um token aud Iugu.Platform.<seu app>.
hidden, disabled, alias Não Dicas para o editor: hidden esconde o campo (e o exclui das entradas da ferramenta MCP), disabled bloqueia a edição, alias é o rótulo exibido.

Tipos e como o Workflow os envia

type O Workflow envia JSON Schema (Iugu for AI / CLI)
string, textarea, select, color, lookup texto {"type":"string"} (select: enum com os options[].value; color: pattern ^#[0-9a-fA-F]{6}$)
number número JSON (10.5) {"type":"number"}
integer número inteiro JSON (10) {"type":"integer"}
boolean booleano JSON (true/false) {"type":"boolean"}
datetime string RFC 3339 (2026-09-20T10:00:00-03:00) {"type":"string","format":"date-time"}
json o valor interpretado como JSON (objeto ou array) {"type":["object","array"]}

Em query e path os valores vão como texto (true, 10, data em RFC 3339). Um valor que não corresponde ao tipo (ex.: abc em number) faz o nó falhar antes de chamar o seu app.

direction — Input vs Output

  • ParamInput: são dados que o Workflow precisa fornecer para que a ação seja executada.
  • ParamOutput: são dados gerados ou retornados após a execução da ação ou trigger. A resposta da ação deve ser um objeto JSON cujas chaves de primeiro nível têm os nomes dos ParamOutput; cada uma vira uma variável do fluxo.

Em triggers, todos os parâmetros devem ser ParamOutput.

source — De onde vem o dado?

Para ParamInput, o campo source define a localização do dado dentro da requisição HTTP:

  • query: query string (?status=open)
  • path: parâmetro de caminho (/api/sheets/:spreadsheet_id/insert)
  • body: corpo da requisição, um objeto JSON com um campo por parâmetro

Em ParamOutput, o campo source pode ser omitido.


Como o Workflow chama uma ação

Toda chamada leva:

<method> <url com os parâmetros de path substituídos e os de query acrescentados>
Authorization: Bearer <JWT com aud Iugu.Platform.<seu app>>
Workspace: <short id do workspace do fluxo>
Content-Type: application/json
  • O workspace vem no cabeçalho Workspace. Um parâmetro workspace_id declarado no manifesto continua sendo preenchido durante a transição, mas prefira o cabeçalho.
  • O corpo (em POST, PUT, PATCH e, quando há entradas para ele, DELETE) é um objeto JSON com os parâmetros source: body, já convertidos para o tipo declarado.
  • A resposta deve ser JSON. Erros devem seguir o formato problem JSON (RFC 9457): { "error": "...", "error_description": "..." } com o status HTTP adequado; o Workflow registra o corpo no log do fluxo.

Autorização de uma ação

O bloco authorization diz o que uma chamada precisa, e é lido antes de o Workflow chamar você:

  1. action — o Workflow consulta POST /verify do Console para o seu próprio principal (app:3X3OZfVdfhohOZfO2f2Ndq) nessa ação, no workspace do fluxo. Se o Console responder false, o nó falha e o seu app não é chamado. Você deve fazer a mesma verificação do seu lado (semântica AND — veja Deveres do provedor).
  2. acr — config e transfers exigem uma autenticação recente da pessoa (segundo fator). O Workflow executa fluxos com o token do próprio app, sem pessoa, e por isso não chama ações com esses níveis: o editor marca o nó (“precisa de autorização humana — não roda sem supervisão”) e a execução falha com essa mensagem. Use informations (o padrão) em tudo que pode rodar automaticamente.

Autenticação e segurança

Deveres do provedor ao receber uma chamada

Sempre que o Workflow chamar uma action do seu aplicativo, valide o token antes de processar a requisição:

  • assinatura pelo JWKS do Console (https://console.iugu.com/.well-known/jwks.json), iss, exp e typ at+JWT;
  • aud igual a Iugu.Platform.<seu app>;
  • POST /verify no Console com principals: [token.sub] e actions: [authorization.action] da ação chamada: o principal (uma pessoa, ou um app agindo como ele mesmo — no caso do Workflow, app:3X3OZfVdfhohOZfO2f2Ndq) precisa ter a permissão no workspace do cabeçalho Workspace. O client_id do token é atribuição para registro, não algo a autorizar;
  • para subjects user:, exija o acr declarado. Quando o contexto de autenticação for insuficiente, responda 401 com WWW-Authenticate: Bearer error="insufficient_user_authentication", acr_values="<nível>", max_age="<segundos>" (RFC 9470) — é assim que o Iugu for AI sabe que precisa pedir um segundo fator à pessoa.

Isso protege sua aplicação contra chamadas não autorizadas e garante que a permissão seja verificada dos dois lados.

Geração de access token ao executar um trigger

Quando seu app disparar uma trigger para o Workflow, é sua responsabilidade gerar um token de acesso válido (client_credentials com audience=Iugu.Platform.3X3OZfVdfhohOZfO2f2Ndq) e incluí-lo no header da requisição:

POST https://workflow.iugu.com/services/event
Authorization: Bearer <access_token com audience Iugu.Platform.3X3OZfVdfhohOZfO2f2Ndq>
Content-Type: application/json
{
  "event": "on_new_message",
  "workspace_id": "<short id do workspace>",
  "payload": {
    "message": "Texto da mensagem recebida"
  }
}

O Workflow valida a assinatura e o aud do token e consulta o Console (/verify) para confirmar que o seu app tem a permissão workflow:event.create no workspace informado — ela precisa estar entre as consumed_actions do seu app.

⚠️ Triggers disparadas sem um token válido, ou por um app sem workflow:event.create no workspace, são rejeitadas.

Resumo

Situação O que fazer
Recebendo chamada do Workflow Validar o JWT, chamar /verify com token.sub e authorization.action
Disparando trigger para Workflow Gerar token com audience do Workflow; ter workflow:event.create no workspace

Boas práticas

  • Use nomes de parâmetro curtos e significativos, em snake_case; use Title Case em title.
  • Descreva cada parâmetro de forma objetiva — a description aparece para a pessoa no editor e para o modelo no Iugu for AI.
  • Declare authorization em toda ação, com o menor acr possível; reserve config/transfers para o que realmente exige uma pessoa.
  • Nunca mude o name de uma ação publicada; mude a url quando precisar.
  • Envie Cache-Control e ETag no manifesto.
  • Inclua um icon válido, especialmente para interfaces visuais.