> Why big RestoreCord pulls run gradually, what verification error 10003 means, how pull delays work and how to handle 429 RATE_LIMITED responses from the API.

Source: https://restorecord.tech/rate-limits

# Discord rate limits and RestoreCord, explained

RestoreCord talks to Discord on behalf of your bot, so Discord's rate limits shape verification, pulls and the API. Knowing where they bite saves a lot of confusion.

[Get started free](https://restorecord.com/register)[View pricing](https://restorecord.com/pricing)

Short answer

Members who hit error 10003 should wait 60 minutes and try once, since Discord sets that limit. Pulls run one add-member call at a time with no RestoreCord cooldown, paced by your delay setting. The RestoreCord API answers 429 RATE\_LIMITED with a Retry-After header.

## During verification

If Discord rate-limits the member's account or the bot, the verify page shows **Rate limited, please try again later** with error `10003`. RestoreCord can't lift or shorten that limit. The recommended first step is to wait 60 minutes and try once. Limits can range from minutes to more than a day, and repeated clicks or extra tabs only extend them.

## During member pulls

Adding members back uses Discord's add-member endpoint, one member per call. That's why a large pull completes gradually rather than instantly. RestoreCord itself adds **no cooldown** between pulls on any plan, Free included, and routes requests through proxies to reduce rate-limit pressure. The pace is set by:

| Control                 | What it does                                       | Plan           |
| ----------------------- | -------------------------------------------------- | -------------- |
| Fixed delay             | A constant pause between add-member attempts       | Free           |
| Delay range             | A randomised pause between a minimum and a maximum | Premium and up |
| Scheduled migrations    | Start the pull at a time you choose                | Premium and up |
| Realtime migration logs | Watch progress and Discord's responses live        | Every plan     |

For a big community, start conservatively and watch the first batch in the live log before speeding up.

Why not simply go as fast as possible? Discord applies its limits per bot and per route, and a bot that keeps hitting them gets slowed down further. A steady, slightly randomised pace usually finishes sooner than bursts followed by long forced pauses, and it keeps the bot healthy for the verifications that are still coming in while the pull runs.

## Fewer calls, faster pulls

The surest way to finish a pull sooner is to make fewer add-member calls. Members who revoked the app can't be added anyway, and higher plans let you skip members you probably don't want back:

| Filter                | Skips                                             | Plan            |
| --------------------- | ------------------------------------------------- | --------------- |
| Max leave rate        | Members who leave servers too often               | Business and up |
| Left server duration  | Members who left the target server too recently   | Business and up |
| Minimum stay duration | Members who never stayed a minimum number of days | Enterprise      |
| Minimum activity      | Members below an activity threshold               | Enterprise      |

A smaller, better-targeted pull spends less time inside Discord's limits and brings back the members who actually mattered to the community. On Enterprise, several migrations can also be started from a single server.

## On the RestoreCord API

The RestoreCord REST API applies its own limits. When you exceed them, the response is HTTP `429` with the error code `RATE_LIMITED` and a `Retry-After` header in seconds. A small wrapper handles it cleanly:

Honouring Retry-Afterjavascript

```
async function callRestoreCord(url, init, attempt = 0) {
  const res = await fetch(url, init);
  if (res.status !== 429 || attempt >= 3) return res;

  // RATE_LIMITED: honour Retry-After, then back off further on each retry
  const wait = Number(res.headers.get("Retry-After") ?? 1) * 1000 * (attempt + 1);
  await new Promise((resolve) => setTimeout(resolve, wait));
  return callRestoreCord(url, init, attempt + 1);
}
```

Retrying in a tight loop after a 429 only keeps you limited for longer. Always wait at least the Retry-After value.

Two habits keep integrations out of trouble. First, cache what doesn't change often, such as server lists and settings, instead of fetching them before every call. Second, spread scheduled jobs out: a script that refreshes ten servers at the same second on the hour will hit limits that the same work spread over a few minutes never would. API keys can also be limited to an IP or CIDR allowlist, so a leaked key can't be used to burn your limits from elsewhere.

Authentication details for the API are in RestoreCord's [API keys guide](https://restorecord.com/docs/api-keys). Back to the [technical overview](https://restorecord.tech/), or read about [the scopes that make pulls possible](https://restorecord.tech/oauth2-scopes).

## Pace a large pull safely

1. 1  
### Start with a conservative delay  
Use the fixed delay on Free, or a delay range from Premium, for the first batch of a large pull.
2. 2  
### Watch the realtime log  
Follow the migration's live progress and look for Discord rejections before changing anything.
3. 3  
### Retry API calls politely  
On a 429 RATE\_LIMITED response, honour Retry-After and back off instead of hammering the endpoint.
[Pull members guide](https://restorecord.com/docs/guides/pull-members)

## Rate limit questions

### 

### 

### 

## Pulls that respect Discord's limits

No RestoreCord cooldown, live logs and delays you control, on every plan.

[Get started](https://restorecord.com/register)[View pricing](https://restorecord.com/pricing)
