Stream real-time currency FX rates using GoldAPI.WebSockets
Currency dashboards, international checkout systems, treasury screens, and cross-border pricing services often need exchange rates to remain current after the page has loaded. Calling a REST endpoint on a timer is useful for occasional conversion, but continuous polling adds request overhead and can leave every consumer running its own refresh schedule.
GoldAPI.io WebSockets provide a persistent, push-based alternative. Connect once, subscribe to a concrete foreign-exchange channel such as fx:USDEUR, and process normalized price.update messages whenever a new rate is available.
This guide explains how to get real-time currency FX rates using the same authentication flow, channel conventions, and GoldAPI.io WebSockets protocol documented in the GoldAPI.io API reference. The complete Node.js example streams several currency pairs and exposes the fields needed for conversion displays, bid/ask monitoring, and live business workflows.
References:
- GoldAPI.io WebSocket API
- GoldAPI.io WebSockets protocol reference
- GoldAPI.io dashboard
- GoldAPI.io plans and quotas
What can you build with a real-time FX GoldAPI.io WebSockets?
A GoldAPI.io FX WebSockets is useful when the same screen or service must react to currency movement continuously rather than perform a one-off conversion.
Typical use cases include:
- A live exchange-rate dashboard with multiple currency tiles.
- International e-commerce pricing that refreshes indicative local-currency totals.
- A treasury screen monitoring base-currency exposure across regions.
- Cross-border invoicing and settlement tools.
- Travel-money and remittance quote interfaces.
- Precious-metals dashboards that combine
metals:*andfx:*channels. - Alerting when an FX price, bid, ask, or spread reaches a configured threshold.
- Internal pricing services that distribute one current rate snapshot to many applications.
Keep commercial decisions outside the market-data transport. Fees, margins, rounding, settlement rules, tax, and the period for which a customer quote remains valid should be applied by your own pricing service.
GoldAPI.io FX WebSockets channel names and update payloads
GoldAPI.io FX channels use this format:
fx:BASEQUOTEExamples:
fx:USDEUR— US dollar to euro.fx:GBPAUD— British pound to Australian dollar.fx:EURJPY— euro to Japanese yen.fx:USDAED— US dollar to UAE dirham.
The first code is the base currency and the second is the quote currency. A rate of 0.8674 for fx:USDEUR means one US dollar corresponds to approximately 0.8674 euros at that moment.
Subscribe only to supported concrete pairs. The fx:* value returned during authentication is an authorization capability, not a wildcard subscription.
Real-time GoldAPI.io FX WebSockets price.update example
Currency WebSocket data follows the normalized field names used by GET /api/rates/{base}/{quote}:
{
"type": "price.update",
"channel": "fx:USDEUR",
"publishedAt": 1793951105,
"data": {
"timestamp": 1793951105,
"base": "USD",
"quote": "EUR",
"exchange": "GAPI:USDEUR",
"symbol": "GAPI:USDEUR",
"price": 0.8674,
"bid": 0.8673,
"ask": 0.8675
}
}Use data.price for an indicative conversion rate. Use bid and ask when the workflow needs both sides of the quote. The publishedAt value identifies when the WebSocket update was published, while data.timestamp describes the underlying rate snapshot.
Connect to GoldAPI.io WebSockets in five stages
The dedicated GoldAPI.io WebSocket API key must remain in a trusted environment. It is exchanged for a temporary session token before the WebSocket connection begins.
Stage 1: issue a short-lived WS token
Send an HTTPS request from your backend:
POST /api/ws/token HTTP/1.1
Host: www.goldapi.io
x-ws-api-key: YOUR_DEDICATED_WEBSOCKET_API_KEYThe response provides a short-lived ws token, its expiration time, the websocketUrl, channel capabilities, connection limits, and token-request usage. Tokens currently last 15 minutes.
The dedicated GoldAPI.io WebSocket key differs from the GoldAPI REST API key. Never place it in browser source code, a public repository, a query string, or application logs.
Stage 2: open the secure WebSocket
Connect to the URL returned by the token endpoint. The production endpoint is:
wss://ws.goldapi.io/v1The server first announces the protocol version:
{
"type": "welcome",
"protocolVersion": 1
}Stage 3: authenticate the open connection
Send the temporary ws token rather than the dedicated WebSocket key:
{
"type": "auth",
"token": "GOLD_WS_SESSION_TOKEN",
"requestId": "fx-session-auth"
}The server confirms the effective connection policy:
{
"type": "authenticated",
"requestId": "fx-session-auth",
"allowedChannels": ["metals:*", "fx:*"],
"maxConnections": 1,
"maxChannelsPerConnection": 10,
"expiresAt": "2026-11-06T08:20:00.000Z"
}Always wait for authenticated before sending a subscription command.
Stage 4: subscribe to currency pairs
One connection can carry several FX subscriptions within the plan allowance:
{
"type": "subscribe",
"requestId": "fx-dashboard-subscribe",
"channels": [
"fx:USDEUR",
"fx:GBPAUD",
"fx:EURJPY"
]
}The acknowledgement echoes the request identifier and accepted channels:
{
"type": "subscribed",
"requestId": "fx-dashboard-subscribe",
"channels": [
"fx:USDEUR",
"fx:GBPAUD",
"fx:EURJPY"
]
}To stop one or more feeds without closing the socket, send the same structure with "type": "unsubscribe".
Stage 5: maintain the application heartbeat
Send a ping approximately every 25 seconds and correlate the pong by requestId:
{
"type": "ping",
"requestId": "fx-ping-1793951105000"
}{
"type": "pong",
"requestId": "fx-ping-1793951105000",
"timestamp": 1793951105
}Complete Node.js GoldAPI.io FX WebSockets example
The following client is based on the GoldAPI.io API documentation example, adapted for currency-rate channels. It obtains a session, authenticates, subscribes, prints normalized FX updates, maintains the heartbeat, and reconnects after closure.
Install the WebSocket client:
npm install wsSet the dedicated key in the server environment:
export GOLDAPI_WS_API_KEY="YOUR_DEDICATED_WEBSOCKET_API_KEY"Create stream-fx-rates.js:
// Node.js 18+ · npm install ws
const WebSocket = require('ws');
const channels = ['fx:USDEUR', 'fx:GBPAUD', 'fx:EURJPY'];
let heartbeatTimer;
let reconnectAttempts = 0;
async function requestSession() {
const response = await fetch('https://www.goldapi.io/api/ws/token', {
method: 'POST',
headers: {
'x-ws-api-key': process.env.GOLDAPI_WS_API_KEY
}
});
const session = await response.json();
if (!response.ok) {
throw new Error(session.error || 'Unable to issue WebSocket token');
}
return session;
}
function beginHeartbeat(socket) {
const ping = () => {
if (socket.readyState !== WebSocket.OPEN) return;
socket.send(JSON.stringify({
type: 'ping',
requestId: 'fx-ping-' + Date.now()
}));
};
ping();
heartbeatTimer = setInterval(ping, 25000);
}
async function connect() {
const session = await requestSession();
const socket = new WebSocket(session.websocketUrl);
socket.on('open', () => {
socket.send(JSON.stringify({
type: 'auth',
token: session.token,
requestId: 'fx-session-auth'
}));
});
socket.on('message', raw => {
let message;
try {
message = JSON.parse(raw.toString());
} catch (error) {
console.error('Invalid WebSocket JSON:', error);
return;
}
if (message.type === 'authenticated') {
reconnectAttempts = 0;
socket.send(JSON.stringify({
type: 'subscribe',
channels,
requestId: 'fx-dashboard-subscribe'
}));
beginHeartbeat(socket);
return;
}
if (message.type === 'price.update' && message.channel.startsWith('fx:')) {
const { base, quote, price, bid, ask, timestamp } = message.data;
console.log({ base, quote, price, bid, ask, timestamp });
return;
}
if (message.type === 'error') {
console.error('GoldAPI WebSocket error:', message.code, message.message);
}
});
socket.on('close', (code, reason) => {
clearInterval(heartbeatTimer);
console.log('FX WebSocket closed:', code, reason.toString());
const delay = Math.min(30000, 1000 * (2 ** reconnectAttempts));
reconnectAttempts += 1;
setTimeout(() => connect().catch(console.error), delay);
});
socket.on('error', error => {
console.error('FX WebSocket transport error:', error);
});
}
connect().catch(console.error);Run the stream:
node stream-fx-rates.jsGoldAPI.io WebSockets availability by plan
WebSocket access is not identical across GoldAPI.io plans.
| Plan | FX WebSocket availability | Concurrent connections | Channels per connection | Request policy |
|---|---|---|---|---|
| Free | Evaluation access | 1 | 10 | 150 shared REST, WebSocket-token, and MCP market-data requests per month |
| Pro | Not included | 0 | 0 | Unlimited REST requests only |
| Business | Production access | 5 | 20 | Unlimited REST with production WebSocket access |
On Free, successfully issuing a WebSocket token consumes one request from the shared monthly allowance. Connecting, subscribing, and receiving FX price.update messages do not increment the monthly counter for every message.
Use Free to evaluate channel behavior and develop a proof of concept. Use Business for production dashboards, treasury applications, customer-facing conversion tools, or services that need more simultaneous connections and subscribed currency pairs. Pro remains REST-only and cannot authenticate to the GoldAPI.io WebSocket service.
Architecture for a real-time currency dashboard
A browser must not receive the long-lived dedicated GoldAPI.io WebSocket key. Use one of these patterns.
Temporary browser session
Authenticated browser
↓ requests an FX session
Your backend
↓ sends x-ws-api-key
GoldAPI.io POST /api/ws/token
↓ returns short-lived token
Browser connects to wss://ws.goldapi.io/v1The browser can then authenticate with the temporary token and subscribe directly. Protect your backend session endpoint so only authorized users can request tokens.
Server-side market-data relay
For a larger application, keep the GoldAPI.io connection on your server:
GoldAPI.io FX WebSocket
↓
Rate validation and latest-value cache
↓
Margin, rounding, and conversion rules
↓
Your WebSocket or event bus
↓
Dashboards, checkouts, and internal servicesThis gives many internal consumers one controlled market-data source and centralizes subscription restoration, monitoring, access rules, and commercial calculations.
Process GoldAPI.io FX WebSocket updates safely
When a message arrives:
- Confirm
message.type === "price.update". - Check that
message.channelbegins withfx:. - Validate
baseandquoteagainst the expected subscription. - Compare
data.timestampwith the currently cached rate so an older event cannot overwrite a newer value. - Use decimal-safe arithmetic for monetary calculations.
- Apply fees, spreads, and rounding after preserving the raw market-data values.
- Show the rate timestamp and quote-expiry policy to users.
For example, an international checkout may use the streamed rate to refresh an indicative display while fixing the final customer amount only when the order is submitted. A treasury dashboard may show the raw price, bid, ask, and age of the latest update without producing a customer quote.
Handle errors, token expiry, and reconnection
Protocol errors contain a stable code and readable message:
{
"type": "error",
"channel": "fx:USDEUR",
"code": "PRICE_UNAVAILABLE",
"message": "No valid cached quote available."
}Recommended handling:
- Treat
PRICE_UNAVAILABLEas a channel-level condition. Keep the connection open and wait for valid data. - After
TOKEN_EXPIREDor close code4001, request a new token before reconnecting. - Clear heartbeat timers whenever the transport closes.
- Re-authenticate and restore every required subscription after reconnecting.
- Use bounded exponential backoff to avoid a tight reconnect loop during an outage.
- Monitor the age of each currency pair independently.
- Keep credentials and temporary tokens out of error logs.
Start streaming real-time FX rates using GoldAPI.io WebSockets
Sign in to the GoldAPI.io dashboard, obtain the dedicated WebSocket API key, and run the Node.js example with a supported currency pair. Refer to the GoldAPI.io WebSocket protocol for the current authentication flow, message types, errors, channel limits, and payload definitions.
