Skip to content

Rate Limits

Varity TeamCore Contributors

The Varity platform API (https://varity.app/api) has no per-route request budgets. Two limits can answer 429, and they mean different things.

Creating a deployment or a machine is admitted into a platform-wide queue. When that queue is full, the create is refused before anything is allocated or charged:

{
"code": "queue_saturated",
"message": "The deployment queue is full right now. Try again shortly.",
"retryable": true,
"docs_url": "https://docs.varity.so/api/errors#queue_saturated",
"correlation_id": "..."
}

queue_saturated is always retryable: true. Wait a few seconds and retry the same request with the same Idempotency-Key (below), so a retry can never create a second deployment or machine. Reads, logs, and deletes are not queued. Stopping a resource is never throttled: a resource you cannot turn off keeps billing.

The edge in front of varity.app applies a per-client abuse limit. It is set far above what a portal session, the CLI, the MCP server, or an SDK loop sends, so a normal integration never meets it. A client that does is answered with a plain-text 429 Too Many Requests from the edge, without the JSON error envelope. Slow down and retry with backoff and jitter.

import time, random, requests
def call(method, url, **kw):
for attempt in range(6):
r = requests.request(method, url, **kw)
if r.status_code != 429:
return r
time.sleep(2 ** attempt + random.uniform(0, 1)) # backoff with jitter
raise RuntimeError("still limited")

Every response carries an x-request-id header. Send your own X-Request-Id and it is echoed back as correlation_id in any error body. See API Errors.

Per-plan account limits are planned. When they ship, they will be documented on this page.

Retrying a create after a 429 is safe only if it is idempotent. Send an Idempotency-Key on every create so a retry cannot produce a second deployment or machine:

Terminal window
curl -X POST https://varity.app/api/deployments \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deploy-my-app-001" \
-d '{ "name": "my-app", "repository": { "url": "https://github.com/me/my-app" } }'

Idempotency-key validation is route-specific. Deployment and template creates accept an optional key up to 160 characters. Machine create and delete require [A-Za-z0-9._:-]{8,128}. AI Gateway attachment mutations require the same character set with a length of 1 to 160. Follow the operation’s schema in the OpenAPI document. Replaying the same key with the same body returns the original result; reusing it with a different body returns 409 idempotency_key_reused. See API Errors.

Some limits are enforced by the resource contract rather than by a request budget:

  • Health history: GET /api/deployments/{id}/health-history accepts limit with a default of 100 and a maximum of 500 observations.
  • Idempotency keys: constraints differ by operation; use the OpenAPI parameter on the route you are calling. Records are retained for 24 hours.

The AI Gateway (https://ai.varity.app/v1) is a separate surface with its own independent rate-limit, concurrency, and budget admission controls. Limits documented here do not apply to it. See AI Gateway Rate Limits.