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.
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:
| Interface | Best for | Weakness | Use it in arbitrage for |
|---|---|---|---|
| REST | Request/response tasks, snapshots, account data | One round trip per request; every call costs rate-limit weight | Order-book snapshots, exchange info, balances, and order entry when nothing faster exists |
| Public WebSocket | Streaming prices with no polling | You must manage sequence numbers, reconnects and resyncs yourself | Live order books and trades: the input to every signal |
| Private WebSocket | Push updates for your own orders and balances | Needs a listen key or signed login, and expires if you do not keep it alive | Fills and order status; the trigger for hedging the second leg |
| WebSocket order API | Placing orders over an open connection | Not on every exchange; still subject to rate limits | Lower-latency order entry: no new HTTPS request per order |
| FIX | Institutional order entry and drop copy | Limited availability, onboarding and minimum tiers | Serious 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:
- Subscribe to the diff stream first and buffer the incoming messages.
- Fetch a REST snapshot of the order book. It carries a sequence or update ID.
- Drop buffered updates older than the snapshot, then apply the rest in order.
- Check continuity on every message. Each update’s first sequence number must follow on from the last one you applied.
- On any gap, throw the book away and resync from step 1. Never “patch” a book with a known gap.
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.
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
- Create a dedicated sub-account and API key with trading permission only, withdrawals disabled and your server IP allowlisted.
- Measure latency from your candidate VPS to the exchange’s REST and WebSocket endpoints, and place the server close to the matching engine.
- Sync the clock (NTP/chrony) and confirm the offset stays well inside the exchange’s signature window.
- Load exchange info: symbols, tick sizes, lot steps, minimum notional and your fee tier. Map them into your normalisation layer.
- Build the local order book with the snapshot + diff method, with gap detection, a staleness timer and crossed-book checks.
- Connect the private user-data stream for fills and balances, with keep-alive and automatic reconnect.
- Set your rate-limit budget, with a reserved share for cancels and hedges, and track the weight headers.
- 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.