Wire daily exchange rates into an LLM via function calling
A Moneta API é uma tool ideal para IA: aberta, sem chave, CORS liberado e com saída JSON plana. Os códigos são ISO 4217 — que os modelos já conhecem de cor. Este guia expõe a API como duas funções e deixa o modelo converter valores e ler cotações sozinho.
The Moneta API is an ideal AI tool: open, keyless, CORS-enabled, and with flat JSON output. Codes are ISO 4217 — which models already know by heart. This guide exposes the API as two functions and lets the model convert amounts and read rates on its own.
Base: https://moneta.api.insyde.one — aberta, sem autenticação / open, no auth.
Quase tudo se resolve com duas funções: converter um valor entre moedas e ler cotações de referência. O modelo encadeia sozinho.
Almost everything is solved with two functions: convert an amount between currencies and read rates. The model chains them on its own.
// 1. Usuário: "quanto custa 500 dólares em reais?"
// 2. Modelo chama: moneta_convert({ from: "USD", to: "BRL", amount: 500 })
// 3. API responde { rate: 5.0203, result: 2510.15, date: "2026-06-03" }
// 4. Modelo responde com o valor + a taxa e a data usadas
OpenAI (tools / function calling):
[
{
"type": "function",
"function": {
"name": "moneta_convert",
"description": "Convert an amount between two currencies using official central-bank reference rates. Returns the rate, the result and the rate date.",
"parameters": {
"type": "object",
"properties": {
"from": { "type": "string", "description": "Source currency, ISO 4217 (e.g. 'USD')" },
"to": { "type": "string", "description": "Target currency, ISO 4217 (e.g. 'BRL')" },
"amount": { "type": "number", "description": "Amount to convert (default 1)" },
"date": { "type": "string", "description": "Optional past date, YYYY-MM-DD" }
},
"required": ["from", "to"]
}
}
},
{
"type": "function",
"function": {
"name": "moneta_rates",
"description": "Read reference exchange rates for one base against one or more quote currencies. Pass from/to for a time series. Codes are ISO 4217.",
"parameters": {
"type": "object",
"properties": {
"base": { "type": "string", "description": "Base currency (default EUR)" },
"quotes": { "type": "string", "description": "Comma-separated targets, e.g. 'BRL,USD'" },
"date": { "type": "string", "description": "Single past date, YYYY-MM-DD" },
"from": { "type": "string", "description": "Series start, YYYY-MM-DD" },
"to": { "type": "string", "description": "Series end, YYYY-MM-DD" }
},
"required": []
}
}
}
]
Anthropic (tools): mesma ideia — o campo input_schema recebe o mesmo objeto de parameters acima. / same idea — input_schema takes the same object as parameters above.
{
"name": "moneta_convert",
"description": "Convert an amount between two currencies using official central-bank reference rates.",
"input_schema": {
"type": "object",
"properties": {
"from": { "type": "string" },
"to": { "type": "string" },
"amount": { "type": "number" },
"date": { "type": "string" }
},
"required": ["from", "to"]
}
}
As duas funções são apenas fetch na Moneta API. Sem estado, sem chave:
Both functions are just a fetch against the Moneta API. Stateless, keyless:
const BASE = 'https://moneta.api.insyde.one';
async function runTool(name, args) {
if (name === 'moneta_convert') {
const qs = new URLSearchParams({
from: args.from, to: args.to, amount: args.amount ?? 1,
});
if (args.date) qs.set('date', args.date);
const r = await fetch(`${BASE}/convert?${qs}`);
if (!r.ok) return { error: (await r.json()).error };
return r.json(); // { date, from, to, amount, rate, result }
}
if (name === 'moneta_rates') {
const qs = new URLSearchParams();
if (args.base) qs.set('base', args.base);
if (args.quotes) qs.set('quotes', args.quotes);
if (args.date) qs.set('date', args.date);
if (args.from) qs.set('from', args.from);
if (args.to) qs.set('to', args.to);
const r = await fetch(`${BASE}/rates?${qs}`);
if (!r.ok) return { error: (await r.json()).error };
return r.json(); // [{ date, base, quote, rate }]
}
}
import OpenAI from 'openai';
const client = new OpenAI();
const messages = [{ role: 'user', content: 'Quanto custa 500 dólares em reais?' }];
while (true) {
const res = await client.chat.completions.create({
model: 'gpt-4o', messages, tools: MONETA_TOOLS,
});
const msg = res.choices[0].message;
messages.push(msg);
if (!msg.tool_calls) { console.log(msg.content); break; }
for (const call of msg.tool_calls) {
const out = await runTool(call.function.name, JSON.parse(call.function.arguments));
messages.push({ role: 'tool', tool_call_id: call.id, content: JSON.stringify(out) });
}
}
// → "500 dólares equivalem a R$ 2.510,15 (taxa 5,0203, em 2026-06-03)."
/convert já traz rate,
result e date juntos — o modelo cita a taxa e a data sem fazer conta nem
inventar números.
/convert response carries rate,
result and date together, so the model quotes the rate and date without doing
arithmetic or hallucinating numbers.
amount default em 1 quando o usuário só quer a cotação ("quanto está o euro?"). / Default amount to 1 when the user just wants the rate ("what's the euro at?")./currencies raramente é necessário como tool — os códigos são ISO 4217 e o modelo já os conhece. Adicione só se precisar de símbolo/nome oficial. / The /currencies tool is rarely needed — codes are ISO 4217 and the model already knows them. Add it only if you need the symbol/official name.