Errors

Request-level failures return an HTTP status, a stable machine code, a safe message and a request id. An accepted AI rewrite instead carries its pending or terminal state in the operation response.

Shape

JSON
{
  "error": {
    "code": "invalid_request",
    "message": "text: Too small: expected string to have >=1 characters",
    "docs": "https://genpolish.app/docs/errors#invalid_request",
    "requestId": "3f1c…",
    "issues": [{ "path": "text", "message": "Too small: …" }]
  }
}

docs points at the anchor on this page that describes the code, so a failing response carries its own documentation. requestId is the same value as the X-Request-Id response header.

Codes

invalid_request400
The body does not match the contract. issues[] names the field and the problem.
missing_authorization401
No Authorization header and no session cookie.
invalid_api_key401
The key is malformed, unknown, or from the other environment.
invalid_session401
The session token was rejected. Log in again.
session_auth_unavailable501
No session verifier is configured for the legacy API. AI rewrite endpoints require a real account session; an API key is not a substitute.
rate_limited429
Too many requests in the window. Respect Retry-After; this is not the monthly word allowance.
quota_exceeded429
Insufficient available input words, or no anonymous success remaining. Waiting for a request-rate window does not add words or trials.
idempotency_conflict409
This intention key already identifies a different request. Recover its existing operation; do not silently replace the intention.
invalid_anonymous_session401
The anonymous identity is missing, expired, invalid or already claimed. It is not reset to three trials.
workspace_expired410
The temporary source workspace has expired.
stale_operation409
The source workspace/version or execution capability no longer matches the operation.
legacy_plan_review409
This account requires review before metered rewriting.
word_service_unavailable503
Word accounting is unavailable. This does not mean the balance is zero.
rewrite_unavailable503
The AI engine is disabled, unconfigured, busy or unavailable. Existing operations can still be recovered when storage is available.
rewrite_timeout504
The computation deadline or cancellation ended the attempt. Recover the operation to determine its final state.
rewrite_empty_output502
The provider returned no usable text. No successful consumption is confirmed for this output.
rewrite_invalid_output502
The result violated its structure, size or preservation requirements. It is not accepted as a successful rewrite.
rewrite_refused422
The provider refused the request. A fallback is not used to bypass a refusal.
service_unavailable503
The service could not establish the outcome. Recover an accepted operation before making a new intention.
forbidden403
This origin or action is not allowed. CORS does not grant authorization.
payload_too_large413
The request body exceeds the endpoint byte limit.
unsupported_media_type415
Send an uncompressed JSON body with the appropriate Content-Type.
persistence_unavailable501
save: true on a deployment that stores nothing. Nothing was polished.
not_found404
No route, or no document with that id.
internal_error500
Quote requestId in a bug report. Recover an accepted rewrite before starting a new intention.
Recover before retrying
A lost network response does not prove failure. For AI rewriting, keep the same operationId and recover the operation by GET; never automatically create a fresh intention. A known failed or expired intention is not rerun. Rate limits (rate_limited) and exhausted words/trials (quota_exceeded) are different conditions.