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. History goes back to 1949; a non-trading day resolves to the most recent earlier snapshot (see requestedDate/asOf below). |
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: country auto-resolution
When ppp=true, the API automatically resolves the country for most currencies using a canonical default — you do not need to pass currency:country for common cases:
# Simple — country resolved automatically (USD→USA, INR→IND, EUR→DEU)
?from=USD&amount=100&ppp=true&to=INR,EUR
For currencies used in many countries without a single clear home (e.g. XCD covering 8 Caribbean islands), the API cannot pick one automatically and will return a per-target error asking you to specify:
# Explicit — required for ambiguous currencies, or to target a specific country
?from=USD:USA&amount=100&ppp=true&to=INR:IND,EUR:DEU,EUR:FRA
This is also how you target the same currency across multiple countries (each country has a different PPP factor):
?from=USD:USA&amount=100&ppp=true&to=EUR:DEU,EUR:FRA,EUR:ITA
The currency in each explicit 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. PPP is a price-level conversion
of your amount, bridged through the international dollar:
ppp.result = amount × (toFactor / fromFactor)
It deliberately does not use the nominal FX rate. PPP replaces the market
rate, it doesn’t compound it. So $100 in the US (factor 1.0) into India
(factor 20.4) is 100 × (20.4 / 1.0) ≈ ₹2,040 (“what $100 of US goods costs in
India”), independent of the ~₹83/$ market rate. Each ppp block also reports the
year and source of the factors. 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": 20.4, "result": 2040.00, "year": 2024, "source": "IMF World Economic Outlook" } },
{ "to": "EUR", "toCountry": "DEU", "result": 92.30, "rate": 0.923, "ppp": { "fromFactor": 1.0, "toFactor": 0.72, "result": 72.00, "year": 2024, "source": "IMF World Economic Outlook" } },
{ "to": "EUR", "toCountry": "FRA", "result": 92.30, "rate": 0.923, "ppp": { "fromFactor": 1.0, "toFactor": 0.74, "result": 74.00, "year": 2024, "source": "IMF World Economic Outlook" } }
]
}
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). On a non-trading day this is the most recent earlier snapshot. |
requestedDate | string | The date you asked for. Present only when it differs from date (the requested date had no snapshot, so an earlier one was used). |
asOf | object | Currencies among from/targets whose rate was carried forward → the date it’s from. Present only when at least one rate was carried forward. |
message | string | Present only when no FX data exists at or before 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, year, source) or an error shape (error), never both. |
results[].ppp.fromFactor | number | Source country’s PPP conversion factor (local units per international $). Present on success; absent when ppp.error is set. |
results[].ppp.toFactor | number | Target country’s PPP conversion factor (local units per international $). Present on success; absent when ppp.error is set. |
results[].ppp.result | number | PPP-adjusted amount: amount × (toFactor / fromFactor), a price-level conversion via the international dollar, independent of the FX rate. Present on success; absent when ppp.error is set. |
results[].ppp.year | number | Year of the PPP conversion factors used. Present on success. |
results[].ppp.source | string | Provider of the PPP factors (IMF World Economic Outlook). Present on success. |
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"