API documentation

QUOTC streams independently generated OTC quotes for 58 currency pairs over a WebSocket connection. Your server connects once, authenticates with an API key and receives a price for every available pair each second, 24/7.

Quick start

  1. Create an account and open My keys in your dashboard.
  2. Create a test key. Enter the public IPv4 or IPv6 address of the server that will connect to the feed: the key works only from that address.
  3. Copy the full key with the Copy button and store it on your server, for example in an environment variable. Test keys start with qtc_, production keys with prd_.
  4. From that server, open a WebSocket connection to the endpoint below and send the authentication message.
  5. Receive a tick for every available pair each second. Reconnect automatically if the connection drops.

API keys

Test key Production key
Currency pairs EUR/USD, USD/JPY, AUD/USD, USD/CAD, USD/CHF, NZD/USD, EUR/GBP, EUR/JPY, GBP/JPY, AUD/JPY All 58 pairs
Price Free 500 USD / month per key
Validity 14 days from creation, one per account Set by our team on activation
Key prefix qtc_ prd_

Create a production key in your dashboard, then open a support ticket to arrange payment. A new production key stays inactive until our team activates it and sets its expiry date. You can create several production keys, for example one per server.

Every key is bound to one server IP address. Connections from any other address are rejected. To change the address or renew a key, contact support from your dashboard.

Keep the key secret. Use it only on your server: never place it in browser code, mobile apps or a public repository. If a key leaks, contact support to replace it.

Connection

Endpoint wss://wss.quotc.net

Use any WebSocket client for your language. Within 10 seconds of opening the connection, send the authentication message with your key:

{"type": "auth", "token": "qtc_YOUR_KEY", "protocol": 2}

Set protocol to 2 to receive service messages (auth_ok, subscribed). Clients that omit it receive only ticks and pong messages.

After successful authentication the server replies with auth_ok. It lists the pairs available to the key and the key expiry time in Unix seconds (UTC):

{
  "type": "auth_ok",
  "expiresAt": 1795683600,
  "symbols": [
    { "symbol": "EURUSD", "label": "EUR/USD", "digits": 5 }
  ]
}

A key allows up to 10 simultaneous connections, so several services on the same server can share it.

Closing and reconnecting

Use the close code to decide whether to reconnect:

Code Meaning What to do
1008 Access denied: unknown key, connection from another IP, key inactive, expired or deleted, too many connections, or no authentication within 10 seconds. Do not reconnect with the same key. Check the key status and IP address in your dashboard.
1011 Key verification is temporarily unavailable. Reconnect after 3–5 seconds and authenticate again.
Other Network error or service restart. Reconnect after 3–5 seconds and authenticate again.

Open connections are checked again every minute. If a key is deactivated, expires, is deleted or replaced, its connections are closed with code 1008.

Quotes

Every second the server sends one message for each pair available to your key:

{
  "symbol": "EURUSD",
  "value": 1.11609,
  "open": 1.11608,
  "high": 1.11609,
  "low": 1.11608,
  "volume": 2,
  "ts": 1793091620000
}
Field Description
symbol Pair symbol, for example EURUSD. See the pair list below.
value Current price: the close of the last second.
open, high, low Open, high and low price of the last second.
volume Relative activity of the last second. It is comparable between pairs and is not a traded volume.
ts Tick time in Unix milliseconds (UTC).

Prices are rounded to the number of decimal places shown for each pair in the list below.

Requests

After authentication your client can send the following messages. Responses are shown after the arrow.

Ping

Keeps the connection alive through proxies. Send it every 30 seconds; the server replies with pong and the same timestamp.

{"type": "ping", "timestamp": 1793091620000}
→ {"type": "pong", "timestamp": 1793091620000}

Select pairs

By default you receive all pairs available to the key. Send subscribe to limit the stream to the listed pairs; pairs not available to the key are ignored. Send it again at any time to change the list.

{"type": "subscribe", "symbols": ["EURUSD", "USDJPY"]}
→ {"type": "subscribed", "symbols": ["EURUSD", "USDJPY"]}

Code examples

Complete clients that authenticate, print ticks and reconnect after network errors. Before running them, put your key in the QUOTC_API_KEY environment variable on the server whose IP is bound to the key.

// npm install ws
const WebSocket = require('ws');

const URL = 'wss://wss.quotc.net';
const API_KEY = process.env.QUOTC_API_KEY; // keep the key out of source code

function connect() {
  const ws = new WebSocket(URL);
  let ping;

  ws.on('open', () => {
    ws.send(JSON.stringify({ type: 'auth', token: API_KEY, protocol: 2 }));
    ping = setInterval(() => {
      ws.send(JSON.stringify({ type: 'ping', timestamp: Date.now() }));
    }, 30000);
  });

  ws.on('message', (raw) => {
    const msg = JSON.parse(raw);
    if (msg.type === 'auth_ok') {
      console.log('Authorized. Pairs:', msg.symbols.map((s) => s.symbol).join(', '));
    } else if (msg.symbol) {
      console.log(msg.symbol, msg.value, new Date(msg.ts).toISOString());
    }
  });

  ws.on('close', (code, reason) => {
    clearInterval(ping);
    if (code === 1008) {
      console.error('Access denied:', reason.toString(), '- check the key and server IP');
      return; // do not retry with the same key
    }
    setTimeout(connect, 3000); // network error or service restart
  });

  ws.on('error', (err) => console.error(err.message));
}

connect();

Connect from your server, not from the browser: the key is bound to the server IP and must stay secret. To show quotes on your website, relay them from your server to your visitors.

Available pairs

A production key covers all 58 pairs. The test key covers the pairs marked in the last column.

Symbol Pair Decimal places Test key
AUDCAD AUD/CAD 5 —
EURUSD EUR/USD 5 Yes
AUDJPY AUD/JPY 3 Yes
NZDUSD NZD/USD 5 Yes
AUDUSD AUD/USD 5 Yes
USDJPY USD/JPY 3 Yes
USDCAD USD/CAD 5 Yes
USDCHF USD/CHF 5 Yes
EURGBP EUR/GBP 5 Yes
EURJPY EUR/JPY 3 Yes
EURCAD EUR/CAD 5 —
GBPJPY GBP/JPY 3 Yes
EURAUD EUR/AUD 5 —
AUDCHF AUD/CHF 5 —
CHFJPY CHF/JPY 3 —
EURNZD EUR/NZD 5 —
CADCHF CAD/CHF 5 —
GBPCHF GBP/CHF 5 —
CADJPY CAD/JPY 3 —
GBPNZD GBP/NZD 5 —
NZDCAD NZD/CAD 5 —
NZDJPY NZD/JPY 3 —
GBPCAD GBP/CAD 5 —
NZDSGD NZD/SGD 5 —
USDSGD USD/SGD 5 —
USDSEK USD/SEK 5 —
USDCZK USD/CZK 3 —
EURHKD EUR/HKD 5 —
GBPUSD GBP/USD 5 —
EURCHF EUR/CHF 5 —
GBPAUD GBP/AUD 5 —
AUDNZD AUD/NZD 5 —
NZDCHF NZD/CHF 5 —
EURSEK EUR/SEK 5 —
GBPSEK GBP/SEK 5 —
EURCZK EUR/CZK 3 —
USDHKD USD/HKD 5 —
EURSGD EUR/SGD 5 —
GBPSGD GBP/SGD 5 —
AUDSGD AUD/SGD 5 —
SGDJPY SGD/JPY 3 —
USDNOK USD/NOK 5 —
EURNOK EUR/NOK 5 —
USDDKK USD/DKK 5 —
EURDKK EUR/DKK 5 —
USDPLN USD/PLN 5 —
EURPLN EUR/PLN 5 —
USDHUF USD/HUF 3 —
EURHUF EUR/HUF 3 —
USDTRY USD/TRY 5 —
EURTRY EUR/TRY 5 —
USDZAR USD/ZAR 5 —
USDMXN USD/MXN 5 —
USDCNH USD/CNH 5 —
USDINR USD/INR 3 —
USDILS USD/ILS 5 —
USDTHB USD/THB 3 —
USDAED USD/AED 5 —

About the data

QUOTC quotes are independently generated OTC prices. They follow the general level of the currency market but are not spot forex prices and do not repeat them tick by tick. Quotes are available 24 hours a day, 7 days a week, including weekends and holidays.

Questions about the integration? Contact us or open a ticket in your dashboard.