Limits and retries
Check active plan and usage limits through the account or GET /v1/billing/limits. Plan allowances, AI usage, storage and request rates are different constraints.
Published limits
Section titled “Published limits”| Limit | Value | Set by |
|---|---|---|
| AI requests per wallet | 600 a minute, 32 at once | Exepad |
| AI requests per app or target | 300 a minute, 16 at once | Exepad |
| Reading scanned pages (OCR) per wallet | 60 calls a minute, 6 at once | Exepad |
| Reading scanned pages (OCR), all apps together | 60 calls a minute, 6 at once; a refusal answers 429 ocr_rate_limited | Exepad |
| AI a build session uses to check its preview | 20 requests and $0.25 of provider cost, for 1 hour | Exepad |
| In-app AI across all wallets | $5,000 of provider cost a month | Exepad |
| Builds running at once | 2 per account, on every plan | Exepad |
| AI provider rate and capacity limits | Set by each provider and applied before ours | The provider |
Exepad can change the limits it sets, and this table changes with them. A provider’s own limits apply before ours and can change without notice. The shared limits are capacity every app draws on, so a request can be refused for reasons outside one wallet.
Handle a refused request
Section titled “Handle a refused request”Read the HTTP status and the response body. For a 429 response, wait for the Retry-After header when it is supplied, then retry with bounded exponential backoff and jitter. A 402 means the wallet or a plan limit refused the work, and retrying will not help until credit, funds or the plan change. A 403 permission error or a missing route needs a different correction.
Bound automation
Section titled “Bound automation”Set a maximum retry count and a deadline in your client. Keep read polling infrequent enough for the task. Before retrying a mutation, establish whether the original operation succeeded and whether that endpoint supports the idempotency behavior you need.