AsyTech
apis integrations

Resilient API Integration Patterns: Handling Rate Limits, Retries, and Webhooks

How to build mission-critical API connectors that never drop transactions during third-party downtime, rate limit spikes, or transient network failures.

AsyTech Systems Engineering • Backend Architecture Lead
Oct 19, 2026
9 min read

Why Naive API Integrations Fail

Connecting two software systems via an API appears deceptively simple in staging: you send an HTTP POST request, receive a 200 OK status, and celebrate.

In production, however, distributed systems fail in unpredictable ways: - Upstream third-party services experience degraded performance and 504 Gateway Timeouts. - High-volume transaction bursts trigger HTTP 429 Too Many Requests rate limits. - Inbound webhooks arrive out-of-order or are delivered multiple times due to network retries.

Without defensive architectural patterns, your systems drop valuable customer transactions, duplicate records, or crash under unexpected load.


1. The Token Bucket: Defeating Rate Limits

When syncing data with platforms like Salesforce, Shopify, or QuickBooks, their APIs enforce strict quotas (e.g., 40 requests per second or 1,000 requests per rolling hour).

A production connector should never fire raw HTTP requests directly from incoming user interactions. Instead, implement a **Token Bucket Rate Limiter**:

// Conceptual Token Bucket Rate Limiter
class RateLimiter {
  private tokens: number;
  private lastRefill: number;

constructor(private capacity: number, private refillRatePerSec: number) { this.tokens = capacity; this.lastRefill = Date.now(); }

async acquire(): Promise<void> { this.refill(); if (this.tokens > 0) { this.tokens--; return; } const waitMs = (1 / this.refillRatePerSec) * 1000; await new Promise((resolve) => setTimeout(resolve, waitMs)); return this.acquire(); }

private refill(): void { const now = Date.now(); const elapsed = (now - this.lastRefill) / 1000; this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.refillRatePerSec); this.lastRefill = now; } } ```


2. Exponential Backoff with Full Jitter

When an external endpoint returns a 5xx server error or network connection reset, immediately retrying can trigger a "thundering herd" problem that exacerbates the outage.

The industry-standard approach is **Exponential Backoff with Full Jitter**, which introduces randomized variance to prevent synchronized retry spikes:

$$\text{Sleep Time} = \text{random}(0, \min(\text{MaxSleep}, \text{Base} \times 2^{\text{attempt}}))$$

This ensures that hundreds of queued requests disperse naturally across a wider time window, giving the recovering server breathing room to restore services.


3. Idempotent Webhook Processing

Third-party webhook senders (such as Stripe or Shopify) guarantee *at-least-once delivery*. If their server does not receive an HTTP 200 acknowledgment within a tight 3-second window, they will retry sending the exact same event.

If your webhook handler processes payment fulfillment or creates invoice records without **Idempotency Keys**, your system will charge customers twice or send duplicate inventory orders.

The Defensive Webhook Pipeline: 1. **Validate Cryptographic Signatures:** Verify the HMAC SHA-256 header using your shared secret before touching payload data. 2. **Check the Event Ledger:** Query your PostgreSQL database for the unique `event_id`. 3. **Short-Circuit on Duplicates:** If the `event_id` already exists with status `processed`, return an immediate HTTP 200 OK without re-executing business logic. 4. **Execute in an ACID Transaction:** Update your local tables and mark the event processed in a single atomic database transaction.


4. Dead Letter Queues (DLQ)

What happens when an API payload contains invalid data that fails schema validation regardless of how many times it is retried?

Indefinite retries block the processing queue. Resilient integrations route permanently unprocessable events to a **Dead Letter Queue (DLQ)** along with: - The exact raw incoming payload. - The stack trace and HTTP error code. - A manual retry trigger in your administrative dashboard.

This architectural hygiene keeps your operational pipelines moving while ensuring zero data loss during anomalies.

Filed Under:#API Integration#Webhooks#TypeScript#System Architecture
Related Engineering Service

Explore how AsyTech builds solutions in this domain.

View Service Details