Skip to main content
The Samsa API protects shared capacity with two independent limits: a per-key request rate and a per-organization concurrent-job cap. Both return 429 with headers that tell you when to retry.
These limits are defaults and are subject to change. If your integration needs a higher ceiling, contact support@samsa.ai.

Per-key request rate

Each API key may make up to 60 requests per minute, measured as a sliding 60-second window. Exceeding it returns 429 with code: "rate_limited". Successful responses and rate-limit 429s carry the current window state (the Retry-After header is added on 429s only):
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 41
X-RateLimit-Reset: 1782043260
HeaderMeaning
X-RateLimit-LimitRequests allowed per window (default 60).
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets.
Retry-AfterSeconds to wait before retrying. Sent on 429 responses only.
Read X-RateLimit-Remaining on successful responses to slow down before you hit the limit.

Per-organization concurrency cap

Independently of request rate, an organization may have at most 5 concurrent in-flight jobs — generation, edit, video, and model-creation jobs that are still pending or processing, counted across every key in the organization. Submitting another job while at the cap returns 429 with code: "too_many_active_jobs" and a Retry-After header:
429 Too Many Requests
{
  "error": {
    "type": "rate_limit_error",
    "code": "too_many_active_jobs",
    "message": "Too many active jobs for this organization (5/5). Wait for in-flight jobs to finish before submitting more.",
    "request_id": "req_801c9a3b7d2d5f4a"
  }
}
This cap protects processing capacity, so it is keyed to the whole organization, not a single key. Wait for in-flight jobs to reach a terminal status — poll their GET endpoint, or subscribe to a webhook — before submitting more.

An example 429

A 429 from the per-key window includes both the Retry-After and X-RateLimit-* headers:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1782043260
Content-Type: application/json

{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "API rate limit exceeded. Slow down and retry after the rate-limit window resets.",
    "request_id": "req_5f4a801c9a3b7d2d"
  }
}

Handling 429s

1

Honor Retry-After

When a 429 includes a Retry-After header, wait at least that many seconds before retrying. It is the authoritative signal.
2

Back off exponentially

For repeated 429s, increase the delay between attempts (for example 1s, 2s, 4s, 8s…), capped at a sensible maximum, with a little random jitter to avoid thundering-herd retries.
3

Stay under the limit proactively

Watch X-RateLimit-Remaining and throttle client-side before you hit 0. For the concurrency cap, bound how many jobs you keep in flight at once.
Below is a minimal retry loop that honors Retry-After and falls back to exponential backoff.
import time
import requests


def request_with_retry(method, url, *, headers, max_retries=5, **kwargs):
    for attempt in range(max_retries + 1):
        resp = requests.request(method, url, headers=headers, **kwargs)
        if resp.status_code != 429 or attempt == max_retries:
            return resp
        retry_after = resp.headers.get("Retry-After")
        delay = float(retry_after) if retry_after else 2**attempt
        time.sleep(delay)
    return resp

Outer per-IP protection

Beyond these per-key and per-organization limits, Samsa applies a coarse per-IP protection layer at the network edge (shared with the rest of the platform). It is a backstop against abusive traffic, not a limit you tune per integration — well-behaved server-side clients that respect the limits above will not encounter it. If you route many organizations through a single egress IP and see unexpected throttling, contact support@samsa.ai.