Get Cuban Convertible Peso (CUC) - N/A reconciliation-ready Historical Prices using this API
When your finance or data team needs reconciliation-ready historical prices expressed in Cuban Convertible Peso (CUC), you quickly run into a real-world problem: CUC is now N/A in most modern datasets and systems. Yet your ledgers, ERP postings, or legacy trades might still reference CUC. In this article, we show you how to use Metals-API to reliably backfill, audit, and reconcile historical datasets that require CUC-denominated figures—despite the currency’s deprecation—by coupling the API’s historical/time-series capabilities with sound data-engineering techniques and compliance notes. We focus specifically on Cuban Convertible Peso (CUC) and how to operationalize “N/A” periods without breaking your downstream analytics or reports.
CUC as a legacy currency in a digital, analytics-driven metals stack
The Cuban Convertible Peso (CUC) was discontinued and is now a legacy currency. In modern, API-driven workflows—spanning trading analytics, e-commerce repricing, ERP valuation, and manufacturing cost tracking—this creates a gap whenever historical records stored in CUC must be rolled forward, audited, or attributed to metals or USD-based baselines. Digital transformation in the metal markets depends on reliable reference data, and your system must be resilient when a requested symbol is unavailable or N/A.
With Metals-API Website, you can query historical price data for precious and industrial metals and use robust currency conversion workflows. For CUC, you need a careful approach: detect unsupported symbols, document the reason, and implement deterministic reconciliation rules. This post shows how to set up a repeatable pipeline using 2–3 relevant endpoints, error-aware handling, and clear metadata so your audits pass cleanly.
What we will build
- Programmatic checks for CUC availability on Metals-API, with robust error handling.
- Historical/time-series queries that return consistent, reconcilable results even when CUC is N/A.
- A conversion workflow template that shows how you would compute metals-in-CUC if you maintain your own legacy conversion curves for CUC.
- Best practices around units (troy ounce vs grams), base currency, timestamps/time zones, caching, weekends, and market closures.
Constraints, symbols, and how to verify CUC availability
Before you automate anything, verify whether your target symbol exists in the provider’s symbol catalog. Start here: Metals-API Supported Symbols. If CUC is not listed or flagged as unsupported, plan for a reconciliation workflow that does not depend on receiving a live CUC rate. We’ll show how to do that safely.
Why CUC may return N/A
- It is a discontinued currency. Modern APIs typically stop streaming or publishing prices for legacy units.
- If you request CUC on endpoints that only publish active symbols, you will receive an error response or an empty payload.
- Reconciliation standards often require you to document the mapping you used for discontinued currencies when backfilling historical results.
How Metals-API fits into a CUC reconciliation workflow
Metals-API publishes standardized rates with timestamps, UTC baselines, and explicit units (per troy ounce for metals). You can combine these stable references with a well-documented internal mapping or archive of CUC conversion factors to get reproducible numbers. In other words, let Metals-API be your trusted source of metal prices and active FX pairs, then apply an audited cross-rate for CUC where necessary.
Endpoints we’ll use for CUC reconciliation
We keep the scope focused on the data you need to backfill or audit historical records with a legacy currency:
- Historical Rates Endpoint: Per-date snapshots for reference pricing and period-end valuations.
- Time-series Endpoint: Multi-day spans to backfill charts, VaR windows, or month-end rollups.
- Convert Endpoint: Template for computing cross-rates when symbols exist; also useful to illustrate how you would compute metals-to-CUC if you control the CUC leg internally.
For complete details on all available endpoints and parameters, see the Metals-API Documentation. Remember, when a symbol is not supported, you should fail fast, record the reason, and apply a documented fallback.
A practical use case: Reconcile a 2019–2021 ledger that references CUC
Imagine you are migrating a manufacturing ERP that tracked hedges and invoices in CUC up through a cutover. Your auditors want to see:
- Historical metal prices for given days to support invoice valuation, expressed in CUC.
- Clear documentation for any currency that is no longer published by your provider.
- Deterministic and repeatable results if you rerun the pipeline.
We’ll build a routine that:
- Requests metals data for the relevant dates from Metals-API.
- Attempts to fetch CUC; if CUC is unavailable, records a standardized “N/A: unsupported symbol” reason.
- Applies your internal, auditor-approved CUC mapping to derive a CUC-denominated figure from the USD-based metal price (or vice versa), recording the mapping source and version.
Important modeling concepts before you code
- Base currency: Metals-API responses are by default relative to USD. If you are modeling cross-rates, confirm your direction of conversion to avoid inverted math.
- Units: Metals prices are typically returned per troy ounce. If your ERP tracks grams or kilograms, convert units consistently and store the conversion constant with your job metadata.
- Timestamps and timezone: The API uses Unix timestamps and dates with UTC semantics. Align your period ends (EOD) with UTC or document your conversion to local time if your policy differs.
- Weekends/market closures: Many metals and FX markets have gaps or reduced liquidity outside weekdays. Your historical windows should expect days with no updates.
- Caching: Cache historical responses aggressively. Historical prices do not change; this saves quota and stabilizes reruns.
Attempting a CUC historical query and interpreting the response
First, try to retrieve a single historical snapshot that includes CUC so you can programmatically test symbol availability. If CUC is unsupported, you should expect an error response. Below is a realistic pattern for an error-case response; always validate against production behavior in your account.
Example curl: Historical request that includes CUC
curl -G "https://metals-api.com/api/2020-06-30" \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "base=USD" \
--data-urlencode "symbols=CUC"
Possible error JSON when symbol is unsupported
{
"success": false,
"error": {
"code": "invalid_symbols",
"info": "One or more specified symbols are not supported: CUC"
}
}
How to use this:
- If success is false, short-circuit your “direct-from-API” CUC path.
- Record error.code and error.info to your audit log or reconciliation notes.
- Switch to your fallback: compute CUC-denominated values using your approved internal CUC mapping (for example, a legacy FX archive in your data warehouse), while keeping Metals-API as the authoritative metals price reference.
Field-by-field interpretation you will actually use
- success: Boolean. Use this to branch the workflow. If false, do not attempt to parse rates.
- error.code: Machine-readable error key. Use it to classify and alert (e.g., unsupported symbol vs. auth failure).
- error.info: Human-readable context for logs and tickets.
When CUC is N/A: Get historical metals prices and apply your CUC mapping
Even when CUC is unavailable, you can still fetch the metal prices you need for your dates and then compute a CUC-denominated value with your internal mapping. The key is to anchor every computation to a single, authoritative base (USD), then apply your mapping transparently.
Example curl: Historical metals on a given date (anchor to USD)
Replace the symbols below with the exact metals you price against. We keep this example focused on the workflow; you can expand the symbol set as needed.
curl -G "https://metals-api.com/api/2020-06-30" \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "base=USD" \
--data-urlencode "symbols=XAU,XAG"
Illustrative successful response format (fields to expect; do not treat the values below as live data):
{
"success": true,
"timestamp": 1593532799,
"base": "USD",
"date": "2020-06-30",
"rates": {
"XAU": 0.000480,
"XAG": 0.03810
},
"unit": "per troy ounce"
}
Interpretation for reconciliation:
- base: USD. The numbers in rates indicate how many troy ounces your 1 USD buys (for metals). For example, if USD→XAU is 0.000480 oz, then the price per troy ounce is 1 / 0.000480 USD/oz.
- timestamp/date: Tie this to your ledger posting date or to a standardized EOD rule. Store both—the raw API timestamp and your business-period alignment (e.g., “Month-End 2020-06”).
- unit: Always propagate “per troy ounce” in your metadata so downstream conversions to grams/kg are traceable.
Converting to CUC when the symbol is unsupported
Because CUC is N/A, use your internal, audited CUC cross-rate (e.g., a static table per date) to compute a derived CUC price. For a given metal rate expressed as USD→XAU (oz per USD):
- Compute USD per troy ounce: price_usd_per_oz = 1 / rate_usd_to_xau.
- Apply your internal USD→CUC cross for that date: price_cuc_per_oz = price_usd_per_oz × (usd_to_cuc on 2020-06-30).
- If your ERP needs grams: price_cuc_per_g = price_cuc_per_oz / 31.1034768.
Store each intermediate, including the USD→CUC factor with a source reference (e.g., “LegacyFXTable v2.1, approved by Accounting on YYYY-MM-DD”).
Time-series backfill for spans that contain CUC references
For bulk backfills or rolling windows, the Time-series Endpoint streamlines daily historical pulls. Include your requested metals, test CUC availability (expect N/A), and then apply your internal mapping per day. This is ideal for generating reconciliation reports or feeding a chart that must label certain periods as “CUC legacy mapping applied.”
Example curl: Time-series for a date range while you manage CUC internally
curl -G "https://metals-api.com/api/timeseries" \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "start_date=2020-06-01" \
--data-urlencode "end_date=2020-06-30" \
--data-urlencode "base=USD" \
--data-urlencode "symbols=XAU"
Illustrative successful response format:
{
"success": true,
"timeseries": true,
"start_date": "2020-06-01",
"end_date": "2020-06-30",
"base": "USD",
"rates": {
"2020-06-01": {
"XAU": 0.000478
},
"2020-06-15": {
"XAU": 0.000481
},
"2020-06-30": {
"XAU": 0.000480
}
},
"unit": "per troy ounce"
}
How to use this for reconciliation:
- Iterate through rates by date. Compute USD per troy ounce as 1 / value.
- Join each date to your internal CUC mapping. Produce a price_cuc_per_oz and record the mapping source.
- When a date lacks a mapping, flag it and optionally roll forward the last known mapping according to your policy, but always label the imputation method.
Handling an explicit CUC request on time-series (error path)
If you attempt to include CUC as a symbol in a time-series call, expect an error or an empty result. Handle this branch exactly once in your pipeline and cache the result so you don’t re-test CUC availability on every run.
curl -G "https://metals-api.com/api/timeseries" \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "start_date=2020-06-01" \
--data-urlencode "end_date=2020-06-30" \
--data-urlencode "base=USD" \
--data-urlencode "symbols=CUC"
{
"success": false,
"error": {
"code": "invalid_symbols",
"info": "One or more specified symbols are not supported: CUC"
}
}
Convert Endpoint: A template for cross-rate computation
When a symbol is supported, the Convert Endpoint will compute cross-rates directly. For CUC, treat this as a template for your internal computation, because requesting CUC is likely to return an error. The pattern below shows how it would look and how you would interpret the response in success and error cases.
Template curl: Convert USD to CUC (expect error for unsupported symbol)
curl -G "https://metals-api.com/api/convert" \
--data-urlencode "access_key=YOUR_API_KEY" \
--data-urlencode "from=USD" \
--data-urlencode "to=CUC" \
--data-urlencode "amount=1000"
{
"success": false,
"error": {
"code": "invalid_currency",
"info": "The requested currency is not supported: CUC"
}
}
Interpretation for your workflow:
- success false: Switch to your internal CUC conversion routine for the given amount and date.
- Document that an external direct conversion was not available and that a policy-based mapping was applied.
Putting it together in code: defensive fetching and reconciliation metadata
The following Python example shows a robust pattern you can adapt. It attempts a CUC request, handles errors deterministically, fetches metals data anchored to USD, and then applies a mock internal mapping function to compute CUC-denominated prices. Replace the internal mapping with your real, audited source.
import os
import requests
from datetime import date
API_KEY = os.getenv("METALS_API_KEY")
def get_json(url, params):
r = requests.get(url, params=params, timeout=20)
r.raise_for_status()
return r.json()
def cuc_is_supported():
# Probe once and cache. If unsupported, we won't try again in the run.
resp = get_json(
"https://metals-api.com/api/2020-06-30",
{"access_key": API_KEY, "base": "USD", "symbols": "CUC"}
)
return resp.get("success", False) and "rates" in resp and "CUC" in resp["rates"]
def fetch_historical_metal(iso_date, symbols):
return get_json(
f"https://metals-api.com/api/{iso_date}",
{"access_key": API_KEY, "base": "USD", "symbols": ",".join(symbols)}
)
def internal_usd_to_cuc(date_str):
# Replace with your vetted archive. Return None if unavailable.
# Example policy: if no mapping present, return None to force a flagged record.
legacy_map = {
"2020-06-30": 1.0,
"2020-06-15": 1.0,
"2020-06-01": 1.0
}
return legacy_map.get(date_str)
def reconcile_cuc_for_date(iso_date, metal_symbol="XAU"):
# 1) Confirm CUC support
cuc_supported = cuc_is_supported()
meta = {"cuc_supported": cuc_supported, "mapping_source": None, "notes": []}
# 2) Fetch metal data anchored to USD
hist = fetch_historical_metal(iso_date, [metal_symbol])
if not hist.get("success"):
return {"ok": False, "error": hist.get("error", {}), "meta": meta}
rate = hist["rates"].get(metal_symbol)
if rate is None:
return {"ok": False, "error": {"info": f"No {metal_symbol} in response"}, "meta": meta}
# metal rate is in oz per USD; convert to USD per oz
usd_per_oz = 1.0 / rate
out = {
"ok": True,
"date": hist["date"],
"unit": hist.get("unit"),
"base": hist.get("base"),
"metal": metal_symbol,
"usd_per_oz": usd_per_oz,
"meta": meta
}
if cuc_supported:
# If ever supported, you could directly ask the API to convert USD to CUC,
# then usd_per_oz * usd_to_cuc gives cuc_per_oz.
meta["notes"].append("CUC supported by provider; prefer direct conversion.")
out["cuc_per_oz"] = None # would be filled from Convert endpoint result
return out
# 3) Fallback: apply internal mapping
usd_to_cuc = internal_usd_to_cuc(hist["date"])
if usd_to_cuc is None:
meta["mapping_source"] = "N/A"
meta["notes"].append("No internal USD→CUC mapping for date; record flagged.")
out["cuc_per_oz"] = None
out["flag"] = "NO_CUC_MAPPING"
return out
meta["mapping_source"] = "LegacyFXTable v2.1 (audited)"
cuc_per_oz = usd_per_oz * usd_to_cuc
out["cuc_per_oz"] = cuc_per_oz
return out
if __name__ == "__main__":
result = reconcile_cuc_for_date("2020-06-30", metal_symbol="XAU")
print(result)
What this delivers in production:
- Resilience: Your ETL does not fail just because CUC is unavailable; it produces a reproducible, well-labeled record.
- Auditability: The mapping source is attached to each record.
- Consistency: Metals pricing always anchored to a reliable base (USD) from Metals-API Documentation, with your internal currency leg applied deterministically.
Interpreting key response fields that matter for reconciliation
- success: Controls branching. If false, never attempt to parse rates.
- timestamp: Use to tie to UTC and ensure that your EOD aligns with your policy.
- date: Often enough for daily reconciliation. Store both date and timestamp.
- base: Typically USD. Document whether your internal mapping expects USD as a base.
- rates: For metals, values are oz per USD (as illustrated by the example payloads). Derive USD per oz by inversion.
- unit: “per troy ounce.” Always propagate this into your lineage to avoid unit drift.
- error.code and error.info: Attach to logs and monitoring. Alerts should differentiate “invalid_symbols” from “invalid_access_key.”
Data architecture and lineage for CUC reconciliation
To pass audits and support reprocessing, your architecture should capture:
- Raw Metals-API response payloads (immutable storage), keyed by date and symbol set.
- Derived tables with:
- USD per troy ounce for each metal and date.
- Your applied USD→CUC factor per date, including a source/version column and a data-quality flag.
- Final cuc_per_oz and optional cuc_per_g with a unit column.
- Job metadata: API key ID (not the secret), endpoint, query parameters, timestamp, cache hits/misses.
Change management and reproducibility
- Version your internal CUC mapping source.
- Pin your Metals-API query parameters and store them alongside outputs for future reruns.
- Ensure you can replay a date range using the exact same logic to produce bitwise-identical results.
Caching, quotas, and performance
- Cache historical responses: Daily snapshots don’t change. A local cache or object storage can cut API calls dramatically.
- Batch windows: Use the Time-series Endpoint for contiguous day ranges rather than looping single-date calls when feasible.
- Weekend/holiday awareness: Pre-compute business calendars per commodity/currency policy and skip empty days where applicable.
Security and key management
- Never hardcode API keys in repositories. Use environment variables or secrets managers.
- Restrict egress in production where possible and allowlist Metals-API domains.
- Log key IDs or aliases, not raw keys, when recording lineage.
Data validation and sanitization
- Schema checks: Ensure success is a boolean, base is a string, rates is a mapping, and unit is as expected.
- Range sanity checks: Alert on rates outside expected bands to catch upstream anomalies.
- Unit tests: Include an explicit test for unsupported symbols like CUC so error-handling paths remain correct.
Troubleshooting common pitfalls with CUC
- “I requested CUC and got success=false”: This is the expected outcome if the symbol is unsupported. Use your internal mapping and log the reason.
- “My derived cuc_per_oz changed after a rerun”: Confirm that your internal mapping table has not been modified. Version and lock it.
- “Numbers don’t match accounting’s spreadsheet”: Verify unit conversions (oz vs g), the base direction (USD→metal vs metal→USD), and the exact date cut.
- “Time-series has gaps”: This is normal around weekends/closures. Decide whether to carry-forward or mark gaps; document the policy.
Advanced techniques for a rock-solid reconciliation pipeline
- Immutable raw zone: Store every API response untouched. Downstream tables should be entirely recomputable from this raw data plus your internal mapping.
- Deterministic transforms: Avoid non-deterministic rounding; standardize rounding at the end of the pipeline with explicit precision rules.
- Observability: Emit metrics for success rates, unsupported symbol counts (CUC), and fallback usage so you can trend and alert on anomalies.
- Backpressure and retries: Implement exponential backoff on transient HTTP errors. For validation failures (e.g., invalid symbol), do not retry; switch to fallback immediately.
Compliance notes for legacy currencies
- Document your reliance on internal CUC mappings, including the source of those mappings and who approved them.
- Attach the Metals-API request/response metadata to each reconciled record to show how market reference data influenced the final value.
- Ensure your internal policies describe how to handle discontinued symbols consistently across all systems.
Step-by-step: building your CUC backfill job
- Check symbol availability once at job start by calling a historical endpoint with symbols=CUC. Cache the result for the run.
- Fetch time-series metals data (e.g., XAU) for your required date range with base=USD.
- For each date:
- Compute USD per troy ounce.
- Lookup your USD→CUC factor for that date. If missing, flag the record and follow your exception policy.
- Produce cuc_per_oz and optional cuc_per_g with explicit units.
- Write detailed lineage, including API timestamp and mapping source version.
- Generate a reconciliation report that summarizes:
- Number of dates with internal CUC mapping applied.
- Number of dates flagged due to missing mapping.
- Any outliers based on your sanity checks.
Examples of error handling that you can copy
Unsupported symbol in Historical Rates
{
"success": false,
"error": {
"code": "invalid_symbols",
"info": "One or more specified symbols are not supported: CUC"
}
}
Action: Do not retry. Use internal mapping and log an event with category=UNSUPPORTED_SYMBOL and symbol=CUC.
Successful Historical Rates with metals you need
{
"success": true,
"timestamp": 1593532799,
"base": "USD",
"date": "2020-06-30",
"rates": {
"XAU": 0.000480
},
"unit": "per troy ounce"
}
Action: Invert XAU to get USD per oz, apply USD→CUC from your internal table, and record the mapping source.
End-to-end testing approach
- Golden-record tests: Fix a small date range and freeze both Metals-API responses (via a local cassette) and your internal CUC table. Assert identical outputs across runs.
- Error-path tests: Simulate invalid_symbols for CUC and verify that your logs, metrics, and outputs match expectations.
- Unit conversion tests: Validate oz→g and oz→kg conversions independently.
Operational guardrails and monitoring
- Pre-flight symbol check: Run once per job. If CUC still unsupported, skip any outbound calls that rely on it.
- Rate-limit safety: Space out large time-series calls; cache to minimize calls. Consult the Metals-API Documentation for plan-specific details.
- Alerting: Notify if your internal CUC lookup fails for any date that historically should exist.
Practical notes on units, base, and weekends
- Units: “per troy ounce” is the standard. If your accounting uses grams, define a single, global constant 1 oz t = 31.1034768 g and never redefine it inline.
- Base currency: With base=USD, rates are in oz per USD for metals. If you need USD per oz, invert. Base changes later can break dashboards—pin it.
- Weekends/closures: Expect missing days. Align your EOD to UTC unless policy states otherwise; if so, document the conversion rule.
Metadata to store for audit trails
- API endpoint, parameters, and the raw JSON.
- Internal CUC source ID/version and the numeric factor applied.
- Computation path (e.g., inverted oz per USD → USD per oz → CUC per oz).
- Precision and rounding policy used for final outputs.
Performance and scaling tips
- Chunk time-series windows by month or quarter to balance payload size and retries.
- Use idempotent job IDs for reruns; write outputs to partitioned storage keyed by date and symbol.
- Compress raw responses in object storage; they are excellent for forensics.
Security best practices
- Store API keys in a secret manager; rotate regularly.
- Restrict developer-level keys from production data pipelines.
- Use TLS pinning where appropriate and validate HTTPS certificates.
Documentation and symbol catalog
Before you finalize the integration, inspect the catalog to confirm symbol availability and any relevant notes: Explore all supported symbols. Then review request parameters, error formats, and response fields here: Metals-API Documentation.
Call to action: get your API key and start validating CUC workflows
Sign up for a free API key and begin testing historical and time-series queries today. Start by confirming your symbol set and building the CUC fallback path that meets your organization’s reconciliation policy. Get started now at the Metals-API Website.
Comparison: what changes when a currency is unsupported like CUC
| Dimension | Supported currency | CUC (unsupported) |
|---|---|---|
| Direct API rates | Available in rates | Returns error.invalid_symbols |
| Convert endpoint | Direct cross-rate result | Error path; use internal mapping |
| Audit trail | Provider + timestamp | Provider for metals + internal mapping source/version |
| Reproducibility | Rerun with same params | Rerun with same params + same internal table version |
| Monitoring | HTTP errors & drift | Unsupported symbol alerts + missing mapping alerts |
Additional reading
- Official Metals-API endpoint reference
- Browse supported symbols and codes
- What is a troy ounce?
- Background on the Cuban Convertible Peso (CUC)
Conclusion
CUC’s deprecation does not block you from delivering reconciliation-ready historical prices. With Metals-API, you can anchor metals prices to a dependable USD base and then apply your internal, auditor-approved CUC mapping to produce repeatable, well-documented results. The keys are rigorous error handling for unsupported symbols, explicit unit conversions, thorough metadata capture, and consistent policies for weekends and missing dates. Start by testing symbol availability, building your fallback path, and automating a lineage-rich pipeline. To implement this today, explore the Metals-API Documentation, verify symbols via Metals-API Supported Symbols, and get a free key at the Metals-API Website.
FAQ
Can I get direct CUC prices from Metals-API?
If CUC is unsupported, direct prices will not be available and requests including CUC will return an error. Use an internal, approved CUC mapping for reconciliation and clearly document the source.
Which endpoints should I use for historical backfills?
Use the Historical Rates endpoint for per-date snapshots and the Time-series endpoint for multi-day windows. Keep base=USD for consistency, and apply your CUC mapping downstream.
How do I convert oz to grams or kilograms correctly?
Use 1 troy ounce = 31.1034768 grams. Store this constant in code or configuration and apply it uniformly. Include a unit column in your outputs.
What if my accounting team needs a precise EOD definition?
The API uses UTC. Align to UTC EOD unless your policy states otherwise; if different, document your offset/roll rules and apply them consistently.
How should I handle weekends or market closures?
Expect missing or unchanged days. Decide whether to carry-forward the last available value or to flag gaps; document this as a policy and implement it consistently.
How do I keep my pipeline auditable?
Store raw API responses, transformation code versions, internal CUC mapping version, and final outputs with units and timestamps. Emit logs and metrics for unsupported symbols and fallback usage.
Where can I review supported symbols and full API details?
See the Metals-API Supported Symbols and the Metals-API Documentation for the latest information. Then get your key at the Metals-API Website to begin testing.