Limits

JoyToken’s current public limits come from API key quota, key policy, and wallet balance precheck. Do not assume fixed QPS, RPM, or TPM quotas.

Current Limits

LimitSourceResult
Daily quotaAPI key budget402 insufficient_quota
Weekly quotaAPI key budget402 insufficient_quota
Wallet balancePersonal or organization wallet402 insufficient_quota
Fixed modelAPI key policy403 policy_rejected
Model blacklistAPI key policy403 policy_rejected
Tier allowlistAPI key policy and request tier403 policy_rejected
IP allowlist/blocklistAPI key policy403 policy_rejected

Tier Fallback

When a request uses model: "auto" or omits model, JoyToken may try another tier if the current tier lacks balance.

Current tierFallback order
premiumstandard -> economy
standardpremium -> economy
economystandard -> premium

When the request specifies a concrete model, JoyToken does not automatically switch to another model because of insufficient balance.

Client Handling

ErrorRetry?Fix
400NoFix request body
401NoAdd API key
402NoTop up or adjust key budget
403NoAdjust policy, IP, tier, or model
502Short backoffCould be routing or upstream temporary failure
503 / 504YesUse exponential backoff

Exponential Backoff

1const retryableStatuses = new Set([502, 503, 504]);
2
3export async function withJoyTokenRetry<T>(fn: () => Promise<T>, attempts = 3) {
4 let lastError: unknown;
5
6 for (let attempt = 0; attempt < attempts; attempt += 1) {
7 try {
8 return await fn();
9 } catch (error: any) {
10 lastError = error;
11 const status = error?.status ?? error?.response?.status;
12 if (!retryableStatuses.has(status) || attempt === attempts - 1) throw error;
13 await new Promise((resolve) => setTimeout(resolve, 300 * 2 ** attempt));
14 }
15 }
16
17 throw lastError;
18}