API Reference
/ai Endpoint
Ask currency questions in plain English, the AI endpoint understands the request and answers using live CurrencyCore rates.
The AI endpoint turns a natural-language question into a real answer. You send a
question as q; CurrencyCore interprets it, fetches live rates, performs any
conversion, and returns both a one-line answer and the structured data behind it.
On the Growth plan and higher it also answers historical trends,
comparisons, and “movers” (e.g. “how did EUR perform against USD over the last
decade?”) using the same engine as /history/analysis,
and purchasing-power-parity (PPP) over time (e.g. “has India’s PPP changed over
the last decade?”) via /ppp/analysis.
Endpoint
GET https://api.currency-core.com/v1/ai?q=<your question>
Requires an API key, like the other endpoints: Authorization: Bearer <key>.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | A natural-language question, e.g. Convert 50 euro to indian rupees or What's the USD to EUR rate today?. Max ~200 tokens. A longer q is rejected with 413 before the model runs and is not counted toward your usage. |
Response
{
"query": "Convert 50 euro to indian rupees",
"answer": "50 EUR = 5,520.68 INR at today's mid-market rate.",
"data": [
{
"from": "EUR",
"to": "INR",
"amount": 50,
"result": 5520.68011,
"rate": 110.413602,
"pppApplied": false,
"asOf": "2026-06-08"
}
],
"toolCalls": 1
}
Response fields
| Field | Type | Description |
|---|---|---|
query | string | Your question, echoed back. |
answer | string | A concise natural-language answer. |
data | array | The structured result object(s) returned by the tool(s) used to answer. Dynamic: each entry’s shape depends on the question (see below). Empty when no lookup was needed. |
toolCalls | number | How many tool calls the engine ran for this answer (convert, rates, analysis — the currency-resolution step isn’t counted). On a native answer this is informational (the whole request is one AI credit); with BYOK active you’re billed one API request per tool call. |
byok | boolean | Present only when BYOK is active: true if your own provider answered (billed as API requests), false if it fell back to CurrencyCore’s models (one AI credit). Omitted otherwise. |
Each entry in data is the response object returned by the tool that answered, so
its shape depends on the question and mirrors the matching endpoint:
- a conversion → a convert result (
from,to,amount,result,rate, …), see /convert - a rate lookup → a
base+ratesmap, see /rates - a trend / comparison (Growth+) → a history-analysis object, see /history/analysis
- a PPP-over-time question (Growth+) → a ppp-analysis object (
from/toyears, per-countrychangePct,series), see /ppp/analysis
It carries only result figures, no tool/process metadata, and the internal currency-resolution step is not included. The numbers always come from CurrencyCore’s live rates, the model never makes them up. When a question names a currency by word, symbol, or country (e.g. “euros”, ”₹”, “Indian rupees”, “Japan”), the model resolves it to the exact ISO 4217 code using the /currencies and /countries reference data before converting.
Historical analysis in data
For a trend or comparison question (Growth+), data carries one analysis object
that mirrors /history/analysis, with each currency’s
changePct, strengthenedPct (positive = appreciated vs base), stats
(min/max/avg), and a downsampled series for charting:
{
"query": "How did EUR perform against USD over the last decade?",
"answer": "EUR weakened about 5% against USD over the decade, from 0.90 to 0.95 per USD.",
"data": [
{
"base": "USD", "from": "2016-06-16", "to": "2026-06-16", "mode": "compare",
"results": [
{
"currency": "EUR",
"startRate": 0.90, "endRate": 0.95,
"changePct": 5.6, "strengthenedPct": -5.3,
"stats": { "min": 0.85, "max": 0.97, "avg": 0.91 },
"series": { "2016": 0.90, "2017": 0.89, "2026": 0.95 }
}
]
}
]
}
When you don’t name a timeframe, the window defaults to the last 20 years; the series granularity is chosen automatically from the window (yearly for long ranges, down to daily for short ones) so the response stays compact. For full control over the parameters, call /history/analysis directly.
Scope
The assistant answers only currency-conversion, foreign-exchange (FX) rate, and purchasing-power-parity (PPP) questions:
- Conversions, “Convert 1200 USD to JPY”, “how much is 75 pounds in euros”.
- Rates, “What’s the USD to INR rate today?”, “EUR rates for GBP, JPY, CAD”.
- Cost of living & salary equivalence (PPP), “I earn £50,000 in London, what’s the equivalent in Bangalore?”, “how far does $3,000 go in India vs the US?”. If you leave out the amount, the assistant asks for it before answering.
- Trends, comparisons & “movers” (Growth plan and higher), “How did EUR perform against USD over the last decade?”, “Which currencies strengthened most against INR since 2015?”, “Compare USD, GBP, EUR and AED over 20 years”. Named events resolve to date ranges too: “how did GBP do during COVID / after Brexit / in the 2008 financial crisis?”. On Free and Starter these return a short message asking you to upgrade to Growth.
- PPP over time (Growth plan and higher), “Has India’s PPP changed over the last decade?”, “Compare the PPP of India, Germany and the US since 2010”, “Which countries’ PPP rose most over 20 years?”. Same Growth+ gating as above.
- Volatility & stability (Growth plan and higher), “How volatile is EUR/USD?”, “Which are the most stable currencies against USD?”, “Compare the volatility of EUR, GBP and JPY”. Same Growth+ gating. See /volatility.
- Correlation, drawdown, safe-haven & mean-reversion (Growth plan and higher), “How correlated are EUR and GBP?”, “Which currencies had the largest drawdowns?”, “Which is the best safe-haven currency?”, “Compare CHF and JPY as safe havens”, “Which currencies are the most mean-reverting?”. See /correlation, /drawdown, /safe-haven, and /mean-reversion.
- Risk-adjusted return, strengthening streaks & stability (Growth plan and higher), “Which currency pair had the best risk-adjusted return over the last decade?” (Sharpe-like return ÷ volatility), “Which currencies strengthened against USD for at least 5 consecutive years?”, “Which currencies stayed within ±5% of USD over the last 5 years?”. These are measured against USD by default (computed live for a non-USD base) and answered from a daily-refreshed USD-benchmark precompute, so they return in a few seconds.
A related financial topic CurrencyCore doesn’t cover (commodities like oil, gas, or wheat, precious metals like gold/silver/platinum/palladium, stocks/indices, crypto, interest rates, or inflation/CPI) gets a specific one-line reply (“CurrencyCore doesn’t cover oil prices; only currencies, FX, and PPP”), not a generic refusal.
Anything else, other topics, or attempts to change the assistant’s behavior or
reveal its instructions (prompt injection), is refused with a static
422 unsupported_query. Your q is always treated as a question to answer,
never as instructions.
How PPP answers are kept honest
PPP is a conversion tool, not a verdict on a country’s economy. The assistant is deliberately conservative:
- A PPP-factor change over time is reported as a plain fact (start factor, end factor, % change). It is not described as purchasing power “improving” or “weakening”; the factor is a conversion coefficient that also moves with inflation, relative prices, GDP revisions, and IMF methodology.
- A cross-country purchasing-power ranking (“which country offers the highest
purchasing power?”, “where does my salary go furthest?”, “cheapest country to
live”) is declined (a normal
200): a bigger PPP factor only means a smaller currency unit, so ranking by it is meaningless, and a real answer needs cost-of-living data (local salaries, taxes, housing) CurrencyCore doesn’t have. A pairwise PPP comparison between two named places is still answered.
When the data isn’t available
An in-scope question whose data CurrencyCore doesn’t have is not an error. It
comes back as a normal 200 with the explanation in answer (and data: []):
- an unsupported currency or asset (e.g. precious metals like silver/XAG or gold/XAU, or an unknown code) → “Silver (XAG) isn’t a supported currency.”
- no rate for the requested date → “No rate is available for INR on that date.”
- PPP not available for that country/year → “PPP data isn’t available for that country/year.”
- an analysis too heavy to finish in real time → a
200asking you to narrow the request (“…covers too much data to complete in real time. Try a narrower window or fewer currencies.”), never a504.
If a question is missing a detail, or a currency shared by several countries needs
a country for a PPP adjustment (e.g. EUR), the answer is a short clarifying
question (“Which country should I use for EUR?”). A 503 (“AI unavailable”) now
means the AI service genuinely couldn’t run, not that your currency or data was the
problem.
How it counts against your limits
AI calls run on a separate AI credit pool, they do not count toward your
monthly API request limit. Each AI call consumes 1 AI credit: the monthly
allowance first, then any never-expiring purchased credits.
When both are exhausted, AI calls are blocked with 429 (no over-usage for AI).
You can turn the AI endpoint on or off per organization in the dashboard.
A request rejected as out of scope (422) still consumes a credit, the model
was consulted. A request rejected before the model runs because q is too long
(413) does not consume a credit.
On the Growth plan and higher you can Bring Your Own Keys (BYOK)
and run /ai on your own AI provider and model. When BYOK is active and your
provider answers, the call counts as a normal API request instead of an AI
credit. See the BYOK guide for the full metering rules.
Errors
| Status | Meaning |
|---|---|
400 invalid_input | q is missing. |
413 invalid_input | q exceeds the ~200-token limit. Rejected before the model runs, not counted toward usage. |
422 unsupported_query | The question is out of scope (currency / FX / PPP only). Counted, the model was consulted. |
403 forbidden | The AI endpoint is disabled for this organization. |
429 rate_limited | AI credit balance exhausted (monthly allowance + purchased), or the per-minute rate limit was hit. |
503 internal_error | The AI service is genuinely unavailable (no provider configured, or every provider unreachable), try again. A heavy analysis that can’t finish in time is not a 503 — it returns a normal 200 asking you to narrow the request. |
Example requests
curl -G https://api.currency-core.com/v1/ai \
--data-urlencode "q=Convert 50 euro to indian rupees" \
-H "Authorization: Bearer $CURRENCYCORE_KEY"const url = new URL("https://api.currency-core.com/v1/ai");
url.searchParams.set("q", "Convert 50 euro to indian rupees");
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.CURRENCYCORE_KEY}` },
});
const data = await res.json();
console.log(data.answer); // "50 EUR = 4,512.30 INR …"import requests
res = requests.get(
"https://api.currency-core.com/v1/ai",
params={"q": "Convert 50 euro to indian rupees"},
headers={"Authorization": f"Bearer {CURRENCYCORE_KEY}"},
)
print(res.json()["answer"])