PayCaptain Developers

API

Limits and retries

Rate limits, retry behaviour and pagination.

View as Markdown

Rate limits#

Limit Threshold When you reach it
Requests per second 5 Queue and retry with backoff
Requests per minute 100 Queue and retry with backoff
Requests per hour 2,000 Queue and resume in the next hour
Concurrent connections 3 Queue additional requests

Retries#

On 429 or any 5xx, wait and retry with exponential backoff: start at 1 second, double each time, cap at 60 seconds. After 5 consecutive failures, stop and alert someone. Never retry a 400.

async function callWithRetry(apiCall, maxAttempts = 5) {
  let delay = 1000;
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const response = await apiCall();
    if (response.status >= 200 && response.status < 300) return response;
    if (response.status !== 429 && response.status < 500) {
      throw new Error(`PayCaptain rejected the request: ${response.status}`); // do not retry
    }
    await new Promise((resolve) => setTimeout(resolve, delay));
    delay = Math.min(delay * 2, 60000);
  }
  throw new Error("PayCaptain unavailable after 5 attempts. Halt and alert.");
}

Pagination#

GET /employees and GET /payslips return up to 50 records per page. Request pages in order until you receive a 204.

async function fetchAll(path, params) {
  const records = [];
  for (let page = 1; ; page++) {
    const response = await callWithRetry(() => get(path, { ...params, page }));
    if (response.status === 204) return records;
    records.push(...(await response.json()));
  }
}