Skip to navigation

Errors & Troubleshooting

View as Markdown

Use this page when a request fails or behaves unexpectedly. Endpoint reference pages document per-field validation; this page explains what failed, how to fix it, and how to retry safely.

Error response shape

Most REST errors return JSON:

{
"error": {
"message": "Human-readable description",
"code": "invalid_request_error"
}
}
error.codeTypical HTTP statusMeaning
invalid_api_key_error403Missing, malformed, or unknown API key
invalid_request_error400 / 413 / 422Bad parameters, payload, or file
unprocessable_entity_error422Schema valid but business rule failed
not_found_error404Resource does not exist (e.g. unknown job ID)
insufficient_quota_error402Credit balance is empty
rate_limit_exceeded_error429 / 503Too many requests on your own account
model_rate_limit_exceeded_error429Model or upstream capacity, not your quota
seat_budget_exhausted_error429Seat spend budget used up
audio_duration_busy_error429Gateway busy reading audio duration
internal_server_error500Server-side failure, retry with backoff
model_call_failed502Model backend unreachable, retry
model_overloaded503Model overloaded, retry with backoff

402 is a wallet problem, 429 is a “not now” problem. An empty credit balance returns 402 with insufficient_quota_error and the message No credits available. Rate limits, model capacity and seat budgets return 429, with four different codes behind it that need different responses — see Rate limits and capacity below. Adding credits clears a 402 immediately; only some 429s clear by waiting.

Some endpoints add their own codes for product-specific rules, for example Document Digitization returns invalid_request_error (400) when a file exceeds the 10-page limit. These are listed in the “Errors” section of each API guide.

Auth failures use HTTP 403, not 401. Treat 403 with invalid_api_key_error as an authentication problem. See Authentication.

HTTP status quick reference

StatusWhen it happensWhat to do
400Invalid body or parametersFix request; do not retry blindly
402Credit balance exhaustedAdd credits in Billing & payments; retrying will not help
403Invalid API key (or forbidden), or TIER_LIMIT_REACHED when you reach your saved-voice limit (50 on Starter)Check error.code and key header; for TIER_LIMIT_REACHED, delete a saved voice to free a slot
422Validation failed (e.g. wrong field name)Compare with OpenAPI / guides
429Rate limit, model capacity, or seat budgetBack off for rate and capacity; top up for seat_budget_exhausted_error
500 / 502 / 503Transient server or model issuesRetry with exponential backoff

Out of credits (402)

A 402 means the organisation’s credit balance is empty, not that you are being rate limited. The balance is shared by every workspace, API key and product, so a 402 from one service means the whole organisation is out of credits.

{
"error": {
"message": "No credits available.",
"code": "insufficient_quota_error"
}
}

To recover:

  1. Add credits on Settings → Billing. See Billing & payments.
  2. Turn on Auto-Recharge so a low balance tops up before production traffic stops.
  3. Retry the failed request once credits land. No key rotation or redeploy is needed.

Do not put 402 in your exponential-backoff retry set. It will not clear on its own, and retrying only burns your own request budget.

Rate limits and capacity (429)

Every 429 says “not now”, but four different codes sit behind it and they need different responses:

error.codeWhat it meansWhat to do
rate_limit_exceeded_errorYour account has hit its requests-per-minute limitBack off and retry; capacity refills continuously. See Credits & Rate Limits
model_rate_limit_exceeded_errorThe model or its upstream provider is saturated, which is not your quotaBack off and retry; honour Retry-After when it is present
seat_budget_exhausted_errorA seat in your organisation has used its spend budget for the periodTop up or raise the budget; retrying will not clear it. The response also carries a spend_limits snapshot
audio_duration_busy_errorThe gateway’s audio-duration readers are busyRetry after a short delay

Only the first is your own quota. Treating all four as “rate limited, back off” leaves an exhausted seat budget looking like a temporary blip.

SDK handling (Python)

from sarvamai import SarvamAI
from sarvamai.core.api_error import ApiError
client = SarvamAI(api_subscription_key="YOUR_SARVAM_API_KEY")
try:
response = client.speech_to_text.transcribe(
file=open("audio.wav", "rb"),
model="saaras:v4",
mode="transcribe",
)
except ApiError as e:
if e.status_code == 403:
print("Check SARVAM_API_KEY, auth uses 403, not 401")
elif e.status_code == 402:
print("Credits exhausted, add credits on Settings -> Billing")
elif e.status_code == 429:
# rate limit, model capacity, or seat budget: check e.body["error"]["code"]
print("Rate limited or out of capacity, retry after delay")
else:
print(e.status_code, e.body)

SDK handling (JavaScript)

import { SarvamAIClient } from "sarvamai";
const client = new SarvamAIClient({
apiSubscriptionKey: process.env.SARVAM_API_KEY,
});
try {
const response = await client.speechToText.transcribe({
file: audioFile,
model: "saaras:v4",
mode: "transcribe",
});
} catch (err) {
// SDK wraps HTTP errors, inspect status and body
// 402 = out of credits, 429 = rate limit / capacity / seat budget
console.error(err.statusCode, err.body);
}

Retry with exponential backoff

Use retries only for 429, 500, 502 and 503: not for 400, 402, 403 or 422. A 402 needs credits, not another attempt, and a 429 carrying seat_budget_exhausted_error needs a top-up rather than a backoff.

import time
def call_with_backoff(fn, max_retries=5):
delay = 1.0
for attempt in range(max_retries):
try:
return fn()
except ApiError as e:
if e.status_code not in (429, 500, 502, 503) or attempt == max_retries - 1:
raise
time.sleep(delay)
delay = min(delay * 2, 60)

Common pitfalls

SymptomLikely causeFix
402 insufficient_quota_errorOrganisation credit balance is exhaustedAdd credits on Settings → Billing, or enable auto-recharge. See Billing & payments
429 seat_budget_exhausted_errorA seat has used its spend budget for the periodTop up or raise the budget; read error.spend_limits. Waiting does not help
429 model_rate_limit_exceeded_errorThe model or upstream provider is saturatedBack off and retry; this is not your own quota
403 on every callWrong or missing api-subscription-keySet SARVAM_API_KEY; handle 403 not 401
422 on doc digitizationUsed language_code instead of languageUse language, flat in Document AI, nested as job_parameters.language in the legacy API
400 output_formatSent "markdown"Use "md" or "html" only (parse rejects "json")
405 on doc/STT downloadUsed GETLegacy API: use POST with job_id + files array. Document AI: GET /doc-ai/v1/job/{job_id}/download-url
409 on doc translation exportTranslation not yet Completed for that languageCheck each language’s state in translations[] from live-status; export only languages where state is Completed
Doc translation stuck in AcceptedFile never uploaded or start never calledPUT the file to upload_url, then call POST /translate/document/jobs/{job_id}/start
TTS returns base64 stringExpected raw bytesbase64.b64decode(response.audios[0].audio). See TTS REST
Instant Voice Cloning returns base64 stringExpected raw bytesbase64.b64decode(response.audio). See Instant Voice Cloning overview
Instant Voice Cloning 400 for missing voiceNo voice_id was sentCreate a voice with POST /voices/create, then pass its voice_id to POST /voices/clone. See Instant Voice Cloning overview
Chat 400Missing modelPass model="sarvam-105b" or model="sarvam-105b-conversations"
Chat V2 400Serde / type mismatch in JSON bodyFix field types to match Chat Completion V2; read error.message (e.g. boolean vs string). Include error.request_id in support tickets when present.
Chat V2 400 (glm5.3)logprobs: true, or top_logprobs present (including 0)Omit top_logprobs entirely; use logprobs: false or omit logprobs. See GLM-5.3
Chat V2 503 (glm5.3)More than four stop sequencesSend at most four stops; note SDKs may auto-retry 503 for this case
Pronunciation dict JS 400Blob without JSON MIMEUse fetch + FormData workaround. See Pronunciation Dictionary
Batch webhook empty transcriptExpected text in webhookWebhook is JobStatusResponse only, download output JSON files

Support workflow

  1. Note timestamp, endpoint, and error.code from the response body.
  2. Reproduce with curl or SDK using the smallest failing request.
  3. Check API Status for incidents.
  4. Contact support via Talk to us with request ID if available.