DevelopersRate limits & quotas

Rate limits & quotas

The PhiWebs API protects every World with two separate ceilings:

  • REST rate limits — count requests per rolling window, by endpoint class (public, read, write, admin). Limits are platform-tuned and may be adjusted operationally without a version bump.
  • AI credits — count the credits spent on PhiCo turns, by the work each turn produces; reset each billing period.

Both ceilings degrade gracefully — the API answers with a typed error shape, never a silent drop or a 500.

Rate limit headers

Rate-limited responses carry the current window state:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 12
X-RateLimit-Reset: 1718200800

429 response shape

When you exhaust a window, the API returns HTTP 429 Too Many Requests with a Retry-After header in seconds and a typed JSON body:

HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json
 
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests, please try again later",
    "retryAfter": 42,
    "traceId": "…",
    "timestamp": "2026-06-12T09:30:00.000Z"
  }
}

The envelope is the same for every error, but three different refusals can stop the same request, and a client that only checks for one mishandles the other two:

CodeStatusWhat it means
RATE_LIMIT_EXCEEDED429Too many requests. Read retryAfter and retry.
PLAN_LIMIT_EXCEEDED403 or 429A plan ceiling was reached. The error carries dimension, used, limit, unit and planCode. A standing limit (live apps, records, storage, members) answers 403 and keeps failing until the plan changes; a rolling Φ pace window answers 429 with Retry-After, and the same request works again once the window moves.
CREDIT_LIMIT_EXCEEDED402The Φ wallet is empty. No backoff helps — this needs Φ, not patience.

So branch on the code, not on the status: 402 is not a 429, and a plan ceiling is not congestion.

Honour Retry-After. If you must implement your own backoff:

  1. Start with the Retry-After value (or 1 second if missing).
  2. Double on every subsequent 429, capped at 60 seconds.
  3. Add ±25% jitter to avoid thundering-herd reconnects.

Wrap your calls in a retry loop that does this — the API will not retry for you.

AI credits

AI credits track AI cost separately from REST volume — internally this economy is metered in a unit called Φ. Each plan loads a monthly allowance of Φ; the Wallet page of your account shows yours, what the month has spent, and where to add more. See Billing & plans.

When you hit the cap

  • PhiCo turns are refused until you add Φ from the Wallet page.
  • AI credits are charged per turn, based on the work the turn produces — accepting or rejecting the resulting Receipt costs nothing on its own.

Inspecting your usage

Hit the REST endpoints directly:

GET /api/ai/usage           # AI credit ledger spend per period
GET /api/ai/credits/balance # remaining AI credits
GET /api/billing/overview   # plan, period, billing state

Call these with your bearer token; the response carries the same counters your account page shows.

See also