API Reference
/convert Endpoint
Complete reference for the currency conversion endpoint, including PPP adjustment and the triangulation formula.
Endpoint
GET https://api.currency-core.com/v1/convert
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Source currency (ISO 4217), e.g. USD. When ppp=true, pair it with its country as currency:country (e.g. USD:USA). |
to | string | Yes | One or more target currencies, comma-separated. Each item is a bare currency (INR) or, when ppp=true, a currency:country pair (INR:IND). Max 25. |
amount | number | Yes | Amount to convert (positive number). |
date | string | No | Rate date in YYYY-MM-DD, interpreted as a UTC date. Must not be in the future. Defaults to the latest available. |
ppp | boolean | No | When true, apply a PPP adjustment. Every currency (source + each target) must then carry a country code. |
All dates are UTC. The date you pass is treated as a UTC calendar date, and
when omitted the latest available UTC rate date is used — so results don’t shift
with the caller’s local timezone. Future dates are rejected with
400 invalid_input (there are no rates ahead of today).
The PPP year follows the date’s year (e.g. date=2021-06-01 uses 2021 PPP
factors). When date is omitted, the latest published PPP year is used. A
back-dated request only uses actual (non-projected) PPP data — see
Data availability below.
Country codes are ISO/IMF alpha-3 (e.g. USA, IND, DEU). Look them up
via the /countries endpoint.
Multiple target currencies
to accepts a comma-separated list, so one call can fan out to many currencies:
?from=USD&amount=100&to=INR,EUR,JPY
PPP: pass a country with every currency
PPP is country-specific, and a currency is used by many countries — so the
country can’t be inferred from the currency. When ppp=true, pair each currency
with its country as currency:country, for both from and every to. This is
also how the same currency targets multiple countries (different PPP factor,
different result):
?from=USD:USA&amount=100&ppp=true&to=INR:IND,EUR:DEU,EUR:FRA
The currency in each pair must be an official currency of that country (the
country’s PPP factor is denominated in that currency) — so INR:IND is valid but
EUR:IND is not. Pairs are validated per target: a bad pair only fails that
target’s PPP (see Per-target PPP errors below), not the
whole request. Use /countries to see each country’s
currencies.
Response
The response always returns a results array — one entry per requested target.
When PPP is not requested, the fromCountry, toCountry, and ppp fields are
omitted entirely:
{
"from": "USD",
"amount": 100,
"date": "2024-11-01",
"results": [
{ "to": "INR", "result": 8345.00, "rate": 83.45 },
{ "to": "EUR", "result": 92.30, "rate": 0.923 }
]
}
With PPP enabled, result is still the plain FX conversion — the
PPP-adjusted amount lives in ppp.result. The source country appears once at the
top level as fromCountry, and each result carries its toCountry and ppp
block (note EUR appears twice — once per country):
{
"from": "USD",
"fromCountry": "USA",
"amount": 100,
"date": "2024-11-01",
"results": [
{ "to": "INR", "toCountry": "IND", "result": 8345.00, "rate": 83.45, "ppp": { "fromFactor": 1.0, "toFactor": 2.0, "result": 4172.50 } },
{ "to": "EUR", "toCountry": "DEU", "result": 92.30, "rate": 0.923, "ppp": { "fromFactor": 1.0, "toFactor": 1.40, "result": 65.93 } },
{ "to": "EUR", "toCountry": "FRA", "result": 92.30, "rate": 0.923, "ppp": { "fromFactor": 1.0, "toFactor": 1.35, "result": 68.37 } }
]
}
Response fields
| Field | Type | Description |
|---|---|---|
from | string | The source currency you requested. |
fromCountry | string | Source country (alpha-3). Present only when PPP was requested; shared by all results. |
amount | number | The input amount, echoed back. |
date | string | The rate date actually used (YYYY-MM-DD, UTC). |
message | string | Present only when no FX data exists for date (then results is empty). |
results | array | One entry per requested target — see below. |
results[].to | string | The target currency. |
results[].toCountry | string | Target country (alpha-3). Present only when PPP was requested. |
results[].result | number | Plain FX conversion — never PPP-adjusted. |
results[].rate | number | Effective FX rate applied (result / amount). |
results[].ppp | object | The PPP detail. Present only when PPP was requested. It is a union: either the success shape (fromFactor, toFactor, result) or an error shape (error) — never both. |
results[].ppp.fromFactor | number | Source country’s PPP conversion factor. Present on success; absent when ppp.error is set. |
results[].ppp.toFactor | number | Target country’s PPP conversion factor. Present on success; absent when ppp.error is set. |
results[].ppp.result | number | PPP-adjusted amount: result × (fromFactor / toFactor). Present on success; absent when ppp.error is set. |
results[].ppp.error | string | Set instead of the factors when this target’s PPP couldn’t be applied. The FX fields (result, rate) are still returned, and the response is still HTTP 200. |
Per-target PPP errors
PPP is resolved per target. If one target’s PPP can’t be applied, only
that target’s ppp becomes { "error": ... } — the others still get
factors, and the FX fields (result, rate) are always returned for every
target. The response stays HTTP 200 even when some targets carry a
ppp.error. (If the from pair itself is bad, every target’s ppp is an error,
but FX is still returned for each.)
Each currency:country pair must be consistent: the currency must be an
official currency of that country (the country’s PPP factor is denominated in
that currency). ppp.error carries one of:
ppp.error value | When |
|---|---|
Invalid country code: <C> | <C> is not a known alpha-3 country code. |
<CUR> is not an official currency of <C> | The currency and country don’t match (e.g. EUR:IND). |
No PPP data available for <C> | The country is valid but has no PPP factor for the requested year. |
A country is required for PPP (e.g. INR:IND) | A currency:country pair was missing its country. |
Example — two INR:IND and EUR:IND targets where the second’s currency doesn’t
match the country, so only its ppp is an error:
{
"from": "USD",
"fromCountry": "USA",
"amount": 100,
"date": "2024-11-01",
"results": [
{ "to": "INR", "toCountry": "IND", "result": 8345.00, "rate": 83.45, "ppp": { "fromFactor": 1.0, "toFactor": 2.0, "result": 4172.50 } },
{ "to": "EUR", "toCountry": "IND", "result": 92.30, "rate": 0.923, "ppp": { "error": "EUR is not an official currency of IND" } }
]
}
Data availability & limits
These responses return HTTP 200 (the request succeeded), with a message
explaining what was missing:
PPP data not available for the year — the FX conversion is still returned;
each affected target’s ppp carries an error instead of factors:
{
"from": "USD",
"fromCountry": "USA",
"amount": 100,
"date": "2010-01-04",
"results": [
{ "to": "INR", "toCountry": "IND", "result": 4520.00, "rate": 45.20, "ppp": { "error": "No PPP data available for IND" } }
]
}
No FX data for the date — results is empty and a top-level message
explains it:
{
"from": "USD",
"amount": 100,
"date": "1990-01-01",
"results": [],
"message": "Conversion data is not available for 1990-01-01."
}
How this counts against your limits
- Monthly usage limit — only successful requests (HTTP 2xx) are counted, including the two availability messages above. Requests that error (4xx/5xx — invalid input, unknown currency, a missing PPP country, rate-limit, or quota exceeded) are not counted toward your monthly limit.
- Rate limit — applies to every request regardless of its status, so retries and errored calls still consume your per-window rate budget.
Triangulation formula
CurrencyCore stores all rates as units of currency per 1 USD (i.e., USD is the base). Converting from any currency A to any currency B uses USD as the intermediary:
result = (amount / fromRate) * toRate
Where:
fromRate= units of currency A per 1 USDtoRate= units of currency B per 1 USD
Example: 100 GBP → INR where GBP rate = 0.79, INR rate = 83.45
result = (100 / 0.79) * 83.45 = 10563.29 INR
PPP adjustment formula
When ppp=true, result is still the plain FX conversion. The PPP-adjusted
amount is returned separately as ppp.result, so you get both numbers:
result = (amount / fromRate) * toRate // plain FX, always present
ppp.result = result * (fromFactor / toFactor) // PPP-adjusted, only when ppp=true
Where fromFactor and toFactor are the PPP conversion factors for the source
and target countries. This separation lets you show the market price and the
purchasing-power-adjusted price side by side.
Example requests
Simple conversion:
curl "https://api.currency-core.com/v1/convert?from=EUR&to=JPY&amount=50" \
-H "Authorization: Bearer cc_live_your_key"const res = await fetch(
"https://api.currency-core.com/v1/convert?from=EUR&to=JPY&amount=50",
{ headers: { Authorization: "Bearer cc_live_your_key" } },
);
const data = await res.json();
console.log(data.results[0].result);import requests
res = requests.get(
"https://api.currency-core.com/v1/convert",
params={"from": "EUR", "to": "JPY", "amount": 50},
headers={"Authorization": "Bearer cc_live_your_key"},
)
print(res.json()["results"][0]["result"])req, _ := http.NewRequest("GET",
"https://api.currency-core.com/v1/convert?from=EUR&to=JPY&amount=50", nil)
req.Header.Set("Authorization", "Bearer cc_live_your_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.currency-core.com/v1/convert?from=EUR&to=JPY&amount=50"))
.header("Authorization", "Bearer cc_live_your_key")
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());<?php
$ch = curl_init("https://api.currency-core.com/v1/convert?from=EUR&to=JPY&amount=50");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer cc_live_your_key"]);
echo curl_exec($ch);
curl_close($ch);Historical rate:
curl "https://api.currency-core.com/v1/convert?from=USD&to=GBP&amount=1000&date=2023-01-15" \
-H "Authorization: Bearer cc_live_your_key"
Multiple target currencies:
curl "https://api.currency-core.com/v1/convert?from=USD&to=INR,EUR,JPY&amount=100" \
-H "Authorization: Bearer cc_live_your_key"
With PPP adjustment (one country):
curl "https://api.currency-core.com/v1/convert?from=USD:USA&to=INR:IND&amount=100&ppp=true" \
-H "Authorization: Bearer cc_live_your_key"
PPP across multiple countries (same currency, different PPP):
curl "https://api.currency-core.com/v1/convert?from=USD:USA&amount=100&ppp=true&to=INR:IND,EUR:DEU,EUR:FRA" \
-H "Authorization: Bearer cc_live_your_key"