Skip to main content
Didit Raises $7.5M to Build the Infrastructure for Identity and Fraud
Didit
Back to blog
Blog · March 6, 2026

Mastering Client-Side Rate Limiting for Didit API Integrations

Effectively integrating with APIs requires robust rate limiting to prevent service disruptions. This guide explores strategies for implementing client-side rate limiting in JavaScript/TypeScript, focusing on Didit's API, and.

By DiditUpdated
client-side-rate-limiting-didit-api-javascript-typescript.png

Proactive Throttling is KeyImplement client-side throttling when X-RateLimit-Remaining drops below 15% to avoid 429 errors and ensure continuous service availability.

Exponential Backoff for 429sAlways use an exponential backoff strategy (e.g., 5s, 10s, 20s) when retrying requests after receiving a 429 response, preventing further rate limit breaches.

Leverage Didit's HeadersThe X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers provided by Didit's API are crucial for dynamic and intelligent client-side rate limiting.

Didit Simplifies IntegrationDidit's SDKs and developer-first approach streamline the implementation of best practices for API integration, including built-in mechanisms and guidance for handling rate limits effectively.

Understanding API Rate Limits and Their Importance

API rate limits are a fundamental aspect of modern web services, designed to protect infrastructure from abuse, ensure fair usage, and maintain stability for all users. For developers integrating with critical services like identity verification platforms, understanding and respecting these limits is paramount. When integrating with Didit's API, you'll encounter specific rate limits designed to ensure reliable and high-performance identity verification operations.

Didit enforces multiple layers of rate limiting, including global limits for GET (300 requests per minute per application) and Write/Delete endpoints (300 requests per minute per application), as well as more restrictive endpoint-specific limits for high-impact operations. For example, POST /v2/session/ (for creating verification workflows) has a limit of 600 rpm, while `GET /v2/session//decision/ (for retrieving session decisions) and GET /session//generate-pdf/` are capped at 100 rpm due to their computational intensity.

Exceeding these limits results in a 429 HTTP status code (Too Many Requests). While this is a server-side protection, effective client-side rate limiting is crucial to prevent your application from hitting these ceilings, ensuring a smooth user experience and uninterrupted service. Failing to implement proper client-side handling can lead to degraded performance, failed verifications, and a poor impression for your users.

Strategies for Client-Side Rate Limiting in JavaScript/TypeScript

Implementing client-side rate limiting involves anticipating and responding to API limits before they are enforced by the server. This requires a combination of proactive throttling and reactive error handling. Here are key strategies:

1. Proactive Throttling with Rate Limit Headers

Didit's API includes specific headers in 429 responses that are invaluable for client-side rate limiting: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (in epoch seconds). You should parse these headers and use them to inform your client's request behavior.

A robust client will:

  • Monitor X-RateLimit-Remaining: Actively track the remaining requests. When this value drops below a certain threshold (e.g., 15% of X-RateLimit-Limit), your client should start queuing requests or slowing down its transmission rate.
  • Utilize X-RateLimit-Reset: This header tells you when the current rate limit window resets. You can use this timestamp to schedule when your client can safely resume full-speed requests.

interface RateLimitHeaders {
  limit: number;
  remaining: number;
  reset: number; // epoch seconds
}

async function makeDiditRequest(url: string, options: RequestInit): Promise<Response> {
  // In a real app, you'd manage these globally or per-endpoint
  let currentRateLimit: RateLimitHeaders | null = null;

  // Implement a local queue or delay mechanism based on currentRateLimit
  // For simplicity, this example focuses on response handling.

  const response = await fetch(url, options);

  const limit = response.headers.get('X-RateLimit-Limit');
  const remaining = response.headers.get('X-RateLimit-Remaining');
  const reset = response.headers.get('X-RateLimit-Reset');

  if (limit && remaining && reset) {
    currentRateLimit = {
      limit: parseInt(limit, 10),
      remaining: parseInt(remaining, 10),
      reset: parseInt(reset, 10),
    };
    console.log(`Rate Limit: ${currentRateLimit.remaining}/${currentRateLimit.limit} requests remaining. Resets at ${new Date(currentRateLimit.reset * 1000).toLocaleTimeString()}.`);
  }

  return response;
}

2. Implementing Exponential Backoff for 429 Responses

When your client does receive a 429 response, the correct approach is not to immediately retry. Instead, implement an exponential backoff strategy. This involves waiting for increasingly longer periods between retries, reducing the load on the server and increasing the chance of success on subsequent attempts. Didit's 429 responses also include a Retry-After header, which provides a specific duration (in seconds) to wait before retrying. Always prioritize this header if present.


async function makeDiditRequestWithRetry(url: string, options: RequestInit, retries = 0): Promise<Response> {
  try {
    const response = await makeDiditRequest(url, options);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After');
      const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : Math.pow(2, retries) * 1000; // Exponential backoff: 1s, 2s, 4s...
      console.warn(`Rate limit hit. Retrying in ${delay / 1000} seconds...`);
      await new Promise(resolve => setTimeout(resolve, delay));
      return makeDiditRequestWithRetry(url, options, retries + 1);
    }

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    return response;
  } catch (error) {
    console.error('Request failed:', error);
    throw error;
  }
}

// Example usage for a Didit session decision retrieval
// This endpoint is limited to 100 rpm.
// makeDiditRequestWithRetry(`/v2/session/${sessionId}/decision/`, { method: 'GET' });

3. Utilizing Didit's SDKs for Streamlined Integration

Didit offers robust SDKs for various environments, including a JavaScript SDK for web applications. These SDKs often abstract away much of the complexity of API interaction, including handling common error patterns and providing event-driven callbacks for verification flows. While explicit rate limiting logic might still be necessary for high-volume, custom API calls, using the SDKs for user-facing verification flows (like ID Verification, Passive & Active Liveness, or Age Estimation) significantly simplifies integration.

The SDKs are designed for user-facing workflows, where your backend initiates a session (POST /v2/session/) and your frontend renders the verification UI. The SDK handles the interaction with Didit's services, reducing the direct burden of managing individual API call rate limits from the client side during the verification process itself. When integrating with the JavaScript SDK, you initialize it with a session token from your backend, and it manages the flow, providing onSuccess, onError, and onCancel callbacks.

How Didit Helps

Didit is engineered to be a developer-first, AI-native identity platform that provides flexible integration options while maintaining robust performance. Our approach to API design and SDKs inherently aids in managing rate limits and ensuring smooth operations:

  • Clear Rate Limit Documentation: Didit provides transparent and detailed documentation on all API rate limits, allowing developers to plan their integrations effectively.
  • Informative Headers: The inclusion of X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After headers empowers developers to build intelligent, self-regulating client applications.
  • Modular Architecture: Didit's modular design means you only integrate the identity primitives you need, such as ID Verification for document checks, Passive & Active Liveness for fraud detection, or Age Estimation for age verification. This targeted approach can help optimize your API call patterns.
  • SDKs for Simplified Workflows: Our web and mobile SDKs streamline the integration of complex user-facing verification processes. By handling the intricacies of the verification flow, including many underlying API calls, the SDKs abstract away direct rate limit concerns for those specific interactions, allowing you to focus on your application logic.
  • Free Core KYC: Didit offers Free Core KYC, enabling businesses to get started with essential identity verification services without upfront costs, making it easier to test and optimize your integration strategies, including rate limit handling.

Ready to Get Started?

Ready to see Didit in action? Get a free demo today.

Start verifying identities for free with Didit's free tier.

Infrastructure for identity and fraud.

One API for KYC, KYB, Transaction Monitoring, and Wallet Screening. Integrate in 5 minutes.

Ask an AI to summarise this page
Mastering Client-Side Rate Limiting for Didit API | Didit