Back

    Buyamia Directory API

    v1.1.0

    Rate Limits & Quotas

    Every API key has its own per-minute request limit, set when the key is issued. The limit is counted per key over a rolling 60-second window and applies to all /v1/* routes together — there is no per-endpoint budget. Ask the Buyamia team if you need a higher limit.

    What happens when you exceed it

    The request is rejected before any scope check or database work, with 429 and { "error": "Rate limit exceeded" }. Nothing is written, so a rejected write is safe to retry.

    The API does not send X-RateLimit-* or Retry-After headers. Do not code against them — track your own request rate and back off on 429.

    Honest caveats

    • Counting is in-memory per function instance. Counters reset on cold start and are not shared between concurrent instances, so the effective limit can be higher than the configured number under bursty traffic.
    • Treat the limit as a guardrail against runaway loops, not as a contract or a capacity guarantee.
    • The health check (GET on the base URL, no /v1/ path) is unauthenticated and not rate limited.

    Designing inside the budget

    • Use limit=100 (the maximum) for bulk pulls — 1 request per 100 rows instead of 5.
    • Cache taxonomy (/v1/categories, /v1/product-categories, /v1/regions, /v1/countries) locally; it changes rarely.
    • Use webhooks instead of polling /v1/rfq/:id/quotes on a timer.
    • Serialise bulk jobs, or cap concurrency at a small fixed number of workers.
    • Run nightly full syncs off-peak and keep the day-to-day path event-driven.
    Backoff on 429typescript
    async function withBackoff<T>(fn: () => Promise<T>, tries = 5): Promise<T> {
      let lastErr: unknown;
      for (let i = 0; i < tries; i++) {
        try {
          return await fn();
        } catch (err) {
          lastErr = err;
          const msg = String((err as Error).message ?? err);
          const retryable = msg.includes('Rate limit exceeded') || msg.startsWith('HTTP 5');
          if (!retryable) throw err;
          const wait = Math.min(30_000, 2 ** i * 500) + Math.random() * 250;
          await new Promise(r => setTimeout(r, wait));
        }
      }
      throw lastErr;
    }

    Usage visibility

    Every authenticated request is logged server-side with the key, method, path, status and latency, and last_used_at is stamped on the key. Ask the Buyamia team for a usage extract if you need to reconcile your own counters — there is no self-service usage endpoint.

    Current as of API 1.1.0 — released 7 September 2026