New November 3: Enhanced model updated for GPTZero and Pangram
API Reference v1.2

AI Humanizer API Documentation

Humanize AI-generated text, detect AI authorship, and track usage through a simple REST API. Simple authentication, predictable pricing, 40+ languages.

Base URLhttps://api.writehuman.ai
View Pricing
Starting at$0.14/ 1K words
Watch Video Guide

Quickstart

Get up and running in under a minute.

1

Get your API key

Sign up or log in at writehuman.ai, purchase an API subscription, and create your key from the dashboard.

2

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");
3

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

Monthly words125,000
Max words per request2,000
Output variations1
Human-likeness scores
Rate limit40 req/min

Premium

Monthly words400,000 – 3,000,000
Max words per request4,000 – 6,000
Output variations3
Human-likeness scores
Rate limit120 – 160 req/min

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.

StatuscodeMeaning
422invalid_requestThe body failed validation (missing text, too short or too long).
422forbidden_paramA parameter that is not available on the public API was sent.
422word_limitThe input is over the per-request word cap for your plan.
422moderation_blockedContent moderation refused the input (/v1/humanize only).
401missing_api_keyNo usable Authorization: Bearer header.
401invalid_api_keyThe key is unknown or revoked.
402no_subscriptionThe key is valid but the account has no active API subscription.
402insufficient_balanceNot enough words left for this request; words_remaining is included.
403enhanced_requires_premiumenhanced: true was sent on a Standard plan. upgrade_url links to the plans. Nothing charged.
403enhanced_unavailableenhanced: true was sent while the enhanced model is switched off. Send the request without enhanced. Nothing charged.
403reverify_requiredThe 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.
429rate_limitedOver your plan's requests per minute. Retry-After is the time to the next window.
429auth_locked_outToo many failed authentications from this address. Retry-After is the remaining lockout.
429queue_fullThe admission queue is full. Retry after Retry-After.
429queue_timeoutThe request waited in the admission queue past its deadline. Retry after Retry-After.
503at_capacityCluster-wide capacity shed. Retry after Retry-After.
503billing_unavailableThe billing store is unreachable; the request was refused rather than served unmetered. Retry after Retry-After.
503detector_unavailableThe detector, or the translation step before it, is unavailable (/v1/detect only). Retry after Retry-After.
504timeoutGeneration did not finish within the server deadline (/v1/humanize only). Nothing charged; retry after Retry-After.
500processing_failedGeneration raised an error.
500no_resultsGeneration finished without a usable result.
500safety_limitGeneration produced far more text than the input; discarded.
500billing_failedThe 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.

POST/v1/humanize

https://api.writehuman.ai/v1/humanize

Rewrite AI-generated text so it reads as naturally human. Billed by input word count, from your monthly allowance first, then top-up credits. The API accepts 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

textrequired
string

The text to humanize.

>= 30 characters, <= 100,000 characters

toneoptional
string

Optional writing tone. Omit for default style.

Allowed: professional, academic, blog, casual, creative, scientific, technical

languageoptional
string | null

Target language (e.g. English, Spanish, Chinese (Mandarin)). Auto-detected if omitted.

enhancedoptional
boolean

Serve 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.

200Text humanized successfully

Response Body — application/json

id
string

Unique identifier for this humanization request.

created
integer

Unix timestamp (milliseconds) when the request was received.

results
string[]

Humanized text variations, sorted by score (best first).

scores
(number | null)[] | null

Human-likeness score for each result (0–1, higher = more human).

Premium plans only. null on Standard plans.

input_words
integer

Number of words billed for this request.

words_remaining
object

Your remaining word balance after this request.

Fields: included (integer), topup (integer), total (integer)

model
string

Which model served the request.

Allowed: standard, enhanced

Error Responses

401

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"
}
402

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
  }
}
403

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"
}
422

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"
}
429

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"
}
500

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"
}
503

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"
}
504

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"
}

GET/v1/usage

https://api.writehuman.ai/v1/usage

Retrieve your current word usage, plan tier, and API version. Read-only — it never deducts words. Remaining balance = included_words − words_used_this_cycle + topup_balance.
200Usage returned

Response Body — application/json

included_words
integer

Words included in your plan each billing cycle.

words_used_this_cycle
integer

Words used so far in the current billing cycle.

topup_balance
integer

Remaining top-up words. Top-up packs never expire.

tier
string

Your plan: api_standard or api_premium.

version
string

Current API version.

{
  "included_words": 400000,
  "words_used_this_cycle": 18311,
  "topup_balance": 100000,
  "tier": "api_premium",
  "version": "v1.2"
}

Error Responses

401

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"
}
402

No active subscription (HTTP 402).

{
  "error": "No active subscription",
  "code": "no_subscription"
}
403

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"
}
429

Too many failed auth attempts.

{
  "error": "Too many failed authentication attempts",
  "code": "auth_locked_out"
}

POST/v1/detect

https://api.writehuman.ai/v1/detect

Score text for AI authorship using WriteHuman's detection model. Billed per input word (the original text), the same way as /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

textrequired
string

The text to score for AI authorship.

>= 10 characters, <= 100,000 characters

languageoptional
string | null

Language of the text. Auto-detected if omitted; non-English text is translated to English before scoring.

include_sentencesoptional
boolean

Return a per-sentence AI-probability breakdown.

Default: false

200Text scored successfully

Response Body — application/json

scanId
string | null

Unique identifier for this detection scan.

version
string | null

Detector model version.

versionID
string | null

Detector build identifier.

ai_probability
number | null

Probability the text is AI-generated (0–1, where 1 = AI).

Opposite orientation from the /v1/humanize scores field, where higher = more human.

predicted_class
string | null

Overall label: ai, human, or mixed.

class_probabilities
object

Probability for each class.

Fields: ai, human, mixed

request_meta
object

Length of the scored text.

doc_length: { chars, tokens }

language
string

Detected (or supplied) language of the input.

sentences
array

Per-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

401

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"
}
402

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
  }
}
403

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"
}
422

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"
}
429

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"
}
500

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"
}
503

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.

EnglishChinese (Mandarin)Chinese (Taiwan)FrenchSpanishVietnamesePortugueseJapaneseUkrainianSwedishGermanRussianItalianArabicHindiBengaliKoreanTurkishDutchPolishThaiIndonesianMalayPersianHebrewGreekCzechDanishFinnishNorwegianRomanianHungarianSlovakBulgarianCroatianSerbianSlovenianLithuanianLatvianEstonianUrduSwahiliTagalogAfrikaans

Common Use Cases


Support

By using the WriteHuman API you agree to our Terms of Service.