Guinean Franc (GNF) - N/A Price API integration guide for Node.js applications
You need to show live Guinean Franc (GNF) exchange rates in a Node.js app so you can price, convert, or reconcile payments in Guinea. By the end of this guide, you’ll fetch the latest GNF price via Metals-API, parse the response safely, invert where needed (GNF per USD vs USD per GNF), and ship production-ready code that handles caching and non-trading periods.
What you’ll build: a reliable “latest GNF” fetcher
We’ll integrate the Latest Rates endpoint to retrieve the current Guinean Franc price relative to USD, plus its reciprocal (USD per GNF). We’ll use only the symbols you ask for, keep payloads small, and return data your app can consume immediately.
- Endpoint: Latest Rates
- Symbols: GNF, USDGNF (GNF per USD and USD per GNF)
- Environment: Node.js (native fetch or Axios)
- Use cases: spot pricing, currency conversion UIs, payment reconciliation, hedging dashboards
If you’re new to Metals-API, check supported codes first at the Symbols page, then create an API key: Register.
How Metals-API quotes currencies, and why inversion matters
By default, Metals-API returns rates with base=USD. For currencies:
- rates.GNF = GNF per 1 USD (how many Guinean Francs one US dollar buys)
- rates.USDGNF = USD per 1 GNF (the reciprocal; how many US dollars one Guinean Franc buys)
That means your UI or pricing math can pick whichever is more convenient:
- To convert USD → GNF, multiply by rates.GNF
- To convert GNF → USD, multiply by rates.USDGNF
Request the latest GNF price (curl)
Use the Latest Rates endpoint and specify only the symbols you need. Replace YOUR_API_KEY with your key.
curl "https://metals-api.com/api/latest?access_key=YOUR_API_KEY&symbols=GNF,USDGNF"
Official sample response
The JSON below is a real Metals-API response for this request. Copy it for tests and contract validation.
{"success":true,"timestamp":1791677280,"date":"2026-10-11","base":"USD","rates":{"GNF":8780.6046235,"USD":1,"USDGNF":0.0001138873736921996}}
Fields you’ll actually use:
- success: Boolean — check first; if false, read the error payload.
- timestamp: Unix seconds — when the price was last updated by the service.
- date: ISO date — the calendar date associated with the quote (UTC).
- base: Currency code — USD by default.
- rates.GNF: Number — GNF per 1 USD.
- rates.USDGNF: Number — USD per 1 GNF (reciprocal of GNF).
Node.js: fetch, validate, invert, and cache
The script below calls the same endpoint, verifies the payload, and exposes small helpers to convert between USD and GNF. It also shows a basic in-memory cache to reduce API calls.
import 'node-fetch'; // If on Node <=18. For Node 18+, global fetch is available.
// Minimal in-memory cache (per-process). For serverless, prefer a shared cache (Redis, KV).
const cache = {
key: 'GNF_LATEST',
data: null,
expiry: 0
};
const METALS_API_URL = 'https://metals-api.com/api/latest';
const API_KEY = process.env.METALS_API_KEY || 'YOUR_API_KEY';
const SYMBOLS = 'GNF,USDGNF';
// TTL guidance: align with your plan’s update frequency; e.g., 60s–600s.
// Use a longer TTL off-hours or when markets are closed.
const TTL_MS = 2 * 60 * 1000;
async function getLatestGNF() {
const now = Date.now();
if (cache.data && cache.expiry > now) {
return cache.data;
}
const url = `${METALS_API_URL}?access_key=${encodeURIComponent(API_KEY)}&symbols=${encodeURIComponent(SYMBOLS)}`;
const res = await fetch(url, { method: 'GET' });
if (!res.ok) {
throw new Error(`HTTP ${res.status} fetching latest GNF`);
}
const json = await res.json();
// Basic validation
if (!json.success) {
const err = json.error ? JSON.stringify(json.error) : 'Unknown Metals-API error';
throw new Error(`Metals-API error: ${err}`);
}
if (!json.rates || typeof json.rates.GNF !== 'number' || typeof json.rates.USDGNF !== 'number') {
throw new Error('Unexpected payload: missing GNF or USDGNF');
}
// Cache and return
cache.data = json;
cache.expiry = now + TTL_MS;
return json;
}
// Helpers: USD <-> GNF
export async function usdToGnf(usdAmount) {
if (typeof usdAmount !== 'number') throw new TypeError('usdAmount must be a number');
const { rates } = await getLatestGNF();
return usdAmount * rates.GNF; // GNF per 1 USD
}
export async function gnfToUsd(gnfAmount) {
if (typeof gnfAmount !== 'number') throw new TypeError('gnfAmount must be a number');
const { rates } = await getLatestGNF();
return gnfAmount * rates.USDGNF; // USD per 1 GNF
}
export async function getGnfQuote() {
const data = await getLatestGNF();
return {
base: data.base, // "USD"
date: data.date, // e.g., "2026-10-11" (UTC date)
timestamp: data.timestamp, // unix seconds
gnfPerUsd: data.rates.GNF, // e.g., 8780.60...
usdPerGnf: data.rates.USDGNF // e.g., 0.00011388...
};
}
// Example usage:
// (async () => {
// console.log(await getGnfQuote());
// console.log('100 USD => GNF', await usdToGnf(100));
// console.log('100000 GNF => USD', await gnfToUsd(100000));
// })();
Production details that save time
1) Symbols, base currency, and inversion
- Default base is USD. If you only need currency conversions with USD, you can omit a base parameter.
- For GNF pricing, request GNF and USDGNF together to avoid client-side inversion and rounding drift.
- Always confirm symbol codes at Symbols.
2) Timestamps and timezone
- timestamp is a Unix epoch (seconds). Convert appropriately: new Date(timestamp * 1000) in JavaScript.
- date is an ISO date in UTC. If you display local time, annotate the timezone in your UI.
- Do not assume continuous updates over weekends or holidays. Cache and show “as of” labels using timestamp.
3) Caching and request budgets
- Cache responses at your app edge (CDN) or in-memory between intervals. Align TTL with your plan’s update cadence (e.g., 60–600 seconds).
- Batch symbols you need in one call to reduce latency and calls (e.g., symbols=GNF,USDGNF).
- On errors or timeouts, serve the last-known-good value from cache and mark it “stale” in telemetry.
4) Weekend and market-closure behavior
- Expect the same date for multiple reads during closures; your UI should not blink or “jump to zero.”
- When the market reopens, the first tick may gap from the last close. If you compute deltas, use timestamp boundaries.
5) Precision and rounding
- For fiat currency displays, round to 0 decimals for GNF in consumer UIs, but keep full precision internally.
- When converting GNF→USD for accounting, preserve at least 6–8 decimals through calculation, then round only at presentation or posting time based on your policy.
Testing your integration with contract-first checks
Because Metals-API responses are concise, contract tests work well:
- success must be true
- base must equal "USD"
- rates.GNF must be a finite number greater than 0
- rates.USDGNF must be a finite number greater than 0 and roughly 1 / rates.GNF within a tight tolerance
- timestamp must be a recent Unix epoch
In Node, assert on these invariants before updating your UI state, and log variance if the inversion drift exceeds your threshold.
Going further: time-aware pricing and analytics
If you plan to chart or backfill GNF price movements against USD, evaluate the Historical and Time-series endpoints. These endpoints let you:
- Query a single date for “what was the GNF rate on YYYY-MM-DD?”
- Fetch a date range for trend visualization or statistical analysis
When you need the specifics of parameters and response schemas for those endpoints, see the Documentation.
Operational hardening
- Retry policy: Use short timeouts (e.g., 2–5s) with exponential backoff (max 2–3 retries). Don’t retry on 4xx.
- Observability: Log timestamp, date, and both rates (GNF, USDGNF), plus your cache hit/miss ratio.
- Fallbacks: If your SLA requires continuity, keep a rolling buffer (e.g., last 24 hourly quotes) to compute a temporary estimate only if absolutely necessary, and label it clearly.
- Security: Store YOUR_API_KEY in environment variables or a secrets manager; never commit it to Git.
Notes on metals vs currencies (and why GNF is straightforward)
Metals often use troy ounces for units and may require inversion to get USD per ounce (for example, USDXAG would be USD per 1 ounce of silver). By contrast, for GNF as a fiat currency, there is no metal unit involved; you will only work with currency amounts. The presence of both GNF and USDGNF in one response simplifies conversion in both directions without extra math.
Useful references and next steps
- API reference and query parameters: Documentation
- Supported symbols and what they mean: Symbols
- Get your API key (no free trial; choose a plan and start): Register
- Plan and capabilities overview: MCP
- ISO 4217 code reference for currencies: ISO 4217 official list
FAQ
Q: Which symbols should I request for GNF?
A: Request GNF and USDGNF together to get both directions: GNF per USD and USD per GNF. Example: symbols=GNF,USDGNF.
Q: What’s the base currency in the response?
A: USD by default. rates.GNF is GNF per 1 USD. rates.USDGNF is USD per 1 GNF.
Q: How often do rates update?
A: Update frequency depends on your plan. Cache according to the cadence shown for your subscription and annotate your UI with the provided timestamp.
Q: Do I need to handle weekends or holidays?
A: Yes. Expect unchanged dates and timestamps during closures. Serve cached quotes and display “as of” times to users.
Q: Is there a free trial?
A: No. There’s no free trial. Review options and pick a plan that fits your update needs. See MCP.
Ready to plug GNF into your Node.js pricing or reconciliation pipeline? Create your key in minutes and ship with confidence: Register. For endpoint details and parameters, keep the Documentation open while you code.