MT5 API rate limits: back off without losing orders
Tickwire's MT5 and MT4 API uses plain token buckets per key and per account. Here are the limits, the headers, and how to back off without placing a second order.
Tickwire’s MT5 and MT4 API limits requests with token buckets: each key, account and address has a bucket that holds a burst and refills every second. When a bucket is empty you get 429 with a Retry-After header, and a refused trade says "sent": false, so waiting and repeating it with the same idempotency key is always safe. This post lists the limits and shows a backoff that never places a second order.
The numbers below come from the rate limits page, which is the place to check if they change.
The buckets
| Bucket | Burst | Refill per second |
|---|---|---|
| Per API key | 100 | 50 |
| Per account | 40 | 20 |
| Per account, trades | 20 | 10 |
| Per address, anonymous | 20 | 5 |
| Per address, failed sign-ins | 20 | 0.5 |
| Per address, MCP | 200 | 50 |
| Per address, agent keys | 200 | 50 |
| Per signal webhook | 30 | 1 |
A request takes tokens from every bucket it touches. A trade on one account uses the key bucket, the account bucket and the trade bucket.
Not every call costs the same
| Call | Weight |
|---|---|
| Most reads | 1 |
| History | 5 |
| A trade | 1 |
| A batch order | 10 |
| Opening a stream | 5 |
On top of the buckets, one key may have 16 requests and 16 trades in flight at once. A key may hold 50 WebSockets. Over those limits the answer is an immediate 429.
What is free
- WebSocket frames, once the stream is open;
- webhook deliveries to you;
- health checks.
That is why streaming beats polling. A bot that polls positions ten times a second spends its whole bucket on reads. A bot that opens one stream gets every change and spends nothing more. See Webhooks vs polling and Stream MT5 prices with WebSocket.
The headers
Every answer says where you stand:
RateLimit-Limit: 100
RateLimit-Remaining: 37
RateLimit-Reset: 2
RateLimit-Policy: 100;w=2;name="key"
The same values come as X-RateLimit-* too. Read RateLimit-Remaining and slow down before you hit zero.
What a 429 looks like
{ "error": "rate_limited", "message": "too many requests; retry after the time in Retry-After",
"sent": false, "outcome": "not_sent",
"metadata": { "recommendedRetryTime": "2026-09-25T11:02:20.000Z", "exceededConfig": "perAccountTrades",
"resourceId": "account:acc_7Qx", "limit": 20, "bucket": "account-trades", "weight": 1 } }
metadata.bucket says which bucket ran out, here the trade bucket of one account. "sent": false is the important part. A refused trade never left Tickwire. Nothing reached the broker. On the /users/current/… routes the error is TooManyRequestsError, with rate_limited in code.
Back off without a second order
The rule is short: wait at least Retry-After, then repeat the same request with the same Idempotency-Key. Never make a new key for a retry.
import random, time, uuid, requests
API = "https://api.tickwire.io"
def send_trade(session, account_id, order, reason, max_wait=30):
key = str(uuid.uuid4()) # one key per decision, reused on every retry
delay = 1.0
while True:
r = session.post(f"{API}/users/current/accounts/{account_id}/trade", json=order,
headers={"Idempotency-Key": key, "X-Actor": "bot", "X-Reason": reason},
timeout=30)
if r.status_code != 429:
return r.json()
wait = max(float(r.headers.get("Retry-After", 1)), delay)
time.sleep(wait + random.uniform(0, wait / 2)) # jitter
delay = min(delay * 2, max_wait)
Set the auth-token header on the session. Why the same key matters: if an earlier attempt did reach the terminal and only the answer was lost, the repeat returns that first answer instead of placing a new order. Our post on retries that never trade twice walks through it.
Other answers to handle
too_many_connections: you hold 50 WebSockets on one key. Close some, or share one stream across symbols.503: the service is busy for a moment. Back off the same way.409 idempotency_in_flight: an earlier request with the same key is still running. Wait forRetry-Afterand repeat with the same key.
Habits that keep you under the limits
- Stream instead of polling.
- Ask for history in pages, not all at once, and cache what you already have.
- Use one batch order for many accounts instead of many single calls.
- Read
RateLimit-Remainingand pace yourself. - Spread background jobs over time, not all at the top of the minute.
Need more? Higher limits are available on request.
Frequently asked questions
What are the MT5 API rate limits on Tickwire?
Each API key has a bucket of 100 that refills at 50 per second. Each account has 40 refilling at 20, and trades on an account have 20 refilling at 10. The full table is on the rate limits page.
Is a trade refused with 429 safe to retry?
Yes. A 429 trade answer says sent false and outcome not_sent: nothing reached the broker. Wait for Retry-After and send it again with the same Idempotency-Key.
Do WebSocket messages count toward the limits?
No. Opening a stream costs 5 tokens. The frames you receive after that are free, and so are webhook deliveries and health checks.
Are the limits the same on MT4?
Yes. MT4 and MT5 accounts share the same API and the same buckets.
How do I get higher limits?
Ask us. Higher limits are available on request. See pricing for plans, and the MT5 API page for the full API.
Trading carries risk, and you can lose money. This post explains software and how it behaves; it is not investment advice.