Quickstart

Base URL
https://api.yourdomain.com/v1
Auth
API key via Authorization: Bearer <YOUR_API_KEY>
Content-Type
application/json
Timeout
30s recommended

Test a request

GET /v1/rates/latest?base=USD&symbols=EUR,GBP
curl -s --request GET \
  --url "https://api.yourdomain.com/v1/rates/latest?base=USD&symbols=EUR,GBP" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Accept: application/json"

Tip: Keep your API key secret; never embed it in client-side code or public repos.

Authentication

Use an API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

HTTP Status

StatusMeaning
401 UnauthorizedMissing or invalid API key
403 ForbiddenKey lacks permission for this endpoint

Endpoints

GET /v1/rates/latest

Returns the latest available rates for a base currency.

GET /v1/rates/latest?base=USD&symbols=EUR,GBP
QueryTypeRequiredDescription
basestring (ISO 4217)YesBase currency (e.g., USD)
symbolsstringNoComma-separated list of target symbols (e.g., EUR,GBP)
{
  "timestamp": "2025-10-09T13:17:00Z",
  "base": "USD",
  "rates": {
    "EUR": 0.9204,
    "GBP": 0.7691
  }
}

GET /v1/rates/{date}

Returns historical rates for a specific date (UTC).

GET /v1/rates/2025-09-01?base=EUR&symbols=USD,GBP
Path/QueryTypeRequiredDescription
{date}string (YYYY-MM-DD)YesDate to fetch
basestringYesBase currency
symbolsstringNoTargets to include
{
  "date": "2025-09-01",
  "base": "EUR",
  "rates": {
    "USD": 1.0872,
    "GBP": 0.8515
  }
}

GET /v1/convert

Converts an amount between two currencies using latest or historical rates.

GET /v1/convert?from=USD&to=JPY&amount=123.45
QueryTypeRequiredDescription
fromstringYesSource currency
tostringYesTarget currency
amountnumberYesAmount to convert
datestringNoHistorical date (YYYY-MM-DD). Defaults to latest.
{
  "from": "USD",
  "to": "JPY",
  "amount": 123.45,
  "rate": 149.21,
  "converted": 1841.45,
  "timestamp": "2025-10-09T13:17:00Z",
  "source": "latest"
}

GET /v1/symbols

Lists supported currencies and their names.

GET /v1/symbols
{
  "symbols": {
    "USD": "United States Dollar",
    "EUR": "Euro",
    "GBP": "British Pound Sterling",
    "JPY": "Japanese Yen"
  }
}

GET /v1/timeseries

Returns daily rates for a date range (inclusive). Max span may be limited.

GET /v1/timeseries?base=USD&symbols=EUR&start_date=2025-09-01&end_date=2025-09-07
QueryTypeRequiredDescription
basestringYesBase currency
symbolsstringNoTargets
start_datestringYesYYYY-MM-DD
end_datestringYesYYYY-MM-DD
{
  "base": "USD",
  "symbol": "EUR",
  "series": [
    { "date": "2025-09-01", "rate": 0.9198 },
    { "date": "2025-09-02", "rate": 0.9201 },
    { "date": "2025-09-03", "rate": 0.9210 }
  ]
}

Errors

Errors return standard HTTP codes and a JSON body:

{
  "error": {
    "code": "invalid_parameter",
    "message": "Parameter 'base' must be a valid ISO 4217 currency code.",
    "docs_url": "https://api.yourdomain.com/docs#errors",
    "request_id": "req_3u9n1Qm7d2"
  }
}
StatusCodeDescription
400invalid_parameterMissing/invalid query or path parameter
401unauthorizedMissing/invalid API key
403forbiddenInsufficient permissions
404not_foundEndpoint or resource not found
429rate_limit_exceededToo many requests
5xxserver_errorUnexpected server issue

Rate Limits

Requests may be limited. Response headers (per 1-minute window):

X-RateLimit-Limit
60
X-RateLimit-Remaining
57
X-RateLimit-Reset
2025-10-09T13:18:00Z

On 429, back off and retry after the reset time (use jitter to avoid thundering herds).

Code Samples

cURL

curl -s "https://api.yourdomain.com/v1/convert?from=EUR&to=USD&amount=100" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"

JavaScript (fetch)

const base = "https://api.yourdomain.com/v1";
const headers = {
  "Authorization": "Bearer YOUR_API_KEY",
  "Accept": "application/json"
};

async function getLatest(baseCurrency = "USD", symbols = ["EUR","GBP"]) {
  const url = new URL(base + "/rates/latest");
  url.searchParams.set("base", baseCurrency);
  if (symbols?.length) url.searchParams.set("symbols", symbols.join(","));
  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

getLatest().then(console.log).catch(console.error);

Python (requests)

import os, requests

BASE = "https://api.yourdomain.com/v1"
HEADERS = {
    "Authorization": f"Bearer {os.getenv('API_KEY', 'YOUR_API_KEY')}",
    "Accept": "application/json"
}

def convert(frm="USD", to="JPY", amount=50):
    params = {"from": frm, "to": to, "amount": amount}
    r = requests.get(f"{BASE}/convert", headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()

print(convert())