South Korean Won (KRW) Price API in Multiple Currencies — Implementation Guide for Backend Developers

Metals-API 9 min read
South Korean Won (KRW) Price API in Multiple Currencies — Implementation Guide for Backend Developers

You need to deliver KRW prices your backend can trust—quoted both as KRW per USD and USD per KRW—so you can price products, settle payouts, or normalize trade P&L across currencies without wasting time on manual cross-rate math. By the end of this guide you will fetch real-time KRW rates via a single API call, parse, invert, and cache them correctly, and lay the groundwork to extend into historical series for monitoring and reporting.

What you will build: a KRW multi-currency feed ready for production

This walkthrough focuses on a minimal, production-friendly integration that:

Illustration: South Korean Won (KRW) Price API in Multiple Currencies — Implementation Guide for Backend Developers
  • Pulls KRW quotes with the latest endpoint (base=USD by default) and includes the inverse pair for convenience.
  • Explains the math you will actually implement for conversions: USD→KRW and KRW→USD using returned fields.
  • Highlights practical details you must handle: timestamps and timezone, base currency semantics, precision, caching, and weekends/market holidays.

We will use a single endpoint for the core logic and keep options open to expand with time-series later. For full capabilities and parameters, see the Documentation. To review all supported symbols (metals and currencies), open the Symbols list.

If you need an API key, create one here: Register. There is no free trial; plans are available on metals-api.com, and the Copper Monthly plan is $19.99/mo.

KRW rates model: base, units, and inverses you’ll actually use

Key concepts before you code:

  • Base currency: By default, rates are relative to USD. That means rates.KRW is KRW per 1 USD (KRW/USD).
  • Inverse pair: The API may also include USDKRW, which is USD per 1 KRW (USD/KRW). You can invert rates yourself if needed.
  • Units: Currency pairs are unitless exchange rates. Metal rates (if you later add them) are per troy ounce by default. Keep the distinction clear in your data model.
  • Timestamp and timezone: The API returns a Unix timestamp and an ISO date; treat them as UTC for caching and audit.
  • Weekends and closures: FX trades over-the-counter with reduced liquidity on weekends. Expect slower or unchanged rate movements during closures. Cache appropriately.

You can always browse all available codes (including KRW and USD) on the Metals-API Supported Symbols page.

Fetch KRW with one request (latest endpoint)

Call the latest endpoint with KRW, USDKRW, and USD to get both directions and an explicit base reference. Replace YOUR_API_KEY with your key from Metals-API Register.

curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=KRW,USDKRW,USD"

Below is an official example response for this exact request. Use it to validate your parser and field names during development.

{"success":true,"timestamp":1792109280,"date":"2026-10-16","base":"USD","rates":{"KRW":1341.330329,"USD":1,"USDKRW":0.000745528508809257}}

Fields you will actually consume

  • success: Boolean indicating the request status. Always check it before using data.
  • timestamp and date: Snapshot time in Unix epoch and ISO date (UTC). Use these for caching keys, monitoring staleness, and time-based partitioning in storage.
  • base: "USD" indicates all non-prefixed symbols in rates are quoted per 1 USD.
  • rates.KRW: KRW per USD (KRW/USD). Multiply a USD amount by this to get KRW.
  • rates.USDKRW: USD per KRW (USD/KRW). Multiply a KRW amount by this to get USD.
  • rates.USD: Always 1 when base=USD. Useful as a sanity check for data integrity.

Practical math and edge cases (USD↔KRW)

Given the example above:

  • USD→KRW conversion formula: krw_amount = usd_amount × rates.KRW
  • KRW→USD conversion formula: usd_amount = krw_amount × rates.USDKRW
  • If USDKRW is not present, compute inverse yourself: USDKRW = 1 / KRW, but prefer the explicit field when it’s provided to avoid rounding drift.

Precision tips:

  • Carry sufficient decimal precision in both directions. Store raw floats/decimals from the API and round only at presentation or settlement boundaries dictated by your product.
  • When producing audit logs, persist the timestamp, date, and the exact rate used in each conversion for reproducibility.

Production-grade Python example

The snippet below fetches KRW, validates the response, handles inverses, and shows both conversion directions. It also sketches a simple time-based cache to avoid over-calling the API when your latency/consistency needs are modest.

import os
import time
import json
import math
import urllib.parse
import urllib.request

API_BASE = "https://metals-api.com/api/latest"
API_KEY = os.getenv("METALS_API_KEY", "YOUR_API_KEY")
SYMBOLS = ["KRW", "USDKRW", "USD"]

# naive in-memory cache (replace with Redis/Memcached in production)
_cache = {"payload": None, "expires_at": 0}

def fetch_latest_krw(ttl_seconds=60):
now = time.time()
if _cache["payload"] and _cache["expires_at"] > now:
return _cache["payload"]

params = {
"access_key": API_KEY,
"symbols": ",".join(SYMBOLS),
}
url = f"{API_BASE}?{urllib.parse.urlencode(params)}"
with urllib.request.urlopen(url, timeout=10) as resp:
body = resp.read().decode("utf-8")
data = json.loads(body)

if not data.get("success"):
raise RuntimeError(f"Metals-API error: {body}")

# basic schema checks
rates = data.get("rates", {})
if "KRW" not in rates or "USD" not in rates:
raise ValueError(f"Missing expected symbols in response: {list(rates.keys())}")

# normalize presence of USDKRW
if "USDKRW" not in rates:
# compute inverse cautiously; avoid division by zero
krw_per_usd = float(rates["KRW"])
if krw_per_usd == 0:
raise ZeroDivisionError("KRW rate returned as zero")
rates["USDKRW"] = 1.0 / krw_per_usd

data["rates"] = rates

# cache for ttl_seconds to limit external calls
_cache["payload"] = data
_cache["expires_at"] = now + ttl_seconds
return data

def usd_to_krw(usd_amount, rates):
return float(usd_amount) * float(rates["KRW"])

def krw_to_usd(krw_amount, rates):
return float(krw_amount) * float(rates["USDKRW"])

if __name__ == "__main__":
payload = fetch_latest_krw(ttl_seconds=90)
rates = payload["rates"]
ts = payload["timestamp"]
quote_date = payload["date"]
base = payload["base"]

print(f"Base: {base}, Date: {quote_date}, Timestamp: {ts}, KRW per USD: {rates['KRW']}, USD per KRW: {rates['USDKRW']}")

# demo conversions
print("100 USD => KRW:", usd_to_krw(100, rates))
print("100000 KRW => USD:", krw_to_usd(100000, rates))

Notes:

  • Timeouts and retries: set reasonable timeouts on your HTTP client. Implement exponential backoff for transient network errors.
  • Caching: The example uses a 90s TTL. Pick a TTL that balances freshness vs. call volume. The latest endpoint’s update cadence depends on plan; review your plan’s specifics in the Documentation.
  • Weekend behavior: Expect slower or unchanged updates around weekend hours; your cache may suffice without impacting accuracy targets.

Schema guardrails and storage layout

A consistent storage schema simplifies downstream analytics and risk controls. Suggested fields for each snapshot:

  • as_of_ts (int, UTC epoch), as_of_date (ISO), base ("USD")
  • krw_per_usd (float) from rates.KRW
  • usd_per_krw (float) from rates.USDKRW (or computed inverse)
  • raw_json (text) for audit and replay

Partition your warehouse by as_of_date for efficient time-window queries. For streaming pipelines, propagate the timestamp and date downstream with each event.

Expanding to history and analytics

Once you have latest rates in production, your next step is typically monitoring and reporting. The API offers historical snapshots and time-window endpoints you can use to compute daily changes or roll up KPIs. Keep in mind:

  • Historical coverage: Historical rates are available back to earlier years for most symbols. Use this to backfill dashboards or stress models.
  • Fluctuation and time-series: These endpoints aggregate change and deliver ranges over dates you choose. They are ideal for daily monitoring or alerting on KRW moves.

Because this post is centered on a working latest integration, we have not duplicated full examples for other endpoints here. For parameters, date formats, and response structures, refer to the API Documentation.

Operational considerations you should not skip

  • Keys and environments: Inject your API key via environment variables or a secrets manager. Do not hardcode it.
  • Staleness guards: Treat timestamp monotonicity as a signal. If a newly fetched timestamp is older than your last-used one, hold the prior value to avoid time reversals in accounting.
  • Precision and rounding: Agree on rounding at the business boundary (e.g., settlement to 2 decimals in USD, 0 decimals in KRW), but store high precision upstream.
  • Alerting: If rates.KRW drops to zero or is missing, alert and fail closed. Use USD=1 as a cheap integrity test when base=USD.
  • Throughput and caching: Coalesce requests with a short TTL and a single-flight mechanism to reduce duplicate upstream calls across app instances.
  • Documentation bookmarks: Keep direct links handy—Metals-API Documentation and Supported Symbols.

Integrating with pricing, trading, and ERP systems

Common patterns when plugging KRW into downstream systems:

  • Pricing engines: Keep a KRW snapshot cache keyed by timestamp for deterministic repricing and quote validation.
  • Payouts: Calculate the KRW or USD payable at the time-of-execution rate and store both the numeric rate and raw JSON for audit.
  • Risk and analytics: Persist end-of-day KRW rates to compute day-over-day deltas and value-at-risk input assumptions for exposures denominated in KRW.
  • Data distribution: Normalize publish/subscribe messages with fields base, pair, value, timestamp. Example pairs: KRW/USD and USD/KRW alongside base=USD.

About units: when you add metals alongside KRW

Metals data in this API defaults to per troy ounce. If you later join KRW with a metal quote, keep units explicit:

  • Currency fields (KRW, USDKRW) are exchange rates.
  • Metal fields (e.g., XAU when you add gold later) are “per troy ounce.” If you price goods in grams, convert by 1 troy ounce = 31.1034768 grams.

Keep the unit in your price objects to prevent silent dimension mismatches when mixing currencies and metals. For anything beyond KRW and USD, confirm codes on the Symbols page.

Plan selection and managing costs

There is no free trial. Choose a plan consistent with your required update frequency and call volume. For example, the Copper Monthly plan is $19.99/month. Review plan specifics and manage your account from the MCP page. To create an API key now, go to Register.

Additional references for KRW context

FAQ

  • What does base=USD mean for KRW? It means rates.KRW is KRW per 1 USD (KRW/USD). If you need USD per 1 KRW, use rates.USDKRW (if present) or compute 1 / rates.KRW.
  • Which rate should I store for audits? Persist both KRW per USD (rates.KRW) and the timestamp/date. If you convert KRW→USD, also persist USDKRW (either returned or computed) used at transaction time.
  • How often do KRW rates update? Update cadence depends on your subscription tier. Implement caching with a TTL that matches your operational needs and consult the Documentation for endpoint behavior.
  • What timezone is the timestamp? Treat the Unix timestamp as UTC and the date field as the corresponding UTC calendar date.
  • Can I join KRW with metals prices later? Yes. The API serves both currencies and metals. Confirm symbols on the Symbols page and remember that metal prices are per troy ounce by default.

Ready to ship your KRW integration? Get your API key now at Register, then keep the Documentation open as you wire the latest endpoint into your backend. If you need to manage or upgrade your plan, visit MCP.