Connecting to Crypto Exchange APIs for Arbitrage: WebSockets, Rate Limits and Order-Book Sync

In crypto arbitrage, the price gap between two exchanges usually lasts somewhere between a few hundred milliseconds and a couple of seconds. Your strategy can be clever, your capital can be ready and your fees can be negotiated down. If your connection to the exchanges is slow, out of sync or keeps getting rate-limited, the gap is gone before your order lands. For a cross-exchange bot, the API connection is the strategy. Everything else sits on top of it.

This guide covers the plumbing most arbitrage tutorials skip: how to connect to crypto exchange APIs properly. That means which interface to use for what, how to keep a local order book that matches the exchange, how to stay inside rate limits, how to lock down API keys, and how to stay connected 24/7. It is written for traders who run, or plan to run, an arbitrage bot across several exchanges. If you are still choosing a strategy, start with our cross-exchange crypto arbitrage bot guide and come back here when it is time to wire things up.

The anatomy of an arbitrage API connection

A working cross-exchange setup is not one connection but several, each with its own job. For every exchange you trade on, you typically keep:

  • A public market-data stream (WebSocket) that pushes order-book updates and trades the moment they happen.
  • An order-entry channel (REST, or a WebSocket/FIX order API where the exchange offers one) to place and cancel orders.
  • A private user-data stream (WebSocket) that tells you about fills, order-status changes and balance updates without you having to ask.
  • Occasional REST calls for things that do not need to be fast: order-book snapshots, exchange info (tick sizes, lot steps), fee tiers and balances for reconciliation.
Exchange A matching engine (e.g. hosted in Tokyo) Exchange B matching engine (e.g. hosted in Tokyo) Arbitrage bot (VPS near both) Local book A Local book B Signal: bid B – ask A > fees + buffer Risk + inventory + rate-limit budget 1. market data (WS push) 2. order (REST / WS) 3. fills (private WS) Three channels per exchange: market data in, orders out, fills back in
Each exchange needs three channels: a market-data stream, an order channel and a private fills stream. The bot keeps its own copy of each order book.

Beginners often make two mistakes here. The first is polling prices over REST instead of subscribing to a stream. The second is checking order status by polling instead of listening to the private stream. Both waste your rate-limit budget and add hundreds of milliseconds of delay you never get back.

REST vs WebSocket vs FIX: which interface for which job

Most major exchanges offer a REST API and WebSocket streams. A smaller group of large venues also offers FIX or a dedicated low-latency order-entry API, usually for higher fee tiers or institutional accounts. Each one is good at different things:

InterfaceBest forWeaknessUse it in arbitrage for
RESTRequest/response tasks, snapshots, account dataOne round trip per request; every call costs rate-limit weightOrder-book snapshots, exchange info, balances, and order entry when nothing faster exists
Public WebSocketStreaming prices with no pollingYou must manage sequence numbers, reconnects and resyncs yourselfLive order books and trades: the input to every signal
Private WebSocketPush updates for your own orders and balancesNeeds a listen key or signed login, and expires if you do not keep it aliveFills and order status; the trigger for hedging the second leg
WebSocket order APIPlacing orders over an open connectionNot on every exchange; still subject to rate limitsLower-latency order entry: no new HTTPS request per order
FIXInstitutional order entry and drop copyLimited availability, onboarding and minimum tiersSerious volume on venues that support it

A simple rule: data comes in over streams, decisions are made locally, and orders go out over the fastest channel the exchange offers. REST is for setup and reconciliation, not for anything on the hot path. If you are coming from forex, the trade-offs are a lot like the ones in FIX API vs MT4 bridges: the protocol sets the latency floor.

Keeping a local order book that is actually correct

This is where most home-built bots silently fail. An exchange does not send you the full order book on every update. It sends changes: “price level 64,210.5 on the ask side is now 0.82 BTC”. You keep the full book yourself. If you miss a single change, your book drifts away from reality. Your bot then “sees” a spread that does not exist and fires orders at prices that were never there.

The standard pattern, documented in different forms by most large exchanges, looks like this:

  1. Subscribe to the diff stream first and buffer the incoming messages.
  2. Fetch a REST snapshot of the order book. It carries a sequence or update ID.
  3. Drop buffered updates older than the snapshot, then apply the rest in order.
  4. Check continuity on every message. Each update’s first sequence number must follow on from the last one you applied.
  5. On any gap, throw the book away and resync from step 1. Never “patch” a book with a known gap.
Snapshot + sequenced diffs = a book you can trust REST snapshot lastUpdateId = 1000 diff 990-999 drop (old) 1001-1004 apply 1005-1009 apply 1013-1016 GAP! (1010-1012) Discard book resync from step 1 never trade on a book with a known gap Also stop trading when: no message for X seconds (silent stream), crossed book (bid >= ask), or a checksum mismatch on exchanges that publish one. A stale book is more dangerous than no book.
The local book is only valid while the sequence numbers run with no gaps. Any gap, silence or crossed book means you stop and resync.

Two more sanity checks are worth adding. First, a staleness timer: if a liquid pair has sent nothing for, say, two seconds, treat the book as unreliable, because the stream may be half-dead without having closed. Second, a crossed-book check: a best bid at or above the best ask on one venue almost always means your book is broken, not that you found free money. Some exchanges also publish a checksum of the top levels. If yours does, compare against it.

Rate limits: the budget behind every order

Every exchange limits how hard you can hit its API. The details differ, but most combine several layers:

  • Request weight per minute, usually counted per IP. Heavy endpoints, such as a deep order-book snapshot, cost more weight than light ones.
  • Order-count limits per second and per day, usually counted per account rather than per IP.
  • WebSocket limits: messages per second you may send, connections per IP, and streams per connection.

Going over the limit is not just an error message. Repeated violations can bring escalating temporary IP bans, often minutes at first and longer for repeat offenders. That can take your bot offline in the middle of an open position. So treat the limits as a budget you plan ahead, not a wall you discover by hitting it.

Illustrative weight budget per minute (limit = 100%) 100% limit Polling bot ~127% – IP ban risk Streaming bot ~30% – headroom for bursts book/price requests orders + cancels status polling
Illustrative numbers. Moving prices and order status from polling to streams frees most of the budget for the requests that actually make money: orders and cancels.

Practical rules that keep you inside the budget:

  • Read the limit headers. Many exchanges return your used weight in every response header. Track it, and slow down before you hit the ceiling instead of after.
  • Keep a reserve for cancels. The worst moment to be rate-limited is when you need to cancel a stale order or hedge a filled leg. Hold back at least 20-30% of the budget for that.
  • Use the private stream for status. Never poll “is my order filled?” in a loop.
  • Do not get around limits with IP rotation or extra accounts. It usually breaks the exchange’s terms of use and can get every account involved banned. Asking the exchange for higher limits or a better tier is the legitimate path.

Authentication, clock sync and API key security

Private endpoints are usually signed with HMAC (some exchanges also support Ed25519 or RSA keys). The signature covers a timestamp, and the exchange rejects requests whose timestamp falls outside a short window, often a few seconds. That makes clock synchronisation part of your trading infrastructure: run NTP or chrony on your server and watch the offset. A drifting clock produces a burst of “timestamp outside recvWindow” rejections, exactly when the market is busy and your server is under load.

API keys are the keys to your capital, so lock them down:

  • Trading only, withdrawals off. An arbitrage bot never needs withdrawal permission on its trading keys. Move funds between exchanges manually or with a separate, tightly controlled process.
  • IP allowlisting. Bind every key to your server’s static IP. A leaked key that only works from your VPS is far less dangerous.
  • One key per bot, per exchange, ideally per sub-account. If something goes wrong, you can revoke one key without stopping everything.
  • Secrets out of code and logs. Use environment variables or a secrets manager, and make sure your error logs never print the full key or signature.
  • Rotate on a schedule and right away after any staff change or suspected leak.

Latency: where the milliseconds actually go

For two exchanges, total reaction time is roughly: market-data delivery from exchange A + your processing + order travel to exchange B + matching. On a home internet connection, a cross-continent round trip can easily be 150-250 ms. On a VPS in the same cloud region as the exchange’s matching engine, the network part can drop to a few milliseconds.

That is why server location matters more than code tricks. Many large crypto exchanges run their matching engines in major cloud regions (Tokyo is a common one), and some publish their hosting region. Others can be found with ping tests from candidate data centers. Pick a location that is close to both venues of your main pair. If they sit on different continents, you will pay the gap on one leg either way, and your strategy should allow for it. Our low-latency VPS setup guide covers measuring latency and choosing a data center in detail. The same method works for crypto venues.

Inside your own process, the main gains come from parsing messages without heavy allocations, updating only the price levels that changed, and keeping order-signing keys and connections warm. A trick like TCP_NODELAY is worth having. A correct book and a short network path are worth far more.

Staying connected 24/7

Crypto never closes, but connections do. Plan for these normal events, not as rare exceptions:

  • Scheduled disconnects. Some exchanges close every WebSocket connection after a fixed lifetime, commonly 24 hours. Open a fresh connection before the old one expires and switch over smoothly.
  • Heartbeats. Answer ping frames and send your own pings where the exchange expects them. Private-stream listen keys often need a keep-alive call every so often.
  • Maintenance windows and API upgrades. Subscribe to each exchange’s API announcements. Endpoints get deprecated, weights change and new versions replace old ones.
  • Partial outages. An exchange can keep streaming prices while order entry fails. If an order times out, do not assume it was rejected. Check through the private stream or a status query before you retry, or you may end up with a double position.

The safest design is a kill-switch state machine. Any lost stream, stale book or out-of-sync clock moves the bot into “no new positions”. It flattens or hedges whatever is open, then rebuilds cleanly.

Normalising several exchanges into one view

Every exchange describes the same market differently. One writes BTCUSDT, another BTC-USDT, a third XBT/USDT. Tick sizes, minimum notional values, lot steps and fee schedules also differ. Before your bot can compare prices across exchanges, it needs a normalisation layer that:

  • maps each exchange’s symbols to one internal instrument ID;
  • rounds prices to each venue’s tick size and quantities to its lot step, in the direction that keeps you conservative;
  • checks minimum order sizes, so the second leg of an arbitrage never gets rejected for being too small;
  • applies your actual maker/taker fees per venue. The spread that matters is the one after fees, as explained in our breakdown of the main types of crypto arbitrage.

Load this reference data from each exchange’s info endpoint at startup and refresh it every few hours. Listings, tick sizes and limits change more often than you would think.

Step-by-step: connecting a new exchange to your arbitrage setup

  1. Create a dedicated sub-account and API key with trading permission only, withdrawals disabled and your server IP allowlisted.
  2. Measure latency from your candidate VPS to the exchange’s REST and WebSocket endpoints, and place the server close to the matching engine.
  3. Sync the clock (NTP/chrony) and confirm the offset stays well inside the exchange’s signature window.
  4. Load exchange info: symbols, tick sizes, lot steps, minimum notional and your fee tier. Map them into your normalisation layer.
  5. Build the local order book with the snapshot + diff method, with gap detection, a staleness timer and crossed-book checks.
  6. Connect the private user-data stream for fills and balances, with keep-alive and automatic reconnect.
  7. Set your rate-limit budget, with a reserved share for cancels and hedges, and track the weight headers.
  8. Test with minimum size, compare your local book against the exchange UI, and only then raise position size.

If you would rather not build and maintain all of this yourself, a ready-made platform already handles the exchange sessions, books and order routing. The guide to adding a cryptocurrency exchange session shows how that looks in HFT Arbitrage Platform, where you enter the API key and the platform takes care of the rest.

Frequently asked questions

Do I need WebSockets for crypto arbitrage, or is REST enough?

For any arbitrage that depends on speed, you need WebSockets for market data. Polling prices over REST is slower, burns your rate-limit budget and misses changes between polls. REST is still useful for snapshots, account data and, on some exchanges, order entry.

What API permissions should an arbitrage bot have?

Read and trade only. Turn withdrawals off on every key the bot uses, bind the key to your server’s IP address, and use a separate key, ideally a separate sub-account, for each bot and exchange.

Why does my bot see arbitrage opportunities that are not real?

Usually because the local order book is out of sync: a missed update, a stream that went quiet, or a snapshot applied in the wrong order. Add sequence-gap detection, a staleness timer and a crossed-book check, and resync whenever one of them trips. Also confirm the spread still holds after your real fees.

What happens if I exceed an exchange’s API rate limit?

First you get rejected requests, typically with an HTTP 429 or a similar error code. If you keep exceeding the limit, many exchanges escalate to temporary IP bans. That is dangerous when you have an open leg to hedge, so keep a reserve of budget for cancels and hedges.

Where should my server be for crypto exchange arbitrage?

As close as possible to the matching engines of the exchanges you trade, usually the same cloud region. Measure ping from candidate locations rather than guessing. When the two venues are far apart, place the server near the venue where speed matters most for your strategy.

Is it allowed to use several API keys or IPs to get more requests?

Exchanges set rate limits on purpose, and using extra IPs or accounts to get around them usually breaks their terms of use and can lead to account bans. If you need more throughput, ask the exchange about higher limits, VIP tiers or institutional APIs.

About The Author

Comments
0 Comments
Comments will be displayed after approval by the administrator