Get Gold Turkey 21k (XAUTUR21) - Per Gram Historical Prices using this API (GraphQL)
If you need Gold Turkey 21k (XAUTUR21) per gram historical prices to power a chart, price a jewelry catalog in real time, benchmark supplier quotes, or backtest a hedging rule, you can do it quickly with Metals-API. This guide shows how to fetch XAUTUR21 history with two practical REST endpoints (Historical and Time-series), how to normalize units (troy ounce vs grams, 21k purity), and how to wrap the data behind a GraphQL layer for your internal apps. We’ll also cover caching, weekend handling, and production-grade error strategies—so you can deliver fast, accurate 21-karat gold pricing in Turkey, per gram, across your tools.
What is XAUTUR21, and why “per gram” matters
In regional retail and manufacturing flows, 21-karat gold (875‰ fineness) is a common working standard. The symbol XAUTUR21 is used by many teams to represent the traded or reference price for Turkey 21k gold. For operational purposes (quoting bracelets, chains, and components), per-gram values are the most convenient unit, not troy ounces. This article focuses exclusively on using Metals-API to retrieve historical XAUTUR21 prices per gram.
If your workflow depends on a specific symbol mapping or a particular per-gram feed, first verify the symbol on the official list at Metals-API Supported Symbols. Symbols can evolve, and new local-market variants may be added over time.
Where to verify availability and behavior
- Check the canonical symbol and unit assumptions: Browse supported symbols and notes.
- Consult endpoint behaviors and parameters: Metals-API Documentation.
- If you do not see the exact symbol you need, consider modeling 21k per gram from XAU (24k troy ounce) by purity and unit conversion in your application logic (explained below).
Two reliable ways to get 21k gold per gram
Method A: Query XAUTUR21 directly (preferred)
If XAUTUR21 is available on your plan, the Historical and Time-series endpoints will return its price directly. Use this method when you need the precise local-market convention and you want Metals-API to provide a consistent per-gram historical series.
Method B: Derive 21k per gram from 24k per troy ounce (fallback)
If XAUTUR21 is not available for your account or plan, you can derive it from XAU using these conversions:
- Troy ounce to grams: 1 troy ounce = 31.1034768 grams.
- 21k purity factor: 21k = 21/24 ≈ 0.875 (or 875‰).
So if the API returns a 24k price per troy ounce (for example, in TRY via base conversion), compute:
XAUTUR21 per gram ≈ (XAU price per troy ounce in TRY) × 0.875 ÷ 31.1034768.
In practice, even with Method B, you’ll often use the same two endpoints (Historical and Time-series) and either change the base to TRY or convert USD to TRY externally to reflect the local currency.
Endpoints you’ll use for XAUTUR21 history
We’ll use only two endpoints, keeping implementation focused and fast:
- Historical Rates: for point-in-time backfills, audits, and deterministic reruns.
- Time-series: for bulk loads across a date range (e.g., building a full daily chart).
Both endpoints return JSON with a consistent envelope, including “success”, “base”, “date(s)”, and “rates”. For XAUTUR21, we’ll parse rates["XAUTUR21"]. The default base is USD; confirm whether you need TRY or USD in downstream logic. See details in the documentation: Metals-API Documentation.
Authentication and request shape
Every request includes your API key via the access_key parameter. Sign up on the Metals-API Website to get a free API key and upgrade as needed for higher-frequency or expanded endpoints. Keep the key server-side—never embed it in a public client app or static site. Rotate keys when staff or systems change, and store them in a secure secret manager.
Example: backfill a one-week history for XAUTUR21 (per gram)
Use the Time-series endpoint when you need a continuous series (e.g., powering a price chart or feeding a daily P&L process). Here’s a complete cURL example:
curl -G https://metals-api.com/api/timeseries \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "start_date=2026-09-12" \
--data-urlencode "end_date=2026-09-19" \
--data-urlencode "symbols=XAUTUR21"
Representative JSON response (abbreviated for clarity):
{
"success": true,
"timeseries": true,
"start_date": "2026-09-12",
"end_date": "2026-09-19",
"base": "USD",
"rates": {
"2026-09-12": {
"XAUTUR21": 27.45
},
"2026-09-13": {
"XAUTUR21": 27.41
},
"2026-09-16": {
"XAUTUR21": 27.62
},
"2026-09-19": {
"XAUTUR21": 27.55
}
},
"unit": "per gram"
}
What these fields mean for your application
- success: True indicates a valid payload; handle false by inspecting the error object (see troubleshooting).
- timeseries: True signifies the payload contains a date-indexed map.
- start_date/end_date: Boundaries you requested; some markets skip weekends/holidays; not every date is present.
- base: The reference currency for the exchange rate mapping. Default is USD unless you specify otherwise. If you need Turkish Lira valuations, consider converting downstream or changing the base if your plan supports it.
- rates: A dictionary keyed by date. For each date, there’s a nested object where "XAUTUR21" maps to a numeric price. Treat missing dates as market-closed days.
- unit: For XAUTUR21, treat as per gram in this workflow. If your symbol’s unit differs, normalize in your pipeline.
Point-in-time query for an audit date
To reconcile a purchase order or spot-check a price on a single date, call Historical Rates by appending the date. This is reproducible and ideal for compliance logs.
curl -G https://metals-api.com/api/2026-09-18 \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "symbols=XAUTUR21"
Representative JSON response:
{
"success": true,
"timestamp": 1789690595,
"base": "USD",
"date": "2026-09-18",
"rates": {
"XAUTUR21": 27.58
},
"unit": "per gram"
}
Interpreting the historical payload
- timestamp: Unix epoch seconds for the snapshot. Useful for precise time-window joins and debugging.
- date: The applicable market date in YYYY-MM-DD.
- rates["XAUTUR21"]: The number you’ll store and display for per-gram 21k gold. Combine with your base logic to render localized currency.
Minimal JavaScript example: fetch a time series and prepare it for a chart
This example demonstrates a server-side script or a secure backend route that pulls XAUTUR21 history and emits normalized values for plotting.
async function fetchXauTur21Series({ start = "2026-09-12", end = "2026-09-19" }) {
const params = new URLSearchParams({
access_key: process.env.METALS_API_KEY,
start_date: start,
end_date: end,
symbols: "XAUTUR21"
});
const url = `https://metals-api.com/api/timeseries?${params.toString()}`;
const res = await fetch(url, { timeout: 10000 });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const body = await res.json();
if (!body.success) {
const code = body.error?.code || "UNKNOWN";
const info = body.error?.info || "No additional info";
throw new Error(`Metals-API error: ${code} - ${info}`);
}
// Build a sorted array for charting: [{ date, value }]
const points = Object.entries(body.rates)
.map(([d, v]) => ({ date: d, value: v["XAUTUR21"] }))
.filter(p => Number.isFinite(p.value))
.sort((a, b) => a.date.localeCompare(b.date));
return {
base: body.base,
unit: body.unit,
start: body.start_date,
end: body.end_date,
points
};
}
// Example usage:
// const series = await fetchXauTur21Series({ start: "2026-09-01", end: "2026-09-30" });
// console.log(series);
Notes:
- Always read and branch on success. The API includes structured error codes.
- Sort by date to make time-indexed arrays deterministic for charting libraries.
- If your downstream expects TRY values, convert your base appropriately (see the documentation for base behaviors).
Units, purity, and base currency—avoid surprises
Units
- Precious metals often use “per troy ounce.” Jewelry and retail operations need “per gram.” Validate the unit for your symbol and normalize where needed.
- If you must convert from troy ounce to gram: divide per-oz prices by 31.1034768.
Purity (21k vs 24k)
- 21k = 0.875 fineness. If you are deriving 21k from 24k (XAU), multiply by 0.875.
- If you query XAUTUR21 directly, purity is already embedded. Do not double-apply purity factors.
Base currency
- Default base is USD. If you need TRY valuations, set your base accordingly if your plan supports it, or apply a reliable USD-TRY rate to convert downstream.
- Store both the price and its base in your data model to prevent silent misinterpretations.
Timestamps and time zones
- Use the provided timestamp for precise event-time joins.
- Display dates in local time for UI; store UTC for data integrity and reproducibility.
Optional: derive XAUTUR21 from XAU (fallback design)
If you can only access XAU (24k per troy ounce) historically, compute XAUTUR21 per gram as follows:
- Fetch XAU time series from Metals-API.
- If needed, convert base to TRY (via your FX stack or plan features).
- Compute per-gram: value_per_gram = (value_per_troy_ounce × 0.875) ÷ 31.1034768.
Be explicit in code about whether values are “per oz 24k,” “per gram 21k,” or “per gram 24k.” Name columns clearly to avoid silent unit drift in analyses.
Designing a GraphQL façade on top of Metals-API
Many teams prefer GraphQL for internal consumers despite using a REST provider upstream. You can wrap Metals-API with a small GraphQL layer to expose a stable contract across apps (mobile, web, reporting). The general approach:
- Schema: Define types like GoldCaratPrice, TimeSeriesPoint, and queries such as xauTur21History(start, end) returning [TimeSeriesPoint].
- Resolver: On xauTur21History, call Metals-API Time-series with symbols=XAUTUR21, map the JSON into your GraphQL types, and enforce unit/base invariants.
- Caching: Add short-lived caching (e.g., 15 minutes) on resolvers to reduce upstream traffic and improve latency.
- Validation: Validate input dates (format, range) and fail fast with descriptive GraphQL errors.
This pattern keeps Metals-API logic server-side, centralizes rate-limiting and retries, and provides a single coherent schema for all client teams.
Performance and scaling tips
- Cache by (endpoint, symbol, start_date, end_date, base) tuple. A CDN or in-memory cache can cut latency for repeated dashboard loads.
- Batch requests: If you need adjacent time windows, consolidate them into one time-series call.
- Pagination: If you’re building a large historical dataset, split by months or quarters and parallelize responsibly with backoff.
- Weekend/holiday handling: The time-series may not return entries for closed days; pre-seed missing dates as NaN to keep chart axes stable.
- Idempotent retries: On 5xx or transient network errors, retry with jitter. Avoid duplicate writes by hashing the (date, symbol) pair.
Error handling and troubleshooting
Common issues
- Symbol not found: Verify the exact code on Metals-API Supported Symbols. Watch for capitalization and suffixes.
- Empty date range: If start_date and end_date include only weekends/holidays, you may get sparse results. This is expected; fill forward as needed.
- Quota/rate limits: Add caching and batch calls. Implement exponential backoff and alerting.
- Unit mismatch: Confirm “unit” in the response and your assumptions. Don’t double-apply oz-to-gram or purity factors.
Example error payload
{
"success": false,
"error": {
"code": 101,
"type": "invalid_access_key",
"info": "You have not supplied a valid API Access Key."
}
}
Handle by inspecting error.code and error.info, surfacing an actionable message internally (never leak keys in logs). Rotate keys or correct configuration as needed.
Security best practices
- Keep access_key server-side. Never expose it in mobile apps or browser code.
- Store secrets in vaults (e.g., environment variables in a protected runtime, secret managers).
- Implement request signing on your own GraphQL/REST proxy to clients; do not forward Metals-API keys to end users.
- Log minimally; avoid logging full URLs with query strings that contain keys.
Data modeling for repeatable analytics
- Schema: date (UTC), symbol (“XAUTUR21”), value, base (“USD” or “TRY”), unit (“per gram”), source (“metals-api”), ts (epoch), and a version tag.
- Immutability: Treat historical prices as append-only; corrections are new records with version bump.
- Normalization: Convert all inputs to a canonical unit/base early, then derive display variants downstream.
Practical integrations
- Pricing engines: Pull latest or previous close, add making charges, and quote retail prices in TRY.
- E-commerce: Hourly cache for PDPs, invalidate on significant fluctuation.
- ERP/MRP: Daily batch to revalue WIP inventory and hedge exposures.
- Research dashboards: Use time-series for rolling correlations, volatility, and regime detection.
Additional endpoint to consider: OHLC for daily candles
When available for your symbol/plan, OHLC gives you open/high/low/close for a market date—useful for charting candlesticks and understanding intraday range.
{
"success": true,
"timestamp": 1789776995,
"base": "USD",
"date": "2026-09-19",
"rates": {
"XAUTUR21": {
"open": 27.60,
"high": 27.75,
"low": 27.50,
"close": 27.55
}
},
"unit": "per gram"
}
Interpretation: Use close for EOD marks, high/low for volatility bands, and open for gap analysis. If OHLC isn’t available for your plan/symbol, fall back to Time-series and Historical endpoints. For more details, see endpoint documentation.
Caching and cost control
- Immutable history: Cache historical days aggressively (e.g., 30d+). They don’t change, so cache hits are pure wins.
- Near-real-time: Cache latest minute/hour depending on your plan’s update cadence. Stagger refreshes to avoid thundering herds.
- Edge caching: If you run a GraphQL proxy, leverage CDN caching with Cache-Control and vary by symbol/date.
Schema and validation guardrails
- Input validation: Enforce YYYY-MM-DD on dates. Ensure start_date ≤ end_date and keep ranges within plan limits.
- Output validation: Check presence of rates["XAUTUR21"] and that it’s finite; quarantine anomalies for manual review.
- Alerting: Threshold-based alerts when data is stale, missing, or deviates beyond configured bands.
SLAs, retries, and health checks
- Timeouts: Set reasonable upstream timeouts (e.g., 10s) with retries and jitter.
- Circuit breakers: Temporarily fall back to cached values if the upstream is unavailable.
- Health checks: Create a daily canary request for XAUTUR21 and alert if it fails.
Practical comparison and symbol references
| Symbol | Description | Unit | Notes |
|---|---|---|---|
| XAUTUR21 | Gold Turkey 21k | per gram | Verify availability and unit: check symbols |
Worked example: building a 3-year chart and a daily alert
- Initial load: Query Time-series for XAUTUR21 across 36 months in monthly batches (e.g., 12 calls). Cache results.
- Chart: Convert the date-indexed map to an array sorted by date. Downsample for UI if needed.
- Alert: Each morning at 09:00 local time, fetch the latest available date. Compare to 30-day moving average; send alert if deviation exceeds 2 standard deviations.
- Audit: For finance, fetch a specific Historical date to lock EOM valuations.
Sample fluctuation snapshot (day-over-day check)
If you want a lightweight read on day-over-day change, the Fluctuation endpoint can be used when applicable to your plan and symbol. Example response shape:
{
"success": true,
"fluctuation": true,
"start_date": "2026-09-18",
"end_date": "2026-09-19",
"base": "USD",
"rates": {
"XAUTUR21": {
"start_rate": 27.58,
"end_rate": 27.55,
"change": -0.03,
"change_pct": -0.1088
}
},
"unit": "per gram"
}
Use cases: threshold alerts, EOD summaries, and concise KPI widgets. For broader capabilities and parameter details, review the endpoint documentation.
Production checklist
- Confirm symbol and unit on the Supported Symbols page.
- Decide on base currency strategy (stick to USD or convert to TRY in-app).
- Normalize all values to “per gram” in storage to simplify query logic.
- Cache immutable history and short-cache recent data based on your update cadence.
- Implement robust retries, backoff, and circuit-breaking.
- Version data and keep an audit trail of inputs and derived fields (e.g., purity-adjusted computations).
Innovation with XAUTUR21: analytics and digital workflows
Gold as digital data unlocks better decisioning across the value chain. With consistent per-gram, 21k series for Turkey, you can compute rolling volatility, identify structural breaks, run regime classification for inventory hedging, and drive automated pricing pipelines for e-commerce. Embedding Metals-API into your GraphQL fabric lets product teams ship features faster—dashboards, alerts, catalogs—without re-implementing integrations. This is how digital transformation in precious metals becomes concrete: repeatable data contracts, reproducible analytics, and low-latency delivery.
Get started
- Create your key on the Metals-API Website and start with a free tier.
- Confirm symbols and plan alignment on Supported Symbols.
- Build your first Time-series request using the Metals-API Documentation.
FAQ
Does Metals-API provide XAUTUR21 directly per gram?
In many cases, yes—query XAUTUR21 and verify the unit in the response. Always confirm on the symbols page. If unavailable, derive it from XAU with purity and unit conversions as described.
What about weekends and holidays?
Expect sparse results on closed days. Your time-series array should be robust to missing dates. For charts, pre-seed dates and carry forward the last available value (if that suits your UX), or let the chart render gaps.
How do I ensure prices are in TRY?
Either request a TRY base if your plan supports it or convert USD-based results using your FX stack. Always label stored values with their base to prevent confusion.
Can I use GraphQL directly with Metals-API?
Metals-API is a JSON REST API. You can build a thin GraphQL layer internally that calls Metals-API under the hood, providing a unified contract for your clients.
How should I cache historical data?
Treat history as immutable and cache aggressively. Invalidate only when you intentionally re-ingest or correct historical series. Cache near-real-time data with short TTLs aligned to your plan’s update frequency.
What if I get an error with success=false?
Inspect error.code and error.info, correct the issue (key, symbol, parameters), and retry using exponential backoff for transient errors. Log context but never log secrets.
Where can I find all parameters and plan-specific behaviors?
See the Metals-API Documentation for endpoint parameters, examples, and plan features. For symbol coverage and units, refer to Supported Symbols.
Ready to implement? Visit the Metals-API Website to get your free API key and start retrieving XAUTUR21 per gram historical prices today.