Quickstart
Get up and running in under a minute.
Get your API key
Sign up or log in at writehuman.ai, purchase an API subscription, and create your key from the dashboard.
Make your first request
Install an official SDK, or call the REST API directly:
npm install @writehuman/sdkpip install writehuman// npm install @writehuman/sdk
import { WriteHuman } from "@writehuman/sdk";
const wh = new WriteHuman({ apiKey: "wh_live_your_api_key_here" });
const out = await wh.humanize("Artificial intelligence has revolutionized the way we approach content creation and digital communication.");
console.log(out.results[0]);
console.log(out.words_remaining.total, "words left");See the response
Standard plans return a single result. Premium plans return 3 variations with human-likeness scores. On Premium, set enhanced to true to use the Enhanced model; the model field shows which one ran.
{
"id": "hum_a1b2c3d4e5f6",
"created": 1778533901580,
"results": [
"AI has changed how we create content and communicate online."
],
"scores": null,
"input_words": 14,
"words_remaining": {
"included": 124986,
"topup": 0,
"total": 124986
},
"model": "standard"
}Video Guide
A step-by-step walkthrough of authentication and setup, followed by three real integrations: calling the API directly with Python, wiring it into a Lovable app, and using it with Claude.
Authentication
All API requests require a Bearer token in the Authorization header. You can create and manage API keys from your dashboard.
Authorization: Bearer wh_live_your_api_key_here
Keys use the prefix wh_live_ followed by a unique token. Keep your keys secret — treat them like passwords. You can create up to 5 keys and revoke any key at any time.
Plans & Limits
Choose a plan that fits your usage. All plans include monthly word allowances that reset each billing cycle.
| Standard | Premium | |
|---|---|---|
| Monthly words | 125,000 | 400,000 – 3,000,000 |
| Max words per request | 2,000 | 4,000 – 6,000 |
| Output variations | 1 | 3 |
| Human-likeness scores | ||
| Rate limit | 40 req/min | 120 – 160 req/min |
Standard
Premium
Premium plans automatically return 3 output variations per request with human-likeness scores. Standard plans return a single result without scores. Usage is tracked by input-text word count. Words are deducted from your subscription first, then any top-up credits. Top-up packs never expire. Premium 400K allows 4,000 words per request and 120 requests per minute; 800K and up allow 6,000 and 160.
Errors
Errors return JSON with a code that says what went wrong and an error message for people. A 429, 503 or 504 comes with a Retry-After header: wait that many seconds, then retry.
| Status | code | Meaning |
|---|---|---|
| 422 | invalid_request | The body failed validation (missing text, too short or too long). |
| 422 | forbidden_param | A parameter that is not available on the public API was sent. |
| 422 | word_limit | The input is over the per-request word cap for your plan. |
| 422 | moderation_blocked | Content moderation refused the input (/v1/humanize only). |
| 401 | missing_api_key | No usable Authorization: Bearer header. |
| 401 | invalid_api_key | The key is unknown or revoked. |
| 402 | no_subscription | The key is valid but the account has no active API subscription. |
| 402 | insufficient_balance | Not enough words left for this request; words_remaining is included. |
| 403 | enhanced_requires_premium | enhanced: true was sent on a Standard plan. upgrade_url links to the plans. Nothing charged. |
| 403 | enhanced_unavailable | enhanced: true was sent while the enhanced model is switched off. Send the request without enhanced. Nothing charged. |
| 403 | reverify_required | The account must be re-verified by email. The account owner signs in at writehuman.ai to continue; then the account's newest key created after the check began works within about a minute; every other key stays disabled until the check ends, so create a new key. |
| 429 | rate_limited | Over your plan's requests per minute. Retry-After is the time to the next window. |
| 429 | auth_locked_out | Too many failed authentications from this address. Retry-After is the remaining lockout. |
| 429 | queue_full | The admission queue is full. Retry after Retry-After. |
| 429 | queue_timeout | The request waited in the admission queue past its deadline. Retry after Retry-After. |
| 503 | at_capacity | Cluster-wide capacity shed. Retry after Retry-After. |
| 503 | billing_unavailable | The billing store is unreachable; the request was refused rather than served unmetered. Retry after Retry-After. |
| 503 | detector_unavailable | The detector, or the translation step before it, is unavailable (/v1/detect only). Retry after Retry-After. |
| 504 | timeout | Generation did not finish within the server deadline (/v1/humanize only). Nothing charged; retry after Retry-After. |
| 500 | processing_failed | Generation raised an error. |
| 500 | no_results | Generation finished without a usable result. |
| 500 | safety_limit | Generation produced far more text than the input; discarded. |
| 500 | billing_failed | The result was produced but the usage write failed part-way; included and/or top-up words may already have been charged. Check /v1/usage. |
Endpoint Reference
Three REST endpoints, one base URL, and one Bearer key. All requests authenticate the same way.
/v1/humanizehttps://api.writehuman.ai/v1/humanize
text, tone, language, and enhanced. Premium plans can set enhanced: true for our enhanced model at the same word rate; the model field of the response says which model served it.Request Body — application/json
textrequiredThe text to humanize.
>= 30 characters, <= 100,000 characters
toneoptionalOptional writing tone. Omit for default style.
Allowed: professional, academic, blog, casual, creative, scientific, technical
languageoptionalTarget language (e.g. English, Spanish, Chinese (Mandarin)). Auto-detected if omitted.
enhancedoptionalServe this request with our enhanced model, at the same word rate.
Default: false
Premium plans and above. On a Standard plan true returns 403 enhanced_requires_premium with an upgrade_url; while the enhanced model is switched off it returns 403 enhanced_unavailable.
Response Body — application/json
idUnique identifier for this humanization request.
createdUnix timestamp (milliseconds) when the request was received.
resultsHumanized text variations, sorted by score (best first).
scoresHuman-likeness score for each result (0–1, higher = more human).
Premium plans only. null on Standard plans.
input_wordsNumber of words billed for this request.
words_remainingYour remaining word balance after this request.
Fields: included (integer), topup (integer), total (integer)
modelWhich model served the request.
Allowed: standard, enhanced
Error Responses
Missing or invalid API key.
Invalid API key
{
"error": "Invalid API key",
"code": "invalid_api_key"
}Missing Authorization header
{
"error": "Missing or invalid Authorization header. Use: Bearer <api_key>",
"code": "missing_api_key"
}No active subscription or insufficient word balance.
No active subscription
{
"error": "No active subscription",
"code": "no_subscription"
}Insufficient word balance
{
"error": "Insufficient word balance",
"code": "insufficient_balance",
"words_remaining": {
"included": 12,
"topup": 0,
"total": 12
}
}The request was refused before anything ran, and nothing was charged. The code says why.
enhanced on a Standard plan
{
"error": "The enhanced parameter requires a Premium plan or above",
"code": "enhanced_requires_premium",
"upgrade_url": "https://writehuman.ai/api#pricing"
}The enhanced model is switched off
{
"error": "The enhanced model is not available right now",
"code": "enhanced_unavailable"
}Account must be re-verified
{
"error": "This account must be re-verified by email. The account owner should sign in at writehuman.ai to continue.",
"code": "reverify_required"
}Invalid input, forbidden parameters, over word limit, or content blocked by moderation.
Invalid request body
{
"error": "Invalid request: ...",
"code": "invalid_request"
}model is not available on the public API
{
"error": "The model parameter is not available",
"code": "forbidden_param"
}num_outputs is not available on the public API
{
"error": "The num_outputs parameter is not available",
"code": "forbidden_param"
}sequence_id is not available on the public API
{
"error": "The sequence_id parameter is not available",
"code": "forbidden_param"
}Over word limit
{
"error": "Input exceeds per-request limit of 2000 words for your plan. Received ~2500 words.",
"code": "word_limit"
}Content blocked
{
"error": "Content blocked: sexual",
"code": "moderation_blocked"
}Rate limit, queue capacity, or too many failed auth attempts.
Rate limited
{
"error": "Rate limit exceeded for your plan (api_standard -> 40/min). api_standard: 40/min | api_premium: 120/min | api_premium 800K+: 160/min",
"code": "rate_limited"
}Too many failed auth attempts
{
"error": "Too many failed authentication attempts",
"code": "auth_locked_out"
}Request queue full
{
"error": "Too many queued requests. Please retry shortly.",
"code": "queue_full"
}Queue wait timeout
{
"error": "Request waited too long for capacity. Please retry.",
"code": "queue_timeout"
}Processing failure. No words charged, except that billing_failed may have charged some of the request's words (included and/or top-up) before the usage write failed.
Generation failed
{
"error": "Processing failed",
"code": "processing_failed"
}Generation returned nothing usable
{
"error": "Processing returned no results",
"code": "no_results"
}Output exceeded the safety limit
{
"error": "Output exceeded safety limit",
"code": "safety_limit"
}Billing update failed after generation
{
"error": "Billing update failed",
"code": "billing_failed"
}Service at capacity, or billing temporarily unavailable. No words charged.
Service at capacity
{
"error": "Service is at capacity. Please retry shortly.",
"code": "at_capacity"
}Billing temporarily unavailable
{
"error": "Service temporarily unavailable, please retry shortly.",
"code": "billing_unavailable"
}The request did not finish within the server deadline (170 seconds from request entry; generation is stopped once 10 seconds remain so that billing is never cut part-way). No words charged; safe to retry.
{
"error": "Processing did not finish within 160 seconds. Nothing was charged; please retry.",
"code": "timeout"
}/v1/usagehttps://api.writehuman.ai/v1/usage
included_words − words_used_this_cycle + topup_balance.Response Body — application/json
included_wordsWords included in your plan each billing cycle.
words_used_this_cycleWords used so far in the current billing cycle.
topup_balanceRemaining top-up words. Top-up packs never expire.
tierYour plan: api_standard or api_premium.
versionCurrent API version.
{
"included_words": 400000,
"words_used_this_cycle": 18311,
"topup_balance": 100000,
"tier": "api_premium",
"version": "v1.2"
}Error Responses
Missing or invalid API key.
Invalid API key
{
"error": "Invalid API key",
"code": "invalid_api_key"
}Missing Authorization header
{
"error": "Missing or invalid Authorization header",
"code": "missing_api_key"
}No active subscription (HTTP 402).
{
"error": "No active subscription",
"code": "no_subscription"
}The account owner must re-verify the account by email. Nothing is charged.
{
"error": "This account must be re-verified by email. The account owner should sign in at writehuman.ai to continue.",
"code": "reverify_required"
}Too many failed auth attempts.
{
"error": "Too many failed authentication attempts",
"code": "auth_locked_out"
}/v1/detecthttps://api.writehuman.ai/v1/detect
/v1/humanize. Non-English input is automatically translated to English before scoring. Set include_sentences to true for a per-sentence breakdown. Note: ai_probability runs 0–1 where 1 = AI — the opposite orientation of the humanize scores field.Request Body — application/json
textrequiredThe text to score for AI authorship.
>= 10 characters, <= 100,000 characters
languageoptionalLanguage of the text. Auto-detected if omitted; non-English text is translated to English before scoring.
include_sentencesoptionalReturn a per-sentence AI-probability breakdown.
Default: false
Response Body — application/json
scanIdUnique identifier for this detection scan.
versionDetector model version.
versionIDDetector build identifier.
ai_probabilityProbability the text is AI-generated (0–1, where 1 = AI).
Opposite orientation from the /v1/humanize scores field, where higher = more human.
predicted_classOverall label: ai, human, or mixed.
class_probabilitiesProbability for each class.
Fields: ai, human, mixed
request_metaLength of the scored text.
doc_length: { chars, tokens }
languageDetected (or supplied) language of the input.
sentencesPer-sentence breakdown, each { text, ai_prob }.
Present only when include_sentences is true.
{
"scanId": "20260609OMIOISUZ",
"version": "txtdetect-2026-05-14",
"versionID": "V1.1.1",
"ai_probability": 0.94,
"predicted_class": "ai",
"class_probabilities": { "ai": 0.94, "human": 0.04, "mixed": 0.02 },
"request_meta": { "doc_length": { "chars": 642, "tokens": 98 } },
"language": "English",
"sentences": [
{ "text": "Artificial intelligence has rapidly transformed modern business.", "ai_prob": 0.97 },
{ "text": "Many teams now depend on it every single day.", "ai_prob": 0.61 }
]
}Error Responses
Missing or invalid API key.
Invalid API key
{
"error": "Invalid API key",
"code": "invalid_api_key"
}Missing Authorization header
{
"error": "Missing or invalid Authorization header",
"code": "missing_api_key"
}No active subscription or insufficient word balance.
No active subscription
{
"error": "No active subscription",
"code": "no_subscription"
}Insufficient word balance
{
"error": "Insufficient word balance",
"code": "insufficient_balance",
"words_remaining": {
"included": 12,
"topup": 0,
"total": 12
}
}The account owner must re-verify the account by email. Nothing is charged.
{
"error": "This account must be re-verified by email. The account owner should sign in at writehuman.ai to continue.",
"code": "reverify_required"
}Invalid input or over the per-request word limit.
Invalid request body
{
"error": "Invalid request: ...",
"code": "invalid_request"
}Over word limit
{
"error": "Input exceeds per-request limit of 2000 words for your plan. Received ~2500 words.",
"code": "word_limit"
}Rate limit or too many failed auth attempts.
Rate limited
{
"error": "Rate limit exceeded for your plan (api_standard -> 40/min). api_standard: 40/min | api_premium: 120/min | api_premium 800K+: 160/min",
"code": "rate_limited"
}Too many failed auth attempts
{
"error": "Too many failed authentication attempts",
"code": "auth_locked_out"
}Billing update failure after a successful scan. Some of the request's words (included and/or top-up) may already have been charged before the write failed.
{
"error": "Billing update failed",
"code": "billing_failed"
}Detector unavailable or at capacity, translation failed, or billing temporarily unavailable. No words charged.
Detector unavailable, at capacity, or translation failed
{
"error": "Detection service unavailable. Please retry.",
"code": "detector_unavailable"
}Billing temporarily unavailable
{
"error": "Service temporarily unavailable, please retry shortly.",
"code": "billing_unavailable"
}Code Examples
Full working examples in popular languages. Replace the API key with your own to get started.
Official SDKs: TypeScript / JavaScript @writehuman/sdk and Python writehuman. Both follow the documented retry policy: a 429, 503 or 504 is retried after the API's Retry-After, at most 2 retries and only when the wait is 60 s or less (both defaults); a longer Retry-After, such as an authentication lockout, is not waited for and the error surfaces at once with it as retry_after / retryAfter. A request that may have been charged is never resent.
// npm install @writehuman/sdk
import { WriteHuman } from "@writehuman/sdk";
const wh = new WriteHuman({ apiKey: "wh_live_your_api_key_here" });
const out = await wh.humanize("Artificial intelligence has revolutionized the way we approach content creation and digital communication.");
console.log(out.results[0]);
console.log(out.words_remaining.total, "words left");Response
The response format depends on your plan.
{
"id": "hum_a1b2c3d4e5f6",
"created": 1778533901580,
"results": [
"AI has changed how we create content and communicate online."
],
"scores": null,
"input_words": 14,
"words_remaining": {
"included": 124986,
"topup": 0,
"total": 124986
},
"model": "standard"
}Supported Languages
WriteHuman supports 40+ languages. Pass the language name as the language parameter, or omit it for automatic detection.
Common Use Cases
Content Marketing
Generate blog posts, product descriptions, and ad copy with AI that reads indistinguishable from human writing.
SEO Agencies
Produce high-volume content that passes AI detection checks before publication.
SaaS Products
AI writing features where the final output needs to be indistinguishable from human writing.
Enterprise Teams
Process internal communications, reports, and documentation generated by large language models.
Support
By using the WriteHuman API you agree to our Terms of Service.