Get São Tomé and Príncipe Dobra (STD) - N/A Historical Prices using this API — daily time-series export
You need a daily history of São Tomé and Príncipe Dobra (STD) to backfill charts, run strategy backtests, reconcile invoices, or audit FX exposures. By the end of this guide, you will fetch a single historical day and a full daily time series of STD priced against a base currency, parse the JSON into date/value pairs, and ship it into your database or CSV job—reliably and repeatably.
What you’ll build: daily STD history you can drop into charts, models, or ledgers
We’ll focus on two endpoints that cover the majority of historical export use cases:
- Historical (single date): resolve a known day’s STD rate for reconciliation or spot checks.
- Time-series (date range): export day-by-day STD rates for charting, analytics, and batch backfills.
Both endpoints return JSON with a consistent schema. Rates default to USD as the base unless you specify another base. If you are unsure about symbol spelling, confirm STD in the Metals-API Supported Symbols.
Historical STD for a single date: quick reconciliation and backfill
Use the single-date Historical endpoint when you need the STD rate on a specific calendar day—for example, to reconcile a journal entry, confirm a settlement, or correct a missing datapoint.
Single-day Historical request (curl)
Replace YOUR_API_KEY with your key. Base is USD by default; include base explicitly if you want to be unambiguous.
curl -s "https://metals-api.com/api/2026-10-01?access_key=YOUR_API_KEY&base=USD&symbols=STD"
Official sample JSON (single date)
This is the exact historical STD payload format you will receive. Use these fields as your integration contract.
{"success":true,"timestamp":1790813400,"date":"2026-10-01","base":"USD","rates":{"STD":20697.981008,"USD":1,"USDSTD":4.8313891080172936e-5}}
How to read these fields
- success: Boolean indicating the request completed successfully.
- timestamp: UNIX epoch seconds in UTC for the rate snapshot. Use this for ordering and cache keys.
- date: The calendar date of the historical rate (YYYY-MM-DD).
- base: The base currency for all quoted rates in this payload (USD here).
- rates.STD: The number of STD per 1 base unit (USD here). In this snapshot, 1 USD equals the shown count of STD.
- rates.USD: Always 1 when base=USD (self-reference for convenience).
- rates.USDSTD: A convenience cross symbol for USD/STD. Use rates.STD if you only need STD per USD.
Note on units: Unlike metals quotes that may be “per troy ounce,” currency rates are unitless ratios relative to base. No weight conversions are involved for STD.
Daily time-series export of STD: charting, analytics, and bulk backfill
The Time-series endpoint returns a day-by-day history between start_date and end_date. This is the fastest way to hydrate a chart or backfill a warehouse in one shot without stitching single-day calls.
Time-series request (curl)
Pick a bounded date range that fits your plan and workload (see limits in the Documentation).
curl -s "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&base=USD&symbols=STD&start_date=2026-09-24&end_date=2026-10-01"
Python: turn the time series into a date/value list
This snippet fetches the time series for STD and converts it into a chronologically sorted list you can write to CSV, insert into a table, or hand off to a charting layer.
import requests
from datetime import datetime
API_KEY = "YOUR_API_KEY"
url = "https://metals-api.com/api/timeseries"
params = {
"access_key": API_KEY,
"base": "USD",
"symbols": "STD",
"start_date": "2026-09-24",
"end_date": "2026-10-01",
}
r = requests.get(url, params=params, timeout=30)
r.raise_for_status()
data = r.json()
if not data.get("success"):
raise RuntimeError(f"API error: {data}")
# data['rates'] is expected to be a dict keyed by 'YYYY-MM-DD'
# Each entry contains currency keys, e.g., {'STD': <rate>}
series = []
for day, payload in data.get("rates", {}).items():
rate = payload.get("STD")
if rate is None:
# If a date has no STD, skip or handle per your policy
continue
# Keep UTC-safe ordering
dt = datetime.strptime(day, "%Y-%m-%d")
series.append((dt.date().isoformat(), float(rate)))
# Sort by date to be safe
series.sort(key=lambda x: x[0])
# At this point, 'series' looks like:
# [('2026-09-24', <STD_per_USD>), ('2026-09-25', ...), ..., ('2026-10-01', ...)]
print(series[:3], "...", series[-1])
What fields you will actually use in charts, models, and ledgers
Focus on these fields across historical and time-series responses:
- timestamp: Normalize everything to UTC using the epoch seconds for ordering and reproducibility.
- date: The canonical business date. Use this as the x-axis label for charts and the partition key in storage.
- base: Confirm your conversion context. If you need STD per EUR, request base=EUR instead of USD.
- rates.STD: The primary numeric value—STD units per 1 base unit. This is what you plot, store, and compute with.
Downstream rules of thumb:
- Store both date and timestamp to preserve business-day alignment and exact snapshot timing.
- If you resample to weekly/monthly, keep the original daily series in your warehouse for auditability.
- When converting amounts, multiply your base-currency amount by rates.STD to get STD. For example, amount_in_STD = amount_in_base * rates.STD.
Practical details that save time in production
Base currency and conversion direction
- Default base is USD. If you request base=USD and symbols=STD, you’ll get “STD per USD.”
- To invert (e.g., “USD per STD”), either change base to STD (if supported in your plan) or compute the inverse 1 / rates.STD locally with appropriate numerical precision.
Timestamps, timezone, and ordering
- timestamp is UNIX epoch seconds in UTC. Convert with standard libraries and never assume local time. See a quick reference on epoch time at UNIX timestamp reference.
- Use date for business-day grouping; use timestamp for deterministic sort and cache invalidation.
Weekends and market closures
- Daily FX series can include weekends/holidays depending on the provider’s methodology. If a date has no STD rate, handle it explicitly: skip, forward-fill, or tag as missing.
- Write your ETL to accept sparse calendars. Do not assume seven entries per week or 365 per year.
Request ranges and batching
- Maximum date-range per Time-series call depends on your plan. If you need multi-year data, segment the job into consecutive ranges (e.g., quarter-by-quarter) and merge locally. Check limits in the Documentation.
- Use idempotent schedules: if a run fails mid-range, resume from the last successful date to avoid duplicates.
Caching and cost control
- Historical data is immutable. Cache per (base, symbol, date) key indefinitely in your data store or CDN.
- For time-series backfills, write-as-you-go: persist day-level results as soon as you parse them, so retries only re-fetch missing dates.
Data precision and numeric handling
- Use decimal/fixed-point where your accounting rules require exactness. Float is acceptable for charts but be explicit when you cross from analytics to finance.
- When inverting or chaining conversions (e.g., USD→STD→local rounding), maintain sufficient precision until final presentation.
End-to-end example flow: from curl to CSV
Here’s a compact flow you can adapt for a nightly job:
- Call Time-series with base=USD and symbols=STD for the last N days.
- Parse the JSON, extracting (date, rates.STD).
- Sort by date and upsert to your warehouse keyed by (date, base, symbol).
- Export to CSV for BI tools, or hydrate your chart cache immediately.
- Skip already-seen dates using a local ledger or etag keyed by timestamp to reduce calls.
Comparing single-date vs. time-series for STD workflows
| Use case | Endpoint | Pros | Caveats |
|---|---|---|---|
| One-off reconciliation | Historical (single date) | Simple, minimal payload | One date at a time |
| Charting and backfill | Time-series (date range) | Bulk retrieval of daily points | Respect range limits; segment if needed |
| Scheduled daily close | Historical for “yesterday” | Deterministic snapshot by business date | Requires a loop to build long histories |
Error handling, retries, and validation
- Check success: Always inspect the success flag before accessing rates. If false, log the body and back off.
- Validate dates: Ensure each date key contains STD. If an entry is missing, apply your policy (skip or gap-fill).
- Retry policy: Use exponential backoff for transient network errors. Avoid retry storms; historical data will not change, so consider deferred retries.
- Cross-checks: For audit workflows, store the raw JSON and a checksum. Cross-validate with a secondary source when policy requires it. For currency code context, you can review the ISO 4217 currency code reference.
Beyond STD: building blocks you can reuse
You can reuse the same Historical and Time-series patterns for other currencies and, when relevant, for metals data. If you later need OHLC, daily high/low, or intraday snapshots for metals, see the appropriate sections in the Documentation. For coverage and connectivity considerations across markets, review the MCP overview.
Security and key management
- Use environment variables or a secrets manager to store YOUR_API_KEY. Never hardcode keys in source control.
- In serverless or job schedulers, scope secrets to minimal roles and rotate them regularly per your policy.
- If you build a browser-based client, proxy requests through your backend to keep keys private and enable caching.
Checklist before you ship
- Symbols: Confirm STD on the Supported Symbols page.
- Base currency: Decide if your analytics run on USD or a local base. Set base accordingly.
- Date windows: Segment time-series calls if needed and persist progress markers.
- Precision: Choose Decimal for finance-grade storage and outputs.
- Caching: Cache historical responses forever with a namespaced key like hist:USD:STD:YYYY-MM-DD.
FAQ
Q1: Can I request STD with a non-USD base?
Yes. Add base=YOUR_BASE to the query (for example, base=EUR). The rates.STD will then represent STD per 1 EUR. Confirm what bases are available in your plan in the Documentation.
Q2: How far back can I get STD daily history?
Historical availability is specified in the docs. If you need a long span, divide the request into smaller date ranges and merge locally.
Q3: Why is a given calendar date missing?
Some days may not have rates or may be omitted based on source availability. Treat missing days explicitly: skip, interpolate, or carry forward, depending on your business rules.
Q4: Do I need to handle daylight savings or local time shifts?
No. The timestamp is in UTC and the date is a calendar date string. Use them as-is to avoid timezone-induced drift.
Q5: How should I validate the integrity of my backfill?
Persist the raw JSON for each date, store a checksum, and compare row counts to the expected number of business days. For context on currency codes and conventions, see ISO 4217 explainer.
Ready to fetch STD daily history and wire it into your stack? Get your key and start calling the Historical and Time-series endpoints in minutes: Register. For endpoint details and parameters, keep the Documentation open as you implement, and verify symbols on the Symbols page.