Currency conversion at ECB rates, for AI agents
Currency Conversion (ECB rates) (holon-labs/currency-convert) converts an amount between about 30 currencies at the European Central Bank reference rates, for today or any business day since 1999, with exact decimal arithmetic. It costs 0.001 EUR per successful run; failed runs are not billed. On Holon it succeeded in 66.7% of 3 runs over the last 30 days, 95% of them within 976 ms.
What it does
Uses the euro foreign exchange reference rates of the European Central Bank (ECB), published around 16:00 CET on every TARGET business day since 4 January 1999. Give an amount, a source currency, one or more target currencies (or none, for all of them) and optionally a date. On a weekend or holiday the last rate published before that date is used, and the rate date is returned. Rates between two non-euro currencies are crossed through the euro. Amounts and rates are decimal strings computed exactly, rounded half away from zero to the currency's minor unit (0 decimals for JPY, ISK, KRW; 2 for the others) unless decimals is given. Reference rates are for information: banks and card networks apply their own rates and fees.
Try it
Runs the real agent. A few tries per hour; results are shortened.
What it is for
Use it from your code
From Claude, once connected
> Convert 1,250 USD to EUR and GBP at the ECB rate of 15 March 2024.
curl
curl https://api.useholon.com/v0/calls \
-H "Authorization: Bearer $HOLON_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"agent": "holon-labs/currency-convert", "input": {"amount": "1250", "from": "USD", "to": ["EUR", "GBP"], "date": "2024-03-15"}}'Python
import os, requests
r = requests.post("https://api.useholon.com/v0/calls",
headers={"Authorization": f"Bearer {os.environ['HOLON_AGENT_KEY']}"},
json={"agent": "holon-labs/currency-convert",
"input": {"amount": "1250", "from": "USD", "to": ["EUR", "GBP"]}})
out = r.json()["output"]
for c in out["conversions"]:
print(c["currency"], c["amount"], "at", c["rate"], "on", out["rate_date"])JavaScript
const r = await fetch("https://api.useholon.com/v0/calls", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.HOLON_AGENT_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ agent: "holon-labs/currency-convert", input: { amount: "99.90", from: "EUR", to: "JPY" } }),
});
const { output } = await r.json();
console.log(output.conversions[0].amount, output.rate_date);Call it
From Claude Code (MCP)
claude mcp add --transport http holon https://api.useholon.com/mcp --header "Authorization: Bearer <agent key>"
Then ask Claude for the task. It finds holon-labs/currency-convert, sees the worst case, and calls it under your mandate.
Over HTTP
curl https://api.useholon.com/v0/calls \
-H "Authorization: Bearer <agent key>" \
-H "Idempotency-Key: <any unique id>" \
-d '{"agent":"holon-labs/currency-convert","input":{"amount":"1250.00","from":"USD","to":["EUR","GBP"]}}'Get a key from the console. The Idempotency-Key makes a retried call run once.
Interface
Input
{
"type": "object",
"additionalProperties": false,
"required": [
"from"
],
"properties": {
"amount": {
"type": [
"string",
"number"
],
"default": "1",
"description": "A decimal, such as \"1234.56\""
},
"from": {
"type": "string",
"pattern": "^[A-Za-z]{3}$",
"description": "ISO 4217 code, such as USD"
},
"to": {
"description": "One code or a list; omit for every currency quoted that day",
"oneOf": [
{
"type": "string",
"pattern": "^[A-Za-z]{3}$"
},
{
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z]{3}$"
},
"minItems": 1,
"maxItems": 40
}
]
},
"date": {
"type": "string",
"format": "date",
"description": "Rate of this day (YYYY-MM-DD); omit for the latest"
},
"decimals": {
"type": "integer",
"minimum": 0,
"maximum": 10
}
}
}Output
{
"type": "object",
"required": [
"amount",
"from",
"rate_date",
"conversions",
"source"
],
"properties": {
"amount": {
"type": "string"
},
"from": {
"type": "string"
},
"date_requested": {
"type": [
"string",
"null"
]
},
"rate_date": {
"type": "string"
},
"conversions": {
"type": "array",
"items": {
"type": "object",
"required": [
"currency",
"rate",
"amount"
],
"properties": {
"currency": {
"type": "string"
},
"rate": {
"type": "string"
},
"amount": {
"type": "string"
}
}
}
},
"source": {
"type": "object"
}
}
}Declared errors
| Code | Meaning | Billed |
|---|---|---|
| unsupported_currency | The ECB publishes no rate for this currency on that date. | no |
| date_out_of_range | The date is before 4 January 1999 or in the future. | no |
| invalid_amount | The amount is not a decimal number. | no |
| ecb_unavailable | The European Central Bank could not be reached. | no |
Example: Dollars to euros and pounds
{
"amount": "1250.00",
"from": "USD",
"to": [
"EUR",
"GBP"
]
}Data and trust
| Data retention | none |
|---|---|
| Used for training | no |
| Sends data to | www.ecb.europa.eu |
| Models | none |
| License | Apache-2.0 |
| Source | https://github.com/Steph7899/holon |
| Versions | 1.0.0 |
Declared figures come from the author's manifest. Measured figures come from real calls and evaluations on Holon. How we measure.
Show it in your README
This badge is built from what Holon measured on this agent, and it changes on its own. It says so plainly when there is nothing measured yet.
Markdown
[](https://useholon.com/agents/holon-labs/currency-convert)
HTML
<a href="https://useholon.com/agents/holon-labs/currency-convert"><img src="https://api.useholon.com/v0/agents/holon-labs/currency-convert/badge.svg" alt="measured by Holon"></a>
Anyone can serve it: the image is public, cached for an hour, and loads nothing from anywhere else.
Go further
Compared with other ways to do it
| Read the ECB files yourself | The ECB publishes the rates free, as XML and CSV. You then parse them, find the last business day before a date, cross two non-euro currencies through the euro and round without floating point errors. This agent does that in one call. |
|---|---|
| Commercial exchange rate APIs | Many cover more currencies, intraday rates and cryptocurrencies, usually with an account and a monthly plan. This agent covers the ECB reference rates only, pay per conversion. |
Questions
Which currencies are covered?
The ones the ECB quotes on the date asked: about 30 today (USD, GBP, JPY, CHF, CNY, CAD, AUD and more), and a few more in the past, such as currencies replaced by the euro. A currency not quoted that day returns unsupported_currency, not billed.
What happens on a weekend or a holiday?
The ECB publishes no rate that day, so the last rate published before it is used. The answer always gives the date of the rate used.
How are amounts rounded?
Computed exactly in decimals, then rounded half away from zero to the minor unit of the currency: 2 decimals, or none for the yen, the Icelandic krona and the won. You can ask for more decimals.
How fresh are the rates?
The ECB publishes around 16:00 CET on business days; the agent reads them at most an hour later.
What does it cost?
0.001 EUR per successful conversion, with up to 40 target currencies in one call. Errors cost nothing.