Skip to main content

Rate limits and task quotas

Artguru applies call-rate limits and active-task quotas to protect the service from retry storms and accidental overload. A rejected request returns HTTP 429 with business code -1000 and does not consume credits.

Current limits​

LimitCurrent valueApplies to
Calls per minute100Each API key
Calls per hour1,000Each API key
Active generation tasks3Each API key
Service-wide calls per minute10,000All API clients combined
Service-wide calls per hour50,000All API clients combined

Every authenticated API call counts toward the call-rate windows, including image uploads, task polling, and calls to GET /api/v1/usage. The active-task quota only applies when creating a generation task. A task occupies a slot after it is accepted and releases it when it reaches a terminal state.

Service-wide limits are protective ceilings shared by all clients, not capacity reserved for an individual account. Limits may change as the API evolves.

Inspect remaining call quota​

Call GET /api/v1/usage to inspect the remaining per-key and service-wide call quota. The request to /usage is itself counted before the returned values are calculated.

The endpoint currently reports call-rate windows only. It does not report the number of active tasks or remaining active-task slots.

Handle 429 Too Many Requests​

A quota rejection can include these response headers:

HeaderMeaning
RateLimit-LimitLimit for the scope that rejected the request.
RateLimit-RemainingRemaining capacity for that scope; normally 0 on rejection.
RateLimit-ResetUnix timestamp in seconds when the rejected scope is expected to reset.
Retry-AfterMinimum number of seconds to wait before retrying.
RateLimit-ScopeThe limit that rejected the request; see below.

RateLimit-Scope is one of:

ScopeMeaning
api_key_minuteThis API key reached its per-minute call limit.
api_key_hourThis API key reached its per-hour call limit.
global_minuteThe shared service reached its per-minute call limit.
global_hourThe shared service reached its per-hour call limit.
api_key_active_tasksThis API key already has the maximum number of active generation tasks.

When Retry-After is present, always honor it. If it is absent, use exponential backoff with random jitter. Jitter is especially important when many workers share a key, so they do not all retry at the same instant. For api_key_active_tasks, continue polling the tasks you already have and submit a new task only after one becomes terminal. Changing API keys is not a retry strategy.

For HTTP 503, honor Retry-After when present and use exponential backoff with jitter. Do not retry 400 or 401 responses without first changing the invalid request or credential.

Generation retries are not idempotent

X-Request-Id correlates logs but is not an idempotency key. If a generation submission times out after reaching the server, immediately sending the same request again can create a second task and consume credits again. Store the requestId and returned taskId; retry a submission only when you know the first request was not accepted.