Skip to main content
Live market data over WebSocket: candles, volume footprint profiles and order books. Subscription parameters go in the query string of the connection URL, and the server pushes JSON text frames until you disconnect. The client sends nothing after the handshake.
Base URL: wss://public-api.takeprofit.com/api/v1/marketdata. History is a separate protocol — see the REST API.

Streams

Candles

The latest candle, then live updates of the forming one.

Volume footprint

An optional historical snapshot, then complete profile replacements.

Order book

One snapshot of the top levels per side, then incremental updates.

The handshake

The API key goes in the x-api-key header of the upgrade request, exactly as in REST. One header value is required; duplicate or comma-combined values are rejected. A failed handshake answers with a regular HTTP response and a JSON body: Unknown query parameters and repeated scalar parameters are rejected, and historical range parameters such as from, to and limit are not accepted: use REST for history.

Parameters the streams share

Frames

Every frame carries a type and a meta echo of the normalized subscription parameters. Candle frames also carry a numeric tag echoed from the upstream subscription: it is informational, and you can ignore it. Order book levels are keyed by numeric price, so "1.5" and "1.50" are the same level. An upstream resync is absorbed into a regular update, so you never see a second snapshot. Error frames carry a stable code: canceled, invalid_argument, unauthenticated, permission_denied, not_found, conflict, rate_limited, too_much_data, deadline_exceeded, unimplemented, unavailable or upstream_error. On the order book, too_much_data means the client did not read the stream fast enough for its depth.

Keepalive and reconnects

  • The server pings every 30 seconds. A client that does not answer with a pong within 5 seconds is disconnected. Most WebSocket libraries answer pings on their own; if your connections drop about 35 seconds in, check that yours does. There is no idle timeout besides that.
  • One connection carries one subscription. The query string is the whole subscription, and nothing can be added to an open connection. Open a connection per stream.
  • The server closes with code 1000. A terminal error first arrives as an error frame, then the close. The normal end of the upstream stream and an exhausted quota (rate_limited) close with the same code, so read the last frame to tell them apart.
  • Reconnect with exponential backoff, and treat a 503 on the handshake the same way. A reconnect is a new subscription and is charged again.

Credits

Streams spend their own quota of 1,000 credits per 300 seconds, shared by all API keys on your account and separate from REST. A subscription costs 10 credits for candles, 25 for footprint and 50 for the order book, charged when upstream data confirms it rather than per frame, and charged again in every window the connection stays open in. A stream that dies on a terminal upstream error before it is confirmed is not charged. The handshake needs the full price of the stream in remaining credits, otherwise it is rejected with 429. If an open stream cannot renew because the window is spent, it ends with an error frame with code rate_limited. How many streams the quota holds at once is worked out in Credits and limits.