Documentation

Member Pulling

AdminUpdated Sep 20, 2026

Member Pulling

Pull verified members to a new server with automatic role assignment. Understand how OAuth2 tokens enable pulling, rate limits, cooldowns, filters, role mapping, and the pull worker.

Overview

Member pulling is the process of adding members who verified through one of your servers to a different server. When members verify via Restore Hub, they grant the guilds.join OAuth2 scope, which authorizes Restore Hub to add them to any server where you have a bot. Pulling uses these stored tokens to add members to your target server and assign a role.

This is a one-time consent model: the member authorizes during verification and can revoke access at any time through Discord's Authorized Apps settings. Restore Hub does not re-prompt for consent.

How OAuth2 Tokens Enable Pulling

When a member completes verification, Restore Hub stores their OAuth2 access token and refresh token (both encrypted with AES-256). The access token is valid for 7 days. The refresh token is valid for 30 days.

When a pull job runs, Restore Hub uses the guilds.join scope with the member's access token to add them to the target server via Discord's PUT /guilds/{guild_id}/members/{user_id} endpoint. This endpoint also accepts a roles array, enabling immediate role assignment upon joining.

If the access token has expired, Restore Hub automatically refreshes it using the refresh token before attempting the pull. If the refresh token has also expired (the member has not reverified in 30 days) or the member has revoked access, the member is marked as "not pullable".

Token Refresh Mechanism

Restore Hub proactively refreshes tokens 5 minutes before they expire (TOKEN_REFRESH_BUFFER_MS = 5 minutes). During a pull job, if a token is within 5 minutes of expiry, Restore Hub refreshes it before using it.

When a refresh succeeds, the new access token, refresh token, and expiry timestamp are saved (encrypted) to the database. When a refresh fails (user revoked access, token expired beyond renewal, Discord API error), the member's isPullable flag is set to false.

Tip: Members can regain "pullable" status by reverifying. The new OAuth2 tokens replace the old ones.

What 'Pullable' Means

A member is marked as "pullable" (isPullable = true) when they have valid, non-expired OAuth2 tokens. A member becomes "not pullable" when:

  • Their access token expired AND the refresh token also expired (no reverification in ~30 days)

  • They revoked Restore Hub's access in Discord Settings → Authorized Apps

  • A token refresh attempt failed due to a Discord API error

  • They were manually marked as not pullable by the server owner

Starting a Pull

You can start a pull from three places: the dashboard, a Discord slash command, or the REST API.

  1. From the dashboard — Navigate to your source server → Members → Pull Members. Select the target server, optionally set a role, limit, and filters, then click "Start Pull".

  2. From Discord (Premium+) — Use the /pull command in your source server. Specify the target server ID and optional role.

  3. Via the API — POST /api/v1/servers/:id/pull with a JSON body specifying targetGuildId, roleId, limit, preserveRoles, roleMapping, and filter.

POST /api/v1/servers/:id/pull
{
  "targetGuildId": "123456789012345678",
  "roleId": "987654321098765432",
  "limit": 500,
  "preserveRoles": false,
  "roleMapping": {
    "111111111111111111": "222222222222222222"
  },
  "filter": {
    "roleIds": ["333333333333333333"],
    "memberIds": ["444444444444444444"]
  }
}

Rate Limiting

Discord's API has strict rate limits on the PUT /guilds/{guild_id}/members/{user_id} endpoint. Restore Hub processes members at approximately 50 per minute (PULL_RATE_LIMIT = 50) to stay safely within Discord's limits.

This means a pull of 1,000 members takes approximately 20 minutes. A pull of 5,000 members takes approximately 100 minutes. The pull worker manages timing automatically — you do not need to worry about hitting Discord's rate limits.

Warning: Exceeding Discord's rate limits can result in your bot being temporarily or permanently banned. Restore Hub's built-in rate limiting prevents this, but be aware that large pulls take time.

Cooldowns per Plan

To prevent abuse, each plan has a cooldown period between pulls for the same source server:

| Plan | Cooldown Between Pulls |
|---|---|
| Free | 6 hours |
| Premium | 1 hour |
| Business | 15 minutes |
| Enterprise | No cooldown |

Tip: The cooldown is per source server, not global. If you have two source servers, you can pull from both simultaneously even on the Free plan.

Role Mapping

When pulling members, you can optionally map roles from the source server to roles in the target server. This is useful when you want to preserve member roles across servers.

The roleMapping field is a JSON object where keys are role IDs from the source server and values are role IDs in the target server. When a member is pulled, Restore Hub looks up their roles in the source server and assigns the corresponding mapped roles in the target.

If preserveRoles is set to true without a roleMapping, Restore Hub attempts to match roles by name. Roles with identical names in both servers are automatically mapped.

Pull Filters

You can narrow down which members are included in a pull using filters:

| Filter | Description |
|---|---|
| roleIds | Only pull members who have at least one of the specified roles in the source server |
| memberIds | Only pull specific members by their Discord user IDs |
| limit | Maximum number of members to pull (e.g., 500). If not set, all pullable members are included |

Pull Job Statuses

Each pull job goes through a series of statuses. You can monitor progress in the dashboard or via GET /api/v1/pulls/:id.

| Status | Meaning |
|---|---|
| PENDING | Job created, waiting to be queued |
| QUEUED | Job added to the worker queue, waiting for a worker to pick it up |
| RUNNING | Worker is actively processing members (pulledCount increments in real time) |
| COMPLETED | All members processed (some may have failed or been skipped) |
| FAILED | The entire job failed due to a critical error (e.g., bot removed from target server) |
| CANCELLED | The job was cancelled by the user before completion |

Pull Job Counters

During and after a pull, the following counters track progress:

  • totalMembers — The total number of members that will be processed (based on filters and limit).

  • pulledCount — Number of members successfully added to the target server.

  • failedCount — Number of members that could not be pulled (token expired, user revoked access, Discord API error).

  • skippedCount — Number of members skipped (already in the target server, banned from target server, etc.).

  • progress — Calculated as (pulledCount + failedCount + skippedCount) / totalMembers * 100.

The Pull Worker

Pull jobs are processed by a background worker (BullMQ job queue). The worker:

  • Dequeues the next pending pull job.

  • Loads all pullable members from the source server (applying filters).

  • For each member: checks if their token is valid, refreshes if needed, calls Discord's API to add them to the target server with the specified role(s), and updates counters.

  • Respects the 50/minute rate limit by spacing out API calls.

  • Handles errors gracefully — if a single member fails, the job continues with the next member.

  • Updates the job status to COMPLETED or FAILED when done.

  • Logs all errors to the errorLog JSON field for debugging.

What Happens When Tokens Expire

If a member's access token has expired but their refresh token is still valid, the worker automatically refreshes the token and retries. If the refresh token is also expired or revoked, the member is marked as not pullable (isPullable = false) and counted in failedCount.

To minimize token expiry issues, encourage members to reverify periodically, or set up alerts to monitor your pullable member percentage.

Multi-Server Pull (Enterprise)

On the Enterprise plan, you can pull members from multiple source servers into a single target server in one operation. This is useful for consolidating communities. The multi-server pull respects individual rate limits and processes each source server's members sequentially.

Auto-Pull on Alerts (Business+)

On Business and above, you can configure alerts (nuke, raid, deletion) to automatically trigger a pull to a backup server. If your server is compromised, Restore Hub can automatically start pulling your verified members to a safe server without manual intervention.

Was this page helpful?