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.

A bucket of tokens draining and refilling beside a stream of requests, with a pause before the next one.

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

BucketBurstRefill per second
Per API key10050
Per account4020
Per account, trades2010
Per address, anonymous205
Per address, failed sign-ins200.5
Per address, MCP20050
Per address, agent keys20050
Per signal webhook301

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

CallWeight
Most reads1
History5
A trade1
A batch order10
Opening a stream5

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 for Retry-After and repeat with the same key.

Habits that keep you under the limits

  1. Stream instead of polling.
  2. Ask for history in pages, not all at once, and cache what you already have.
  3. Use one batch order for many accounts instead of many single calls.
  4. Read RateLimit-Remaining and pace yourself.
  5. 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.

Try it on your own account

7-day free trial. See pricing or read the quickstart.