How to Integrate a Forex WebSocket API
Integrating a forex WebSocket API means authenticating your server, selecting currency pairs and keeping incoming updates flowing through connection interruptions. This checklist covers those steps for QUOTC, with links to the message definitions and complete Python and Node.js clients.
Integrating a forex WebSocket API means authenticating your server, selecting currency pairs and keeping incoming updates flowing through connection interruptions. This checklist covers those steps for QUOTC, with links to the message definitions and complete Python and Node.js clients.
QUOTC quotes are algorithmically generated, not market prices, and do not reflect actual market conditions. Read the Risk Warning before deciding whether the data fits your product.
The connection belongs on your backend. Your frontend receives display updates from your application, while the API key remains on the server.
Before you start with a forex WebSocket API
Prepare your server before creating a test key. Confirm its public IP address and how your application will receive its credentials.
You need:
A server with a known public IPv4 or IPv6 address.
A QUOTC test key bound to that address.
The key stored in an environment variable.
A backend process that can maintain a WebSocket connection.
Logs for connection status, authentication and interruptions.
The free test key provides 10 currency pairs for 14 days from creation, with one test key per account.
Use the environment variable QUOTC_API_KEY, as in the official examples. Keep its value out of source files, repositories and diagnostic output.
The registered address must match the public IP used by your outgoing connection. A private address inside your server network is not sufficient.
Review the documentation on keys and IP binding and the guide to IP-bound API keys.
Connect and authenticate
Open a WebSocket connection to wss://wss.quotc.net.
Within 10 seconds of opening it, send an authentication message containing your key and set protocol to 2.
The protocol setting enables service messages, including auth_ok and subscribed. These responses help your client distinguish an open socket from an authenticated session.
Do not treat a successful WebSocket handshake as proof that the key was accepted. Wait for auth_ok before continuing with subscription setup.
The authentication response contains:
| Item | Meaning | What to check |
|---|---|---|
| auth_ok | Authentication succeeded | Continue with pair selection |
| symbols | Pairs available to the key, including their symbols, labels and decimal precision | Confirm your requested pairs are available |
| expiresAt | Key expiry time in Unix seconds, UTC | Convert using seconds, not milliseconds |
Keep authentication failures visible in your logs without recording the token itself.
For exact message formats, follow the documentation on connection and authentication.
Read and interpret quote messages
QUOTC sends one quote message every second for each available pair, subject to your subscription selection.
The stream also carries service messages. Identify the message type before sending its contents to charting or storage logic.
Use the following field definitions:
| Field | Meaning | How to use it |
|---|---|---|
| symbol | Pair identifier, such as EURUSD | Route the update to the correct instrument |
| value | Closing value of the last second | Use as the second’s close or latest displayed value |
| open | Opening value of the last second | Preserve when building longer candles |
| high | Highest value of the last second | Use when calculating an interval’s high |
| low | Lowest value of the last second | Use when calculating an interval’s low |
| volume | Relative activity of the last second | Display as activity, not traded volume |
| ts | Unix timestamp in milliseconds, UTC | Use for ordering, storage and candle boundaries |
The price fields summarise the last second. They should not be interpreted as separate transaction records.
Keep the original timestamp in stored records. Convert it to a readable date only where your interface or logs need one.
Use timezone-aware UTC values internally. Apply a user’s preferred time zone when displaying the data.
Review the quote field definitions before connecting the stream to existing chart components.
Select pairs with subscribe
By default, an authenticated connection receives all pairs available to its key.
Send subscribe to limit the stream to a chosen list. Use API symbols such as EURUSD and USDJPY, rather than display labels containing slashes.
The server responds with subscribed, confirming the selected symbols.
Check that response against your application’s requested list. Pairs unavailable to the key are ignored, so a connection can succeed without delivering every pair you requested.
Make sure the confirmed selection contains at least one pair before expecting quote traffic.
You can send another subscription message to change the list. After reconnecting, authenticate again and reapply your intended selection.
The documentation on ping and subscription requests contains the message formats.
Keep the connection healthy
An open socket does not guarantee that useful updates are still arriving. Monitor both the connection and the quote stream.
Send JSON ping every 30 seconds
Send QUOTC’s application-level JSON ping message every 30 seconds. The server returns pong with the same timestamp.
This exchange is separate from WebSocket protocol Ping and Pong frames.
A library’s automatic protocol keepalive does not send QUOTC’s JSON message. Configure the application-level heartbeat explicitly, following the documentation.
Process pong responses separately from quotes. A pong confirms a heartbeat response; it should not be stored as a price update.
Reconnect after 10 seconds without quotes
As an integration recommendation, treat the connection as dead if no quote arrives for 10 seconds after authentication and a valid subscription.
This is a suggested client-side timeout, not a QUOTC rule.
Track elapsed time using a monotonic timer. Reset it when a quote arrives, rather than when any message arrives.
If the timeout expires, close the existing socket and reconnect after three to five seconds. Authenticate and subscribe again.
An explicit access rejection takes priority: if you receive close code 1008, stop instead of retrying.
Also ensure that slow processing is not creating the apparent silence. Database writes and other blocking work should not prevent the receiver from reading messages.
Reconnect according to the failure
Use one reconnection controller for each connection. Multiple timers responding to the same failure can create duplicate sockets.
| Event | Recommended action |
|---|---|
| Close code 1008 | Stop. Check the key status, server IP and connection count before restarting |
| Close code 1011 | Wait 3–5 seconds, reconnect and authenticate again |
| Network error or service restart | Wait 3–5 seconds, then reconnect |
| HTTP error during the WebSocket handshake, such as 503 during a service restart | Wait 3–5 seconds, then attempt a new connection |
| No quotes for 10 seconds after a valid subscription | Close the socket and reconnect after 3–5 seconds, using the recommended client timeout |
| Unknown message type | Log it and ignore it; do not stop the client |
| Invalid configuration (missing key, requested pairs unavailable) | Stop and fix the configuration instead of retrying |
Code 1008 can indicate an unknown, inactive, expired or deleted key, an incorrect IP, too many connections or missed authentication.
Retrying unchanged credentials does not resolve those conditions.
Handle handshake failures as well as closures of established connections. An HTTP error can occur before your client has a WebSocket close code.
Cancel old heartbeat tasks and timeout checks before starting another session.
See the documentation on close codes and reconnecting.
Python and Node.js clients
The official documentation provides complete clients for both languages.
| Integration | Library used by the official example | Where to start |
|---|---|---|
| Python | websockets, with asyncio | Official Python client |
| Node.js | ws | Official Node.js client |
Both clients are available in the complete code examples.
In Python, organise receiving, heartbeat and reconnection tasks so they end cleanly when a session closes.
Check timestamp conversion and exception handling before adding database writes.
In Node.js, clear old intervals when a connection closes, before opening another socket.
Before moving to production
Each key permits up to 10 simultaneous connections. Count all processes sharing it, including development tools, workers and background services.
Receive WebSocket forex data on your backend and relay the required updates to your frontend. Avoid creating an upstream connection for every visitor.
Keep the key out of browsers, mobile applications and public repositories. If it leaks, contact support to replace it.
IP changes also go through support. Plan that step before moving the client to a server with a different public address.
A production key covers 58 currency pairs and costs 500 USD per month per key. Activation and renewal are handled manually through support after payment.
Contact support to arrange payment. Review the product overview and the test-key-to-production guide before switching access.
Frequently asked questions
Can I connect to a forex WebSocket API for free?
QUOTC offers one free test key per account. It provides 10 currency pairs for 14 days from creation, rather than permanent free access.
Which libraries do the Python and Node.js examples use?
The official Python example uses websockets with asyncio. The Node.js example uses ws.
Both complete clients are available in the documentation’s examples section.
Why does the connection close with code 1008?
Check the key status, registered server IP and connection count. Authentication must also be sent within 10 seconds.
Stop automatic retries with the same key until the cause is resolved.
Why do quote timestamps and key expiry use different units?
Quote field ts uses Unix milliseconds. Authentication field expiresAt uses Unix seconds.
Convert each according to its definition and use an explicit time zone.
Do pong responses mean the quote stream is healthy?
They confirm heartbeat responses, but do not confirm quote delivery.
Monitor quotes separately. We recommend reconnecting after 10 seconds without quotes following authentication and a valid subscription.
Start your integration: create a QUOTC account and request a free test key for 10 currency pairs over 14 days.