Quanto dá 100 dólares em reais? E aqueles 1.500 euros da viagem? Quem compra em site do exterior, planeja férias fora do país ou recebe de cliente estrangeiro faz essa conta toda hora, quase sempre abrindo um site cheio de anúncios. Neste tutorial você vai montar no n8n o seu próprio conversor de moedas: uma página de formulário onde você digita o valor, escolhe a moeda de origem e a de destino, e recebe o resultado na hora, já com a cotação do dia e no formato brasileiro.
As cotações vêm da Frankfurter, uma API gratuita e de código aberto que não pede cadastro nem chave. O workflow tem só quatro nós e traz três coisas que ainda não apareceram na série: um formulário com campo de número e listas de opções, o HTTP Request com Query Parameters e o nó Edit Fields fazendo uma conta.
Qual a diferença para o tutorial do dólar no e-mail? No primeiro tutorial da série, o n8n manda sozinho, todo dia, a cotação de uma moeda (o dólar). Aqui é o contrário: é uma ferramenta que fica esperando você. Você escolhe o valor e as moedas (em qualquer direção, inclusive de real para outra moeda) e o n8n devolve a conta pronta. Outra API, outro gatilho e outra lição.
O que você vai construir

| Nó | O que faz | Comparando com o dia a dia |
|---|---|---|
| 1. On form submission | Mostra o formulário e recebe o valor e as duas moedas. | O balcão da casa de câmbio, onde você diz quanto quer trocar. |
| 2. Buscar cotação (HTTP Request) | Pergunta à API Frankfurter quanto vale a moeda de origem na moeda de destino. | O atendente olhando o painel de cotações. |
| 3. Calcular (Edit Fields) | Multiplica o valor pela cotação e guarda o total. | A calculadora. |
| 4. Mostrar resultado (Form Ending) | Mostra a última página do formulário com o resultado formatado. | O recibo com o valor final. |

Pré-requisitos
- Um n8n funcionando. Se ainda não tem, siga antes o tutorial n8n do zero com Docker.
- Acesso à internet a partir do n8n.
- Nenhuma conta ou chave: a API Frankfurter é aberta.
Versão usada: n8n 2.40.7. Os nomes de botões e campos aparecem em inglês, exatamente como na interface. Este tutorial continua a ideia do consultar CEP com formulário; se você ainda não conhece o Form Trigger, vale dar uma olhada nele também.
A API Frankfurter em 2 minutos
A Frankfurter reúne as taxas de câmbio que bancos centrais e outras fontes oficiais publicam todo dia útil, e entrega tudo num formato simples, em JSON. Na versão atual (v2) ela combina dados de mais de cem provedores, incluindo o Banco Central do Brasil, e cobre centenas de moedas. Não há cadastro, chave nem cota de uso; o serviço só limita abusos. E ele não guarda dados pessoais de quem consulta.
O endereço que vamos usar é este (abra no navegador para ver):
https://api.frankfurter.dev/v2/rates?base=USD"es=BRL
Tudo o que vem depois do ponto de interrogação são os parâmetros, os “pedidos” que você faz à API, no formato nome=valor e separados por &:
base: a moeda de origem (de onde você parte). Aqui,USD, o dólar americano.quotes: a moeda de destino (para onde você quer converter). Aqui,BRL, o real. Repare no s no fim do nome.
A resposta, no dia em que testei (03/10/2026), foi esta:
[{"date":"2026-10-03","base":"USD","quote":"BRL","rate":5.206}]
| Campo | Significado |
|---|---|
date | A data da cotação (formato ano-mês-dia). |
base | A moeda de origem. |
quote | A moeda de destino (no singular, na resposta). |
rate | Quanto vale 1 unidade da moeda de origem na moeda de destino: 1 dólar = 5,206 reais. |
As moedas são sempre escritas com o código de três letras do padrão internacional ISO 4217: USD (dólar americano), EUR (euro), BRL (real), GBP (libra esterlina), ARS (peso argentino) e JPY (iene japonês), por exemplo.
Cotação de referência, não preço de balcão. A Frankfurter entrega taxas de meio de mercado, publicadas por fontes oficiais. No cartão de crédito, na casa de câmbio ou em plataformas de pagamento entram tarifas, spread e impostos (como o IOF), então o valor que você paga ou recebe costuma ser diferente. Use o conversor para ter uma boa ideia do valor, não como recomendação financeira.
Uma curiosidade: a API não tem um endereço “converta 100 dólares”. A própria documentação sugere buscar a taxa e multiplicar pelo valor. É exatamente isso que o nó Calcular vai fazer.
Montando o workflow, nó por nó
No n8n, clique em Create workflow e dê o nome Conversor de moedas. Antes de começar, abra o menu … (três pontinhos) no topo, entre em Settings e confira o Timezone: escolha America/Sao_Paulo.
Nó 1: o formulário (On form submission)
Clique no + do canvas, procure por Form e escolha o gatilho On form submission. Ele cria uma página de formulário; quando alguém envia, o workflow começa. Preencha assim:
| Campo | Valor | Para que serve |
|---|---|---|
| Form Title | Conversor de moedas | O título que aparece no topo da página. |
| Form Description | Digite o valor e escolha as moedas. | Uma linha de instrução para quem preenche. |
| Form Elements | três campos (abaixo) | As perguntas do formulário. |
Em Form Elements, clique em Add Form Element três vezes:
| Field Name | Element Type | Configuração |
|---|---|---|
| Valor | Number | Placeholder: 100 · Required Field ligado. O tipo Number só aceita números, então ninguém digita “cem” por engano. |
| De | Dropdown | Opções: USD, EUR, BRL, GBP, ARS, JPY · Required Field ligado. |
| Para | Dropdown | Opções: BRL, USD, EUR, GBP, ARS, JPY (o real primeiro, porque é o destino mais comum) · Required Field ligado. |
O Dropdown é uma lista de opções, como o campo “estado” de um cadastro. Além de deixar o formulário mais rápido de preencher, ele garante que a API sempre recebe um código de moeda válido. Você pode trocar ou acrescentar moedas; só use o código de três letras.

Para testar, clique em Execute step. O n8n abre o formulário de teste numa aba nova. Preencha 100, USD e BRL e envie. De volta ao nó, o OUTPUT mostra um item com Valor, De e Para (além de submittedAt, a hora do envio).

Nó 2: buscar a cotação (HTTP Request com Query Parameters)
Clique no + à direita do formulário, escolha HTTP Request e renomeie para Buscar cotação (clique no nome no topo do nó). Configure:
| Campo | Valor |
|---|---|
| Method | GET (só vamos consultar) |
| URL | https://api.frankfurter.dev/v2/rates (sem o ponto de interrogação) |
| Send Query Parameters | ligado |
| Parâmetro 1 | Name: base · Value: arraste o campo De do INPUT → {{ $json.De }} |
| Parâmetro 2 | Add Parameter · Name: quotes · Value: arraste o campo Para → {{ $json.Para }} |
Nos vídeos anteriores, a gente escrevia o endereço inteiro na URL. Com Send Query Parameters, você informa cada pedido separado, com nome e valor, e o n8n monta o endereço completo, com o ? e o &. Fica mais fácil de ler, de trocar um valor e de usar dados do formulário sem errar a pontuação.

Clique em Execute step. A resposta da API é uma lista com um elemento só, e o n8n transforma isso em um item com date, base, quote e rate.
Nó 3: a conta (Edit Fields)
Agora vem a peça nova. Adicione o nó Edit Fields (Set) e renomeie para Calcular. Ele serve para criar ou alterar campos no item: você escolhe o nome, o tipo e o valor, que pode ser uma expressão com conta. Deixe Mode em Manual Mapping e clique em Add Field duas vezes:
| Nome | Tipo | Valor |
|---|---|---|
valor | Number | {{ $('On form submission').item.json.Valor }} |
total | Number | {{ $('On form submission').item.json.Valor * $json.rate }} |
Pegando um dado de um nó lá de trás
O $json sempre aponta para o item que chegou do nó imediatamente anterior. Só que o valor digitado está no formulário, dois nós atrás. Para buscá-lo, no painel INPUT, desça até o bloco On form submission e arraste o campo Valor. O n8n escreve sozinho $('On form submission').item.json.Valor: cifrão, o nome do nó entre parênteses e aspas, e o caminho até o campo. É como dizer: “pegue o Valor que está no nó On form submission”.
Dica: se você renomear o nó do formulário depois, o n8n atualiza essas referências automaticamente. Mas se digitar o nome à mão, ele tem que ser idêntico, com maiúsculas e espaços.
A conta
No campo total, arraste o Valor do formulário de novo, digite um asterisco (*, que é o sinal de vezes na programação) e arraste o rate do INPUT. A prévia logo abaixo do campo já mostra o resultado: 100 × 5,206 = 520,6. O tipo Number garante que o resultado é guardado como número, e não como texto.
Include Other Input Fields
Por padrão, o Edit Fields devolve só os campos que você criou. Ligue Include Other Input Fields para manter também o que já vinha (data, moedas e taxa), porque o último nó vai precisar deles. Execute o nó: o OUTPUT mostra date, base, quote, rate, valor e total.

Nó 4: a página do resultado (Form Ending)
Adicione o nó Form (o mesmo ícone do formulário, sem ser gatilho) e escolha a operação Form Ending, que é a última página do formulário. Renomeie para Mostrar resultado. Em On n8n Form Submission, deixe Show Completion Screen; em Completion Title, escreva Resultado; e em Completion Message, mude para Expression e cole:
{{ $json.valor.toLocaleString('pt-BR') }} {{ $json.base }} = {{ $json.total.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }} {{ $json.quote }}
Cotação de {{ $json.date.toDateTime().format('dd/MM/yyyy') }}: 1 {{ $json.base }} = {{ $json.rate.toLocaleString('pt-BR') }} {{ $json.quote }}
Lendo por partes:
$json.valor.toLocaleString('pt-BR')escreve o número do jeito brasileiro: 1500 vira 1.500.$json.total.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })faz o mesmo com o total, sempre com duas casas depois da vírgula (centavos): 520.6 vira 520,60.$json.date.toDateTime().format('dd/MM/yyyy')transforma o texto2026-10-03numa data e escreve 03/10/2026 (MM maiúsculo é mês; mm minúsculo seria minuto).$json.basee$json.quotecolocam os códigos das moedas; a quebra de linha separa o resultado da cotação.

Testando: viagem, compra e freelancer
Feche o nó e clique em Execute workflow, embaixo do canvas. O formulário de teste abre numa aba nova. Experimente casos do dia a dia (valores do teste de 03/10/2026; os seus vão variar com a cotação do dia):
| Situação | Preenchimento | Resultado no teste |
|---|---|---|
| Compra num site americano | 100 · USD · BRL | 100 USD = 520,60 BRL |
| Orçamento da viagem à Europa | 1500 · EUR · BRL | 1.500 EUR = 8.817,30 BRL |
| Freelancer recebendo em dólar | o valor da fatura · USD · BRL | quanto entra, em reais, na cotação de referência |
| Mesma moeda dos dois lados | 100 · USD · USD | 100 USD = 100,00 USD (taxa 1, sem erro) |
Também dá para converter no sentido contrário (por exemplo, BRL para USD, para saber quantos dólares compram 1.000 reais) ou entre duas moedas estrangeiras, como euro para peso argentino.

Erros comuns (testados)
Todos os erros abaixo foram reproduzidos no n8n de teste. Quando um nó falha, o formulário mostra apenas Problem submitting response; para saber o motivo, abra a aba Executions (ou olhe o nó vermelho no editor).

| O que aparece | Causa | Como resolver |
|---|---|---|
| Nó Buscar cotação vermelho: “Your request is invalid or could not be processed by the service” e “unknown parameter: quote” | O nome do parâmetro foi digitado errado (quote, sem o s). | Use quotes. A API só aceita os nomes que conhece, letra por letra. |
| “invalid currency: DOLAR” | O campo do parâmetro foi preenchido à mão (modo Fixed) com algo que não é código de moeda. | Use os códigos de três letras (USD, EUR, BRL…). Com a lista de opções do formulário, isso não acontece. |
| Nó Mostrar resultado vermelho: “toDateTime can’t be used on undefined value” | O Include Other Input Fields do Calcular ficou desligado: data, moedas e taxa sumiram do item. | Ligue Include Other Input Fields e execute de novo. |
| O resultado aparece como “520.6” ou com três casas | A mensagem usou o número direto, sem a formatação brasileira. | Use toLocaleString('pt-BR', …) como na expressão acima. |


Publicando: o endereço definitivo do formulário
Enquanto você testa, o formulário usa a Test URL, que só funciona com o editor aberto e depois de clicar em Execute workflow, e só para um envio de cada vez. Para deixar o conversor sempre disponível, clique em Publish, no canto superior direito, dê um nome à versão se quiser e confirme.

Depois disso, abra o nó do formulário e clique na aba Production URL. Esse é o endereço definitivo: copie, salve nos favoritos do navegador e use quando quiser, sem abrir o editor. Toda conversão fica registrada na aba Executions.


No computador ou num servidor?
| No seu computador (Docker) | Num servidor | |
|---|---|---|
| Para que serve | Teste e aprendizado | Produção |
| Quando funciona | Só com o computador e o Docker ligados | Sempre: é uma máquina na internet ligada 24 horas |
| Quem abre o formulário | Só você, no próprio computador (endereço com localhost) | Qualquer pessoa com o link, até pelo celular |
Atenção: publicar no n8n do seu computador não é o mesmo que colocar em produção. O endereço com localhost não abre no celular nem em outro computador. Levar o n8n para um servidor é um passo que a série vai dar mais adiante, com calma.
JSON do workflow para importar
Se preferir, importe o workflow pronto. Baixe o arquivo abaixo ou copie o JSON. No n8n, crie um workflow novo e escolha uma das opções: abra o menu … (três pontinhos) no topo do editor, vá em Import e depois em From file; ou cole o JSON direto no canvas com Ctrl+V. O workflow não usa credenciais.
O download é um arquivo .zip com o conversor-de-moedas-n8n.json dentro. Descompacte antes de importar (ou copie o JSON do bloco abaixo). Depois de importar, clique em Publish para ganhar a Production URL; o endereço do formulário muda de instalação para instalação.
{
"name": "Conversor de moedas",
"nodes": [
{
"parameters": {
"formTitle": "Conversor de moedas",
"formDescription": "Digite o valor e escolha as moedas.",
"formFields": {
"values": [
{
"fieldLabel": "Valor",
"fieldType": "number",
"placeholder": "100",
"requiredField": true
},
{
"fieldLabel": "De",
"fieldType": "dropdown",
"fieldOptions": {
"values": [
{
"option": "USD"
},
{
"option": "EUR"
},
{
"option": "BRL"
},
{
"option": "GBP"
},
{
"option": "ARS"
},
{
"option": "JPY"
}
]
},
"requiredField": true
},
{
"fieldLabel": "Para",
"fieldType": "dropdown",
"fieldOptions": {
"values": [
{
"option": "BRL"
},
{
"option": "USD"
},
{
"option": "EUR"
},
{
"option": "GBP"
},
{
"option": "ARS"
},
{
"option": "JPY"
}
]
},
"requiredField": true
}
]
},
"options": {}
},
"id": "6c0e7a10-1111-4b6e-9c06-0d0000000001",
"name": "On form submission",
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.6,
"position": [
0,
0
],
"webhookId": "6c0e7a10-aaaa-4b6e-9c06-0d00000000f1"
},
{
"parameters": {
"url": "https://api.frankfurter.dev/v2/rates",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "base",
"value": "={{ $json.De }}"
},
{
"name": "quotes",
"value": "={{ $json.Para }}"
}
]
},
"options": {}
},
"id": "6c0e7a10-2222-4b6e-9c06-0d0000000002",
"name": "Buscar cotação",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.5,
"position": [
260,
0
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "6c0e7a10-a001-4b6e-9c06-0d0000000a01",
"name": "valor",
"value": "={{ $('On form submission').item.json.Valor }}",
"type": "number"
},
{
"id": "6c0e7a10-a002-4b6e-9c06-0d0000000a02",
"name": "total",
"value": "={{ $('On form submission').item.json.Valor * $json.rate }}",
"type": "number"
}
]
},
"includeOtherFields": true,
"options": {}
},
"id": "6c0e7a10-3333-4b6e-9c06-0d0000000003",
"name": "Calcular",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
520,
0
]
},
{
"parameters": {
"operation": "completion",
"completionTitle": "Resultado",
"completionMessage": "={{ $json.valor.toLocaleString('pt-BR') }} {{ $json.base }} = {{ $json.total.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) }} {{ $json.quote }}\nCotação de {{ $json.date.toDateTime().format('dd/MM/yyyy') }}: 1 {{ $json.base }} = {{ $json.rate.toLocaleString('pt-BR') }} {{ $json.quote }}",
"options": {}
},
"id": "6c0e7a10-4444-4b6e-9c06-0d0000000004",
"name": "Mostrar resultado",
"type": "n8n-nodes-base.form",
"typeVersion": 2.5,
"position": [
780,
0
],
"webhookId": "6c0e7a10-bbbb-4b6e-9c06-0d00000000f2"
}
],
"connections": {
"On form submission": {
"main": [
[
{
"node": "Buscar cotação",
"type": "main",
"index": 0
}
]
]
},
"Buscar cotação": {
"main": [
[
{
"node": "Calcular",
"type": "main",
"index": 0
}
]
]
},
"Calcular": {
"main": [
[
{
"node": "Mostrar resultado",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1",
"timezone": "America/Sao_Paulo"
},
"meta": {
"templateCredsSetupCompleted": false
}
}
Para ir além
- Mais moedas: acrescente opções nos dois Dropdowns (por exemplo
CAD,CHF,CLP). A lista completa está emhttps://api.frankfurter.dev/v2/currencies. - Várias moedas de uma vez: o parâmetro
quotesaceita uma lista separada por vírgula (quotes=BRL,EUR,GBP), e a API devolve um item por moeda. É um bom exercício para depois. - Cotação de uma data passada: a API também aceita o parâmetro
date(formato ano-mês-dia), útil para conferir quanto valia uma fatura no dia em que foi paga. - Receber no celular: se quiser um aviso automático em vez de um formulário, veja o tutorial do lembrete no celular com ntfy.
Recapitulando
- O On form submission aceita campos Number e Dropdown; a lista de opções evita valores inválidos.
- Com Send Query Parameters, o HTTP Request monta o endereço com
?e&sozinho. - O Edit Fields cria campos novos e faz contas;
$('Nome do nó')busca dados de um nó que não é o imediatamente anterior. - Include Other Input Fields mantém os campos que já vinham no item.
toLocaleString('pt-BR')eformat('dd/MM/yyyy')deixam número e data no padrão brasileiro.- Depois do Publish, a Production URL é o endereço definitivo do formulário.
Começamos pelo mais simples e estamos evoluindo juntos, um passo de cada vez. Nos próximos tutoriais, a série vai subir o nível com APIs mais sofisticadas e ganhar trilhas novas de projetos reais: uma inspirada em vagas de emprego e outra de monitoramento e DevOps.
Próxima etapa da trilha: no tutorial Preço da Tabela FIPE no n8n com formulário (API gratuita, sem cadastro), a Etapa 7 da Trilha Iniciante, você encadeia dois HTTP Requests: o primeiro busca os anos do modelo, o Filter escolhe o ano digitado e o segundo traz o preço médio do carro.
Fontes
- Frankfurter: documentação da API (v2, endpoint /rates, parâmetros base e quotes, provedores e moedas): https://frankfurter.dev/
- Frankfurter: código-fonte do projeto: https://github.com/lineofflight/frankfurter
- n8n Docs: n8n Form Trigger node: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.formtrigger/
- n8n Docs: n8n Form node (Form Ending): https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.form/
- n8n Docs: HTTP Request node: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/
- n8n Docs: Edit Fields (Set) node: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/
- n8n Docs: dados de nós anteriores em expressões ($(‘nome do nó’)): https://docs.n8n.io/code/builtin/output-other-nodes/
- ISO 4217 (códigos de moeda): https://www.iso.org/iso-4217-currency-codes.html
- Testes próprios no n8n 2.40.7 local, em 03/10/2026 (cotações daquele dia).
Preço da Tabela FIPE no n8n com formulário (API gratuita, sem cadastro)
Monte no n8n uma consulta à Tabela FIPE: digite o código FIPE e o ano e veja o preço médio do carro na hora, com dois HTTP Requests encadeados e…