Workflows
Overview
A workflow is an automation that starts from a trigger and carries data through a chain of steps until it produces an effect — writing rows, sending an email, calling an external system. Each step reads the data the workflow has gathered so far, does one job, and passes the result to the next step, so what one step produces the next can consume.
Workflows replace repetitive manual work and ad-hoc scripts: importing a batch of documents, reacting to a status change, syncing data with an external system, or pausing for someone to check something before it's applied.
Workflows are managed in the Admin panel's Workflows section. The sidebar lists your workflows — searchable, with duplicate/rename/archive actions (archiving keeps the run history, it doesn't delete it) — plus a Connections entry for the external services steps can use.
Triggers
A workflow has exactly one trigger. Available triggers:
| Trigger | Fires when | Configuration |
|---|---|---|
| Manual (a pedido) | Someone fires it by hand, from one of four scopes: Genérico (no context — e.g. a dashboard button), Linha (a single record), Feature (several/all records of a feature), Vista (the rows currently visible in a view) | The scope, plus a source feature (Linha/Feature) or a view (Vista) |
| Upload de ficheiro | Documents are uploaded through the workflow's own upload dialog — one run per file | Accepted file extensions |
| Webhook | An external system sends a POST request to the workflow's own URL | The URL/token is generated for you (copy it, or regenerate to invalidate the old one), plus an optional description |
| Agendado (cron) | On a schedule | A simple interval (every N minutes/hours/days) or a calendar schedule (daily/weekly/monthly/yearly/once, or a raw cron expression), with timezone |
| Registo criado / Registo atualizado / Registo apagado | A row in a chosen feature is created, updated, or deleted | Feature to watch, a filter on the row's data; "Registo atualizado" also accepts a filter on the previous state (to model a transition, e.g. pending → paid) and a list of columns that must have changed |
Steps
Steps are grouped into five roles. The step palette (opened from the + on the canvas) is organized the same way, and the canvas colors each step's connector by role.
Sources — bring data in
| Step | Reads |
|---|---|
| CSV — ler ficheiro | An uploaded CSV (delimiter, header row) |
| Excel — ler folha | An uploaded Excel sheet |
| JSON — ler lista | A JSON array/object from a file or a variable |
| OCR — extrair documento | Structured fields from a document (PDF/image) via AI, per a schema you define |
| HTTP fetch | An external API's JSON response, turned into records — optionally through an HTTP connection |
| Ler feature (linhas) | Existing rows from a feature (filters, sort, limit) — the base for reconciliation workflows |
Transforms — reshape the data
| Step | Does |
|---|---|
| Mapear → colunas | Maps source fields to target feature columns, plus fixed values |
| Deduplicar | Compares each record against existing rows by one or more key fields and marks it insert / update / skip |
| Conciliar (match) | Reconciles two sets of records against each other (exact/numeric/date/fuzzy rules) and scores each match — e.g. bank movements vs invoices |
| Agente (emit-only) | Sends the current data to an AI agent with a prompt and a schema; the result merges into the workflow's variables (e.g. to classify a document type). The agent only proposes — it never writes anything itself |
Control — decide the path
| Step | Does |
|---|---|
| Condição (if/else) | Branches on a variable, record count, or the shape of the data |
| Agente escolhe a rota | An AI agent picks exactly one of several named routes you define (at least two); each route becomes its own lane on the canvas |
| Sub-workflow | Runs another workflow as a single step. By default it fires once with the current data (fire-and-forget); it can instead spawn one child run per record and wait for all of them to finish before continuing |
Gates — pause for a person
| Step | Does |
|---|---|
| Revisão humana | Pauses the run and shows the proposed data for someone to edit, approve, or reject. Rendering adapts to the data: plain fields (default), a table when the records map to a feature, a document viewer, email fields, or a single text block — set via "Formato de revisão". An optional confidence threshold can auto-approve records above it |
| Aprovação | A simple approve/reject checkpoint with a custom title and message — no records shown |
On Revisão humana, each record gets an insert / update / skip decision plus a reject toggle; approving writes the batch and resumes the run. If every record ends up rejected, the dialog instead offers Rejeitar e repetir (start a fresh run from the same source data) or Rejeitar e retomar (end this run without writing anything).
Sinks — the effect
| Step | Does |
|---|---|
| Importar (upsert) | Writes the approved records into the target feature: insert new ones, update matches (by the same key as Deduplicar), or skip. Safe to resume after a pause — it won't write the same record twice |
| Enviar email | Sends an email (recipients/subject/body), optionally with the workflow's files attached — via the global mail transport or a specific SMTP connection |
| Chamar tool MCP | Calls a tool on an external MCP server (e.g. an invoicing system) through an MCP connection |
Field values in a step's configuration can reference the workflow's data: {{vars.name}} for a workflow variable, {{record.field}} for the current record, {{records.2.field}} for a specific record by index.
Connections
Connections (Workflows → Connections) are reusable, pre-configured access to an external service, referenced by name from steps. Secrets are encrypted in the vault and can't be read back once saved — only replaced.
| Type | Stores | Used by |
|---|---|---|
| HTTP | Base URL, headers, auth, named endpoints | HTTP fetch |
| MCP | Server URL, auth (none / bearer token / custom header) | Chamar tool MCP |
| SMTP | Host, port, user, sender address, TLS | Enviar email |
| AI Provider | Provider, model, base URL (bring your own key) | OCR, agent steps |
AI steps (OCR, agent) work out of the box with the organization's configured AI settings — an AI Provider connection is only needed to use a different provider or key for a specific step. A saved connection can be checked with Testar ligação in its edit dialog.
Creating a workflow
From the Workflows sidebar, + starts a new workflow — from scratch or from a template:
- Começar do zero — an empty chain, built step by step.
- Importar CSV — CSV → map → dedupe → review → import.
- Importar documentos (OCR) — OCR → map → dedupe → review → import.
- Importar CSV (condicional) — the same CSV import, but review only kicks in above a record-count threshold.
- Agente revisor (confiança) — one agent drafts a reply, a second scores its confidence, and only low-confidence results go to human review before sending.
The editor shows the trigger as a pill at the top of the canvas, followed by the step chain: click the + on the connecting thread to insert a step there, click a step card to edit its configuration. Branching steps (if/else, AI-routed) fork the canvas into side-by-side lanes that merge back.
Changes are a draft until Guardar nova versão — saving creates a new version; earlier versions and their run history stay intact. A warnings band above the canvas flags incomplete configuration (e.g. a missing target feature); Executar is disabled while there are unsaved changes or unresolved errors.
Running a workflow
Manually, where the button appears depends on the trigger's scope:
- Genérico, Linha, Feature — the Workflow component, placed on a form or a table column; also available from the record detail panel's actions menu. Linha needs the button on a row or open form; Genérico and Feature work from any view.
- Feature / Vista — also (or, for Vista, only) the "Ações Globais" button in a table view's toolbar, under "AÇÕES DA TABELA" / "AÇÕES DA VISTA". The Workflow component refuses to fire a Vista-scoped workflow itself — it points you to this toolbar action instead.
Automatically, a workflow fires on its own once its trigger condition is met: a matching record change, a scheduled slot, or an incoming webhook call — no user action needed.
To test a workflow before wiring up its real trigger, use the editor's own Executar button: for file.upload it opens the real upload dialog; for every other trigger it opens a simulation dialog where you pick a real row or type JSON by hand. It still creates a real run — only the source of the input data is simulated.
Runs
Each workflow's editor shows its runs in a side panel, refreshing automatically while any are in progress.
| Status | Meaning |
|---|---|
| Pendente | Queued, not picked up yet |
| A correr | In progress |
| A rever / A aprovar | Paused at a Gate, waiting for a person |
| A aguardar | Paused waiting on a webhook, schedule, or child runs |
| Sucesso | Completed |
| Falhou | Failed — hover the error icon for the reason |
| Cancelado / Rejeitado | Stopped, or rejected at a Gate |
Selecting a run highlights where it is on the canvas, and adds a Rever/Aprovar button directly on the paused step. Each run's history icon opens a step-by-step timeline — status, timing, and (via the </> button) the exact input/output data of every step, for debugging.
A transient failure (e.g. a flaky external call) doesn't show as Falhou — the run goes back to Pendente and picks up automatically from where it stopped, up to a retry limit; the error icon shows the attempt count and the last failure reason.
Tips
- A workflow needs a trigger and at least one step — an empty chain can't run.
file.uploadneeds a target feature configured on amapstep before it lets you upload.- Auto-approval on Revisão humana is fail-closed: a missing confidence value, or one below the threshold, still goes to a person.
- Aprovação has no per-approver assignment — anyone who opens the run can approve or reject it.
- Nested Sub-workflow calls are capped at 5 levels, to avoid runaway recursion.
- Archiving a workflow stops it from firing but keeps its run history — nothing is deleted.