venice-errors
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVenice errors & retries
Venice错误与重试
Every Venice endpoint returns one of four error shapes. Knowing which shape you got tells you how to react.
每个Venice端点都会返回四种错误结构之一。了解你遇到的错误结构可以指导你如何应对。
Error body shapes
错误体结构
1. StandardError
— simple message
StandardError1. StandardError
— 简单消息
StandardErrorThe default shape for 4xx/5xx. Emitted when there's nothing structured to surface.
json
{ "error": "Unauthorized" }这是4xx/5xx状态码的默认错误结构,当没有结构化信息需要展示时返回。
json
{ "error": "Unauthorized" }2. DetailedError
— Zod validation failure
DetailedError2. DetailedError
— Zod验证失败
DetailedErrorUsed for some responses on malformed request bodies. When present, is a Zod tree ( recursively keyed by field) alongside a flat array. Many s are plain without — always handle both.
400detailsformat()_errorsissues400StandardErrordetailsjson
{
"error": "Invalid request",
"details": {
"_errors": [],
"messages": { "_errors": ["Field is required"] }
},
"issues": [
{ "code": "invalid_type", "path": ["messages"], "message": "Field is required" }
]
}Render / to the user so they can fix the input; don't retry — the request shape is wrong.
detailsissues用于请求体格式错误的部分响应。当存在该错误时,是Zod的树(按字段递归标记),同时包含一个扁平化的数组。许多错误是不带的纯——请务必同时处理这两种情况。
400detailsformat()_errorsissues400detailsStandardErrorjson
{
"error": "Invalid request",
"details": {
"_errors": [],
"messages": { "_errors": ["Field is required"] }
},
"issues": [
{ "code": "invalid_type", "path": ["messages"], "message": "Field is required" }
]
}将 / 展示给用户,以便他们修正输入;请勿重试——请求格式本身存在问题。
detailsissues3. ContentViolationError
— 422 content policy
ContentViolationError3. ContentViolationError
— 422内容策略错误
ContentViolationErrorReturned when a prompt trips content policy. (a model-provided safe alternative) is currently emitted by the audio generation pipeline (, ); image and video endpoints return without .
suggested_prompt/audio/queue/audio/retrieve{ error: "Content policy violation" }suggested_promptjson
{
"error": "Content policy violation",
"suggested_prompt": "A cinematic instrumental track inspired by stormy weather and dramatic tension."
}Pattern — when is present, retry once with if the user consents.
suggested_promptprompt = suggested_prompt当提示触发内容策略限制时返回。(模型提供的安全替代提示)目前仅由音频生成流水线(、)返回;图像和视频端点仅返回,不带。
suggested_prompt/audio/queue/audio/retrieve{ error: "Content policy violation" }suggested_promptjson
{
"error": "Content policy violation",
"suggested_prompt": "A cinematic instrumental track inspired by stormy weather and dramatic tension."
}处理模式 — 当存在时,若用户同意,可使用重试一次。
suggested_promptprompt = suggested_prompt4. X402InferencePaymentRequired
— 402 on x402 inference calls
X402InferencePaymentRequired4. X402InferencePaymentRequired
— x402推理调用返回的402错误
X402InferencePaymentRequiredReturned only when the caller authenticated with SIWE and has insufficient credit. Discriminated by .
code: "PAYMENT_REQUIRED"json
{
"error": "Payment required",
"code": "PAYMENT_REQUIRED",
"message": "Insufficient x402 balance",
"suggestedTopUpUsd": 10,
"minimumTopUpUsd": 5,
"supportedTokens": ["USDC"],
"supportedChains": ["base"],
"topUpInstructions": {
"step1": "POST /api/v1/x402/top-up with no payment header to get payment requirements",
"step2": "Sign a USDC transfer authorization using the x402 SDK (createPaymentHeader)",
"step3": "POST /api/v1/x402/top-up with the signed X-402-Payment header",
"receiverWallet": "<RECEIVER_WALLET_ADDRESS>",
"tokenAddress": "<USDC_TOKEN_ADDRESS>",
"tokenDecimals": 6,
"network": "eip155:8453",
"minimumAmountUsd": 5
},
"siwxChallenge": { ... SIWE template ... }
}The response header carries a base64-encoded x402 v2 object (, , , , optional ) — it is not the same JSON as the body. Protocol-level clients parse the header; human-facing clients parse the richer body. See .
PAYMENT-REQUIREDpaymentRequiredx402Versionerrorresourceaccepts[]extensionsvenice-x402仅当调用者通过SIWE认证但余额不足时返回。可通过区分。
code: "PAYMENT_REQUIRED"json
{
"error": "Payment required",
"code": "PAYMENT_REQUIRED",
"message": "Insufficient x402 balance",
"suggestedTopUpUsd": 10,
"minimumTopUpUsd": 5,
"supportedTokens": ["USDC"],
"supportedChains": ["base"],
"topUpInstructions": {
"step1": "POST /api/v1/x402/top-up with no payment header to get payment requirements",
"step2": "Sign a USDC transfer authorization using the x402 SDK (createPaymentHeader)",
"step3": "POST /api/v1/x402/top-up with the signed X-402-Payment header",
"receiverWallet": "<RECEIVER_WALLET_ADDRESS>",
"tokenAddress": "<USDC_TOKEN_ADDRESS>",
"tokenDecimals": 6,
"network": "eip155:8453",
"minimumAmountUsd": 5
},
"siwxChallenge": { ... SIWE template ... }
}PAYMENT-REQUIREDpaymentRequiredx402Versionerrorresourceaccepts[]extensionsvenice-x402Status code map
状态码映射
| Status | Body | Meaning | What to do |
|---|---|---|---|
| | Malformed input. Zod | Fix and re-send. Don't retry. |
| | Missing / invalid Bearer API key or SIWE. | Rotate credentials. Don't retry. |
| Bearer: | Out of DIEM/USD/wallet credit. | Bearer: top up at venice.ai. SIWE: run the x402 top-up flow. |
| | Valid auth but not entitled. Typical: trial-limited endpoint, beta model, API-key consumption cap hit, SIWE signer ≠ path wallet. | Don't retry. Investigate entitlements. |
| | Wrong | Fix headers. Don't retry. |
| | Content policy violation on generation paths; schema-ish validation on others. | On audio generation, optionally retry once with |
| | Rate limit cap tripped. Also returned by | Honor |
| | Unexpected failure. | Retry with exponential backoff + idempotency key where supported. |
| | Upstream model / service temporarily down. | Retry with backoff. Consider a fallback model. |
| | Upstream slow. Mostly on | Switch to |
| 状态码 | 错误体 | 含义 | 处理方式 |
|---|---|---|---|
| | 输入格式错误。Zod | 修正后重新发送。请勿重试。 |
| | 缺少/无效的Bearer API密钥或SIWE认证。 | 更换凭证。请勿重试。 |
| Bearer认证:带配置消息的 | DIEM/USD/钱包余额不足。 | Bearer认证:前往venice.ai充值。SIWE认证:执行x402充值流程。 |
| | 认证有效但无权限。常见场景:试用版受限端点、测试模型、API密钥消耗上限、SIWE签名者与路径钱包不匹配。 | 请勿重试。 检查权限配置。 |
| | | 修正请求头。请勿重试。 |
| 图像/音频/视频生成: | 生成路径触发内容策略限制;其他路径触发类 schema 验证错误。 | 音频生成:可选择使用 |
| | 触发限流上限。当每日额度或并发上限触发时, | 遵循 |
| | 意外故障。 | 在支持的情况下,使用指数退避+幂等键重试。 |
| | 上游模型/服务暂时不可用。 | 退避后重试。考虑使用备用模型。 |
| | 上游服务响应缓慢。主要出现在上下文超大的 | 切换为 |
Rate-limit headers (429
)
429限流请求头(429
)
429Emitted on :
/crypto/rpc/{network}| Header | Meaning |
|---|---|
| Per-minute request cap for your tier (paid = 100, staff = 1000 on crypto RPC). |
| Requests remaining in the current 60-second window. |
| Unix timestamp in seconds when the window resets. |
Additionally, model-overloaded conditions set a header (seconds) on the 429 — honor it when present.
LlmInferenceErrorRetry-AfterInference endpoints (chat, image, audio, video) use a per-API-key tier defined via . See to pre-fetch your caps, and for DIEM/USD usage.
/api_keys/rate_limitsvenice-api-keysvenice-billing/crypto/rpc/{network}| 请求头 | 含义 |
|---|---|
| 你的套餐每分钟请求上限(付费版=100,内部员工在加密RPC上=1000)。 |
| 当前60秒窗口内剩余的请求次数。 |
| 窗口重置的Unix时间戳(秒)。 |
此外,当模型过载触发时,429响应会附带请求头(单位:秒)——请遵循该值。
LlmInferenceErrorRetry-After推理端点(聊天、图像、音频、视频)使用通过定义的每个API密钥的套餐限制。详见预获取你的上限,以及了解DIEM/USD使用情况。
/api_keys/rate_limitsvenice-api-keysvenice-billingResponse headers on 402
(x402)
402402
(x402)响应的请求头
402| Header | Notes |
|---|---|
| Base64-encoded JSON of the x402 v2 |
| 请求头 | 说明 |
|---|---|
| base64编码的x402 v2 |
Retry strategy
重试策略
Never retry
绝不重试
- — bad input. Fix the request.
400 - — bad auth. Fix credentials.
401 - — not entitled. Don't hammer.
403 - — wrong
415.Content-Type
- — 输入错误。修正请求。
400 - — 认证错误。修正凭证。
401 - — 无权限。请勿重复请求。
403 - —
415错误。Content-Type
Retry with modification
修改后重试
- (x402) — run top-up then retry.
402 - (Bearer) — surface to user; top up at venice.ai.
402 - with
422— one retry with the safer prompt.suggested_prompt
- (x402) — 完成充值后重试。
402 - (Bearer) — 告知用户;前往venice.ai充值。
402 - 带的
suggested_prompt— 使用更安全的提示词重试一次。422
Retry with backoff
退避后重试
- — back off for at least
429. Add jitter.X-RateLimit-Reset - now() - /
500/503— exponential backoff (e.g. 0.5s, 1s, 2s, 4s, 8s), capped at ~30s. 3–5 retries max.504 - Use (e.g. on
Idempotency-Key) so retries can't double-bill state-mutating calls./crypto/rpc/{network}
- — 至少等待
429时间。添加抖动。X-RateLimit-Reset - now() - /
500/503— 指数退避(例如0.5s、1s、2s、4s、8s),最大延迟约30s。最多重试3–5次。504 - 使用(例如在
Idempotency-Key上),确保重试不会导致状态变更类请求重复计费。/crypto/rpc/{network}
Reference retry loop
参考重试循环
ts
async function callVenice<T>(fn: () => Promise<Response>): Promise<T> {
const maxRetries = 5
let delay = 500
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fn()
if (res.ok) return res.json() as Promise<T>
const body = await res.clone().json().catch(() => ({}))
const { status } = res
if ([400, 401, 403, 415].includes(status)) {
throw Object.assign(new Error(body.error ?? 'Venice error'), { status, body })
}
if (status === 402 && body.code === 'PAYMENT_REQUIRED') {
await topUpX402(body.suggestedTopUpUsd)
continue
}
if (status === 422) {
throw Object.assign(new Error('Content policy'), { status, body })
}
if (status === 429) {
const retryAfterSec = Number(res.headers.get('retry-after'))
const resetSec = Number(res.headers.get('x-ratelimit-reset'))
const waitMs = !Number.isNaN(retryAfterSec) && retryAfterSec > 0
? retryAfterSec * 1000
: !Number.isNaN(resetSec) && resetSec > 0
? Math.max(resetSec * 1000 - Date.now(), delay)
: delay
await sleep(waitMs + Math.random() * 250)
delay *= 2
continue
}
if (status >= 500 && attempt < maxRetries) {
await sleep(delay + Math.random() * 250)
delay *= 2
continue
}
throw Object.assign(new Error(body.error ?? 'Venice error'), { status, body })
}
throw new Error('Exceeded max retries')
}ts
async function callVenice<T>(fn: () => Promise<Response>): Promise<T> {
const maxRetries = 5
let delay = 500
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fn()
if (res.ok) return res.json() as Promise<T>
const body = await res.clone().json().catch(() => ({}))
const { status } = res
if ([400, 401, 403, 415].includes(status)) {
throw Object.assign(new Error(body.error ?? 'Venice error'), { status, body })
}
if (status === 402 && body.code === 'PAYMENT_REQUIRED') {
await topUpX402(body.suggestedTopUpUsd)
continue
}
if (status === 422) {
throw Object.assign(new Error('Content policy'), { status, body })
}
if (status === 429) {
const retryAfterSec = Number(res.headers.get('retry-after'))
const resetSec = Number(res.headers.get('x-ratelimit-reset'))
const waitMs = !Number.isNaN(retryAfterSec) && retryAfterSec > 0
? retryAfterSec * 1000
: !Number.isNaN(resetSec) && resetSec > 0
? Math.max(resetSec * 1000 - Date.now(), delay)
: delay
await sleep(waitMs + Math.random() * 250)
delay *= 2
continue
}
if (status >= 500 && attempt < maxRetries) {
await sleep(delay + Math.random() * 250)
delay *= 2
continue
}
throw Object.assign(new Error(body.error ?? 'Venice error'), { status, body })
}
throw new Error('Exceeded max retries')
}Streaming errors
流式错误
Streaming responses ( on chat, TTS, video-queue progress) deliver mid-stream errors as SSE events:
stream: truedata: {"error": {"type": "…", "message": "…"}}Treat them as terminal — the underlying connection is closed. The HTTP status is because a successful stream can't be changed mid-flight.
200流式响应(聊天、TTS、视频队列进度的)会通过SSE事件传递中途错误:
stream: truedata: {"error": {"type": "…", "message": "…"}}将此类错误视为终止信号——底层连接已关闭。HTTP状态码为,因为成功启动的流无法中途修改状态。
200Request-ID correlation
Request-ID关联
When present on a response, keep the header. Include it in support tickets — Venice keys diagnostic logs by this ID. routes set it explicitly; many inference routes also include it, but don't assume it's universal — fall back to your own client-side correlation ID.
X-Request-ID/crypto/rpc/*若响应中存在请求头,请保留该值。在提交支持工单时包含它——Venice通过该ID关联诊断日志。路由会明确设置该请求头;许多推理路由也会包含,但不要假设它是通用的——若不存在,请回退使用客户端自己的关联ID。
X-Request-ID/crypto/rpc/*Common gotchas
常见陷阱
- A from
402with no/x402/top-upheader is the expected discovery response, not an error. SeeX-402-Payment.venice-x402 - A on
500with a huge file upload often means the upstream model chose to abort — reduce/chat/completions/ image size rather than blindly retrying.max_tokens - on
429may mean the 24-hour credit cap tripped, not the per-minute one. Check/crypto/rpc/{network}.customMessage - is a Zod
DetailedError.detailstree, not a flat map. Walk it recursively._errors - Some endpoints (image generation) echo variants — treat any header whose name starts with
X-Rate-Limitas advisory.X-RateLimit - Don't treat an empty chunk as an error — send-keepalives look like
streamor empty lines.data: [DONE]
- 不带请求头调用
X-402-Payment返回的/x402/top-up是预期的发现响应,而非错误。详见402。venice-x402 - 上传大文件时返回
/chat/completions通常意味着上游模型主动终止——请减小500/图像大小,而非盲目重试。max_tokens - 返回的
/crypto/rpc/{network}可能意味着触发了24小时额度上限,而非每分钟上限。请检查429。customMessage - 是Zod的
DetailedError.details树,而非扁平化映射。请递归遍历它。_errors - 部分端点(图像生成)会返回变体——将任何名称以
X-Rate-Limit开头的请求头视为参考值。X-RateLimit - 请勿将空的块视为错误——保活信号看起来像
stream或空行。data: [DONE]