Error handling
Every ToHuman API response includes a conventional HTTP status code so your integration can tell at a glance how a request went. Codes in the 2xx range mean the request succeeded, 4xx means the request needs a change on your side, and 5xx means something went wrong on ours. This page lists each code the API returns, the response body that comes with it, and how your client should react.
Status codes
| Status | Description |
|---|---|
| 200 | Request succeeded. |
| 201 | Resource created successfully. |
| 401 | Missing or invalid API token — check your authentication setup. |
| 402 | Payment required — your monthly word allowance is used up. Upgrade to Pro or buy a word pack to continue. |
| 403 | Your token doesn't have permission for this action. |
| 404 | The requested resource doesn't exist or isn't visible to your API token. |
| 422 | The request body is invalid or missing required fields. |
| 429 | You've exceeded the rate limit — slow down and retry. |
| 500 | Something went wrong on our end. Safe to retry with backoff — see retries below. |
Error response format
When a request can't be completed, the API returns a JSON body with an error field describing what to fix:
{
"error": "Content is required"
}
(empty body — check the status code)
When your account's monthly word allowance (2,500 words on Free, 100,000 on Pro) and any purchased word credits are used up, humanization requests return 402 Payment Required with your usage numbers and the ways to continue. Nothing is created or charged for a rejected request, and the very next request succeeds as soon as you upgrade or top up:
{
"error": "Monthly word allowance reached.",
"words_used": 2534,
"word_cap": 2500,
"word_credits": 0,
"upgrade_url": "https://tohuman.io/pricing",
"word_pack_url": "https://tohuman.io/checkout?plan=pack"
}
Requests that exceed the sync word limit return a message pointing you to the async endpoint:
{
"error": "Content exceeds 2000 word limit for sync. Use async endpoint instead."
}
Retries and timeouts
A resilient integration treats each range of status codes differently:
-
Retry
429after the window resets. TheX-RateLimit-Resetheader tells you exactly when you can resume — wait until then instead of hammering. Details on the rate limits page. -
Retry
5xxwith exponential backoff. Start around one second, double each attempt, add jitter, and cap at three or four attempts. These responses are transient — the same request usually succeeds moments later. -
Don't retry other
4xxresponses. They mean the request itself needs to change — an invalid token, a missing field, an exhausted word allowance. Retrying the identical request will return the identical response. - Long texts belong on the async endpoint. Humanizing runs as fast as quality allows, so large sync requests can take tens of seconds. If your HTTP client times out on big payloads, switch to create (async) and poll for the result instead of holding the connection open.
Humanization requests that are rejected — for any reason — never consume words from your allowance, so retrying is always safe from a billing perspective.