Moneta como ferramenta de IA

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.

1. Duas ferramentas / Two tools

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

2. Schema das ferramentas / Tool schemas

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"]
  }
}

3. Executor das ferramentas / The tool executor

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 }]
  }
}

4. Exemplo end-to-end (OpenAI) / End-to-end (OpenAI)

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)."
Por que funciona bem: a resposta de /convert já traz rate, result e date juntos — o modelo cita a taxa e a data sem fazer conta nem inventar números.
Why it works: the /convert response carries rate, result and date together, so the model quotes the rate and date without doing arithmetic or hallucinating numbers.

5. Boas práticas / Best practices

Cache: conversões/cotações atuais são cacheadas ~1 h; datas passadas, 24 h. Para um agente, isso reduz latência e evita repetir chamadas idênticas.
Caching: latest conversions/rates are cached ~1 h; past dates 24 h. For an agent that cuts latency and avoids repeating identical calls.

API reference · Live demo · Back to Insyde APIs