Errors and troubleshooting
Every API failure has a stable code, a readable message and a link to its exact fix.
{
"error": {
"code": "unauthorized",
"message": "A valid API key is required.",
"docs_url": "https://metaphrase.msalman.com/docs/errors#unauthorized"
}
}
Use HTTP status and error.code in program logic, not English wording. Keep X-Request-Id for support. For SSE, HTTP 200 can contain an error event after output starts; only done marks success. See streaming.
invalid_file
HTTP 422. This document could not be read.
Fix: Upload an unencrypted .txt (UTF-8), .docx, or text-based .pdf file, at most 5 MB and within max_input_chars. Scanned PDFs need OCR first.
invalid_request
HTTP 400. Check the request fields and their allowed values.
Fix: Send the documented JSON fields with the correct types. Unknown fields are rejected.
invalid_json
HTTP 400. The request body is not valid JSON.
Fix: Serialize the request with JSON.stringify or your language's JSON encoder.
unsupported_media_type
HTTP 415. Send application/json content.
Fix: Set Content-Type: application/json. File uploads use their separate documented route.
body_too_large
HTTP 413. The request body exceeds the allowed size.
Fix: Reduce the payload and split long documents at sentence boundaries.
text_too_long
HTTP 413. The text exceeds the configured character limit.
Fix: Use the max_input_chars value in the API specification and split longer documents.
unauthorized
HTTP 401. A valid API key is required.
Fix: Send Authorization: Bearer YOUR_KEY. Create a new key if the old one was revoked.
forbidden
HTTP 403. This action is not available to this account.
Fix: Check account status and the key's access permissions.
rate_limited
HTTP 429. Too many requests. Please wait and try again.
Fix: Wait for Retry-After seconds and use exponential backoff with jitter.
quota_exceeded
HTTP 429. The monthly usage quota has been reached.
Fix: Wait for the next UTC calendar month or ask an administrator to change the plan.
budget_exceeded
HTTP 429. The writing service has reached its configured spending limit.
Fix: The operator must review usage and adjust the configured budget before more paid requests can run.
verification_required
HTTP 403. Please complete the verification challenge.
Fix: Complete Turnstile in the web interface, then submit the new verification token.
provider_not_configured
HTTP 503. The writing provider is not configured yet.
Fix: The operator must configure LLM_PRIMARY_API_KEY or a fallback provider in .env and recreate the web container.
upstream_unavailable
HTTP 503. The writing provider is temporarily unavailable.
Fix: Retry with backoff. The operator can inspect provider availability without logging submitted text.
upstream_timeout
HTTP 504. The writing provider took too long to respond.
Fix: Retry a shorter input or wait before retrying. Do not append a retry to partial streamed output.
upstream_error
HTTP 502. The writing provider returned an invalid response.
Fix: Retry once with a shorter input. If it continues, the operator should check the configured model's compatibility.
output_truncated
HTTP 502. The response reached its output limit before finishing.
Fix: Use a shorter input or ask the operator to adjust the tool's output cap and chunk size.
service_unavailable
HTTP 503. A required service is temporarily unavailable.
Fix: Wait and retry. The operator should check Redis, PostgreSQL, or the tool's health.
invalid_source
HTTP 422. The source could not be used.
Fix: Check the DOI, ISBN, or public HTTP URL, or use manual citation fields.
source_unavailable
HTTP 422. Source metadata could not be retrieved.
Fix: Try a DOI or ISBN, or enter the source details manually.
text_too_short
HTTP 422. More text is needed for a meaningful estimate.
Fix: Submit at least the documented minimum word count. Very short texts cannot be assessed meaningfully.
not_found
HTTP 404. This resource does not exist.
Fix: Check the API version, endpoint name, and resource identifier.
method_not_allowed
HTTP 405. This HTTP method is not supported.
Fix: Use POST for processing endpoints and the method documented for dashboard routes.
conflict
HTTP 409. This action conflicts with an existing resource.
Fix: Use a different identifier or retry after the existing operation has completed.
internal_error
HTTP 500. The request could not be completed.
Fix: Retry once. If it persists, provide the X-Request-Id header to the operator.
Troubleshooting FAQ
I received HTML instead of JSON. Check the exact HTTPS origin and path, your reverse proxy/CDN rules and the Content-Type. A CDN challenge or gateway failure is outside the API's JSON handler. SDKs surface it as an upstream error.
My browser integration works but exposes a key. Move the upstream request into a backend route; use the working proxy. CORS does not make a secret safe in frontend code.
My provider is not configured. This is an operator setting. Grammar, citations and extractive summaries still work. Generative tools require a provider configured on MetaPhrase, not an OpenAI key from every API consumer.
My grammar offsets are wrong with emoji. Offsets/lengths use UTF-16 code units. JavaScript slice works directly; Python clients need UTF-16 conversion, as shown on the grammar page.
My request succeeded but quota decreased for a cache hit. Accepted calls count against monthly quota; cache hits avoid model tokens, not request accounting. All tools share each key's cap.
The SDK raised an error with status=null. This is a client network/timeout failure before an HTTP status was received. Check connectivity and the configured base origin. Retrying paid work may incur another attempt, so use bounded retries.
The widget is blank or denied. Check the public widget ID, active linked key, exact scheme/host/port origin and your site's script/frame CSP. See widget setup.