FlowAlp

Merchant API rate limits

July 30, 2026

FlowAlp Pay Merchant API rate limits: 600 requests per 5 minutes, 405/403 signals under load, and a retry strategy with backoff.

The Merchant API applies a request quota so that all merchants get predictable performance. Design your integration to stay well below the limit and to slow down gracefully when it is reached.

The limit

PropertyValue
Quota600 requests per 5 minutes
ScopeAll Merchant API requests
EnforcementWeb application firewall at the platform edge (AWS WAF)

The quota covers bursts as well as sustained traffic: 600 requests in five minutes corresponds to an average of two requests per second.

What happens when you exceed it

SignalMeaningRecommended action
405 Method Not AllowedTypical first signal from the platform edgePause, then retry with backoff
403 ForbiddenFollow-up block while the limit stays exceededStop the burst; increase delays substantially

Both codes also occur for unrelated reasons — a wrong HTTP verb or missing permissions. Treat them as rate-limit signals only when they correlate with high request volume; the full status semantics are in Merchant API errors.

Backoff strategy

Retry with exponential backoff and jitter:

ParameterSuggested value
Initial delay500 ms
Multiplier2.0 per attempt
Jitterrandom 0–300 ms added per attempt
Maximum delay30 s
Maximum attempts5
Node.js backoff wrapperJavaScript
async function withBackoff(fn, { maxAttempts = 5, baseMs = 500, maxDelayMs = 30000 } = {}) {
  for (let attempt = 1; ; attempt++) {
    try {
      return await fn();
    } catch (err) {
      const retriable = [403, 405, 429].includes(err.status) || err.status >= 500;
      if (!retriable || attempt >= maxAttempts) {
        throw err;
      }
      const delay =
        Math.min(baseMs * 2 ** (attempt - 1), maxDelayMs) + Math.random() * 300;
      await new Promise((resolve) => setTimeout(resolve, delay));
    }
  }
}
PHP backoff loopPHP
<?php
$delayMs = 500;

for ($attempt = 1; $attempt <= 5; $attempt++) {
    [$status, $body] = sendFlowAlpRequest(); // your HTTP call

    if ($status < 400) {
        break;
    }
    if (!in_array($status, [403, 405, 429], true) && $status < 500) {
        throw new RuntimeException('Non-retriable error: HTTP ' . $status);
    }

    usleep(($delayMs + random_int(0, 300)) * 1000);
    $delayMs = min($delayMs * 2, 30000);
}

Reduce your request volume

  • Use webhooks instead of polling payment status in a loop.
  • Cache slow-changing data such as the provider list from PaymentProvider.
  • Aggregate work: fetch lists with one request instead of fetching entities one by one.
  • Spread scheduled jobs such as reconciliation over time instead of firing them all at the top of the hour.

Never react to 403/405 with an immediate tight-loop retry — that keeps the block active. Always increase the delay between attempts.

Next: harden your error handling with Merchant API errors and set up webhooks.