Chat with us, powered by LiveChat
← Return to MyDisct Solver

Rate Limits

Understanding RPM limits, concurrent thread limits, and how to handle them correctly

Limits Overview

MyDisct Solver API applies three separate protections. A request must pass all relevant checks before it can be accepted.

Layer What It Controls Typical Error
IP limit Too many requests from the same IP address in a short time IP_RATE_LIMIT_EXCEEDED
API key RPM How many requests your API key can send per minute API_KEY_RATE_LIMIT_EXCEEDED
Concurrent threads How many active solving tasks your subscription can run at the same time THREAD_LIMIT_REACHED

IP-Based Rate Limit

A global limit is applied per IP address to protect the service against abuse, DDoS traffic, and brute-force patterns. This check applies to every request, even before user-specific limits are evaluated.

Scope Limit Window Error Code
Per IP address 1,000 requests 1 minute IP_RATE_LIMIT_EXCEEDED

API Key RPM Limit

Each user has a personal RPM (Requests Per Minute) limit tied to the API key. Balance accounts default to 1,000 RPM. Subscription packages can include their own RPM values, and customizable packages can raise that limit further.

Account Type Default RPM Notes
Balance account 1,000 Can be adjusted per user
Subscription package Defined by package Automatically applied when the subscription becomes active

Concurrent Thread Limit

Threads are different from RPM. Threads control how many active captcha tasks can be processing at the same time on your account. If your package allows 2 threads, a third request can be rejected even if your RPM usage is still low.

When Threads Outside Billing is enabled on your subscription, requests above the package thread count are not blocked. Instead, they continue with normal balance pricing and do not return THREAD_LIMIT_REACHED.

Subscription Setting When Threads Are Full
Disabled New requests return THREAD_LIMIT_REACHED
Enabled New requests continue with balance pricing

Rate Limit Headers

Authenticated responses include RPM information in the headers. These headers describe request-per-minute usage, not concurrent thread usage.

Response Headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 985
X-RateLimit-Reset: 45
Header Description
X-RateLimit-Limit Your maximum requests allowed per minute
X-RateLimit-Remaining Requests remaining in the current 1-minute window
X-RateLimit-Reset Seconds until the RPM window resets

429 Error Responses

All of the following situations may return HTTP 429 Too Many Requests, but the response body tells you which limit you hit.

IP Rate Limit Exceeded

JSON - 429 Too Many Requests
{
  "success": false,
  "errorId": "ERROR_RATE_LIMIT",
  "errorCode": "IP_RATE_LIMIT_EXCEEDED",
  "message": "Too many requests from this IP address. Please wait before retrying.",
  "service": "MyDisct Solver",
  "retryAfter": 60
}

API Key RPM Exceeded

JSON - 429 Too Many Requests
{
  "success": false,
  "errorId": "ERROR_RATE_LIMIT",
  "errorCode": "API_KEY_RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded. Your plan allows 1000 requests per minute.",
  "service": "MyDisct Solver",
  "rateLimit": {
    "limit": 1000,
    "remaining": 0,
    "resetInSeconds": 42
  }
}

Concurrent Thread Limit Reached

JSON - 429 Too Many Requests
{
  "success": false,
  "service": "MyDisct Solver",
  "error": {
    "code": "THREAD_LIMIT_REACHED",
    "message": "Your concurrent thread limit has been reached. Wait for an active task to finish before creating a new one."
  },
  "reason": "thread_limit_reached",
  "thread_limit": 2,
  "active_requests": 2
}

Checking Your RPM Limit

You can check your currently active RPM value with the /accountInfo endpoint.

JSON - GET /accountInfo Response
{
  "success": true,
  "account": {
    "email": "[email protected]",
    "username": "myuser",
    "balance": 25.50,
    "currency": "USD",
    "status": "active",
    "rpm_limit": 1000,
    "created_at": "2025-01-15T12:00:00.000Z"
  }
}

Handling Limits

Handle each limit based on its cause. RPM errors should use retry logic. Thread errors should wait for active tasks to finish or rely on Threads Outside Billing.

JavaScript Example
async function solveWithRetry(captchaData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch('https://solver-api.mydisct.com/createTask', {
      method: 'POST',
      headers: {
        apikey: 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        auth: { token: 'YOUR_API_KEY' },
        context: { source: 'api', version: '1.0.0' },
        captcha: captchaData
      })
    });

    const data = await response.json();

    if (response.status !== 429) {
      return data;
    }

    if (data.errorCode === 'API_KEY_RATE_LIMIT_EXCEEDED') {
      const resetSeconds = response.headers.get('X-RateLimit-Reset') || Math.pow(2, i) * 2;
      await new Promise(resolve => setTimeout(resolve, resetSeconds * 1000));
      continue;
    }

    if (data.error && data.error.code === 'THREAD_LIMIT_REACHED') {
      throw new Error('Your active thread quota is full. Wait for a running task to finish.');
    }

    throw new Error(data.message || 'Rate limit exceeded');
  }

  throw new Error('Max retries reached');
}

Best Practices

Recommendations
  • Monitor X-RateLimit-Remaining to stay below your RPM ceiling
  • Use X-RateLimit-Reset instead of guessing retry timing
  • Treat THREAD_LIMIT_REACHED separately from RPM errors in your client code
  • Use thread_limit and active_requests to debug concurrency issues
  • Enable Threads Outside Billing if you want overflow traffic to continue with balance pricing
  • Upgrade to packages with higher RPM or more threads if you hit limits consistently
  • Avoid sending large request bursts when a steady flow is possible