Authentication
Your server authenticates with an API key. A web page never holds a key: your server hands it a short-lived token to open the stream.
API keys
Create your keys in your account. A key is shown only once, when it is created: copy it right away. We keep no readable copy, so a lost key cannot be recovered, only rotated.
| Key | Data | Use |
|---|---|---|
fc_test_… | Sandbox rights: delayed by 10 minutes, 7 days of history | Building and testing your integration, for free |
fc_live_… | The rights of your offers: real time with Live, full history with Historical. Without an offer, the Sandbox rights | Production |
A test key always has the Sandbox rights, whatever your offer. Apart from the delay, it behaves exactly like a live key: same messages, same cursors, same responses.
Send the key in the Authorization header, on every REST request and when opening the WebSocket:
curl https://api.fathomcharts.com/v1/usage -H "Authorization: Bearer $FATHOM_CHARTS_API_KEY"An invalid, expired or revoked key is rejected with 401 UNAUTHORIZED over REST; on the WebSocket, the connection is closed with code 4001. A valid key that lacks the required scope is rejected with 403 FORBIDDEN, or code 4003 on the WebSocket.
Scopes and restrictions
A key only grants what you allow it to. If it leaks, the damage stays contained: a key that only reads the stream has no business starting exports.
Scope (scopes) | Allows |
|---|---|
stream | The real-time stream, and creating browser tokens |
history | Historical queries and their estimates |
export | Exports |
keys | Managing keys through the API |
You can also restrict a key to specific instruments or IP addresses, and give it an expiry date. Through the API, with a key that has the keys scope:
curl https://api.fathomcharts.com/v1/keys \
-H "Authorization: Bearer $FATHOM_CHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"collecteur","environment":"live","scopes":["stream","history"],"instruments":["NQ.front"],"allowedIps":["203.0.113.0/24"]}'| Field | Content |
|---|---|
name | Key name, 1 to 64 characters |
environment | live or test |
scopes | At least one of stream, history, export, keys |
instruments | Optional: allowed instruments (up to 32). Omitted: all |
allowedIps | Optional: allowed IP addresses or CIDR ranges (up to 32). Omitted: any |
expiresAt | Optional: expiry date, as a timestamp in nanoseconds since January 1, 1970 (UTC) |
The response contains the full key in the key field, once. A key cannot create a key with broader rights than its own, nor a key of the other kind (test or live). GET /v1/keys lists your keys.
An account can have up to 10 active keys. All your keys share the same limits: creating more does not raise your quotas.
Rotating a key
To change a key without interrupting your service, rotate it (<id>: the key's id field, from GET /v1/keys):
curl -X POST https://api.fathomcharts.com/v1/keys/<id>/rotate \
-H "Authorization: Bearer $FATHOM_CHARTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"gracePeriodSeconds":172800}'You get a new key with the same scopes and restrictions. The old one keeps working during the grace period (gracePeriodSeconds, up to 7 days; 2 days here), giving you time to deploy the new key everywhere, and is then revoked. With 0, it is revoked immediately. A key can only be rotated once: a second rotation is rejected with 409 CONFLICT.
Revoking a key
DELETE /v1/keys/<id>, or from your account. Revocation is immediate: WebSocket connections opened with the key are closed within a second (code 4003).
Browser access
An API key must never appear in a web page: any visitor could read it. To show the stream in a browser:
- your server requests a stream token with its key;
- it passes the token to the page;
- the page opens the WebSocket and sends the token.
On the server:
curl -X POST https://api.fathomcharts.com/v1/stream-tokens -H "Authorization: Bearer $FATHOM_CHARTS_API_KEY"The response contains the token (token) and its expiry (expiresAt). With the SDK: FathomChartsRest.streamToken().
In the page, give the SDK a function that fetches a token from your server (here a /api/fathom-charts-token route of your backend that makes the call above). The SDK calls it on every connection and handles the rest:
import { FathomChartsStream } from '@fathom-charts/sdk';
const stream = new FathomChartsStream({
url: 'wss://stream.fathomcharts.com/v1',
streamToken: async () => {
const response = await fetch('/api/fathom-charts-token', { method: 'POST' });
const { token } = (await response.json()) as { token: string };
return token;
},
});
for await (const event of stream.subscribe({ instrument: 'NQ.front', indicator: 'big-trades', params: { minimum: 30 } })) {
console.log(event.type, event);
}Without the SDK, send the token in an auth message, first, within 5 seconds of opening the connection:
const { token } = (await fetch('/api/fathom-charts-token', { method: 'POST' }).then((r) => r.json())) as { token: string };
const ws = new WebSocket('wss://stream.fathomcharts.com/v1');
ws.onopen = () => {
ws.send(JSON.stringify({ t: 'auth', token }));
ws.send(JSON.stringify({
t: 'subscribe', sub: 'bt', instrument: 'NQ.front', indicator: 'big-trades',
params: { minimum: 30 }, mode: 'live', from: 'live',
}));
};
ws.onmessage = (e) => console.log(JSON.parse(e.data));Good to know:
- a token is valid for 60 seconds and works only once. It opens the connection, which then stays open as long as you need. Every reconnection needs a new token;
- the token has the same scopes and limits as the key that created it, and stops working if that key is revoked;
- any website can use a token: only hand tokens to your own users, once they are authenticated.
If the first message is not a valid auth, or does not arrive within 5 seconds, the connection is closed with code 4001.
Signing in to the portal
Your account (keys, offers, billing, usage) has no password. On the Sign in page, enter your email address: you receive a sign-in link valid for 15 minutes, usable once. You can request up to 5 links per hour.
Link rejected? It has expired or was already used: request a new one. Once signed in, your session stays open for 30 days in that browser.