Developer API

WriteTone API

The same humanizer, paraphraser, grammar fixer and AI detector that run writetone.com, as a simple REST API. Same engine, same results.

// Quick start example
const response = await fetch('https://api.writetone.com/api/v1/humanize', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'your_api_key'
  },
  body: JSON.stringify({
    text: 'Your AI-generated text here...',
    level: 'advanced'
  })
});

const data = await response.json();
console.log(data.data.humanizedText, data.data.aiScore);

API Pricing

Simple plans. Every plan includes every endpoint. Yearly billing = 2 months free.

Starter

$9/month
or $90/year
100,000 characters/month
  • ~25,000 words/month
  • 10 requests/min
  • All endpoints

Business

$129/month
or $1,290/year
5,000,000 characters/month
  • ~1,250,000 words/month
  • 120 requests/min
  • All endpoints

Enterprise

Custom
Monthly or yearly
Custom volume
  • Custom character volume
  • Custom rate limit
  • All endpoints
Contact Us
  • What counts: paraphrase and grammar count the characters of the text returned; humanize counts the first version returned; detect counts the characters of the text checked.
  • Monthly allowance, hard stop: no free trial and no overage. When the month's characters are used up, requests stop with MONTHLY_LIMIT_REACHED until the allowance renews or you upgrade.
  • Yearly plans: billed once a year, but the allowance is still monthly. Unused characters don't carry over.

Why Use WriteTone API?

The tools writetone.com users rely on, with a simple integration

AI Humanizer

Make AI-generated text read naturally; the Advanced level also returns an AI score

Paraphraser

Rewrite in any tone, or as a subject expert, keeping the meaning

Grammar Fix

Fix grammar, spelling and punctuation while keeping your voice

AI Detector

AI score, verdict and a per-sentence breakdown for any text

Same Results as WriteTone

The same humanizer, paraphraser, grammar and AI detector as writetone.com

Freeze Words

Keep names, terms and quoted text exactly as written

50+ Languages

Humanize, paraphrase and grammar detect the language and answer in it

Fast

Paraphrase and grammar in seconds; humanize in under a minute

Secure

HTTPS only; your API key never leaves your server

API Endpoints

Base URL https://api.writetone.com - JSON in, JSON out

Basics
  • Send your API key in the X-API-Key header. POST endpoints take a JSON body (Content-Type: application/json).
  • Every success has the shape { success: true, data, usage: { charactersUsed, remaining } }.
  • Every error has the shape { success: false, error: <CODE>, message } - see Error codes.
Success
{
  "success": true,
  "data": { ... },
  "usage": { "charactersUsed": 412, "remaining": 99588 }
}
Error
{
  "success": false,
  "error": "MONTHLY_LIMIT_REACHED",
  "message": "This month's characters are used up. ...",
  "upgradeUrl": "https://writetone.com/api-docs#pricing"
}
POST /api/v1/humanize

Make AI-generated text read like a person wrote it. Advanced checks its result with the AI detector and tries once more with another strategy if needed. Counted: the first version returned.

FieldTypeDescription
textstring, required30 to 1,550 words.
levelstring"advanced" (default) or "balanced".
strategystring"auto" (default), "academic", "business", "casual", "creative" or "technical".
response_countnumber1 (default) or 2 - two different versions; only the first is counted.
frozenstring[], optionalWords or phrases kept exactly as written (up to 30, each up to 60 characters).
keepQuotesboolean, optionaltrue keeps text in "double quotes" unchanged.
Request Body
{
  "text": "Your text to humanize...",
  "level": "advanced",
  "strategy": "auto",
  "response_count": 1,
  "frozen": ["WriteTone"],
  "keepQuotes": true
}
Response
{
  "success": true,
  "data": {
    "humanizedText": "...",
    "versions": ["..."],   // 2 strings when response_count = 2
    "level": "advanced",
    "strategy": "auto",    // the strategy used
    "language": "English",
    "aiScore": 12,         // advanced only: 0-100, lower = more human; may be null
    "aiScores": [12],      // one per version
    "attempts": 1          // 2 when it tried again
  },
  "usage": { "charactersUsed": 412, "remaining": 99588 }
}
POST /api/v1/paraphrase

Rewrite text in a different tone while keeping its meaning. Counted: the characters of the text returned.

FieldTypeDescription
textstring, required3 to 1,550 words.
tonestringDefault "normal". The website's tones: simple, normal, formal, informal, casual, academic, shorter, longer, subtle, human, ceo - or any other tone word, e.g. "persuasive", "friendly", "witty" (like the website's More Tones list).
subjectstring, optionalRewrite as a subject expert, e.g. "biology". frozen and keepQuotes don't apply to a subject rewrite.
frozenstring[], optionalWords or phrases kept exactly as written (up to 30, each up to 60 characters).
keepQuotesboolean, optionaltrue keeps text in "double quotes" unchanged.
Request Body
{
  "text": "Your text to paraphrase...",
  "tone": "formal",
  "subject": "biology",
  "frozen": ["CRISPR"]
}
Response
{
  "success": true,
  "data": {
    "paraphrasedText": "...",
    "language": "English",
    "tone": "formal",
    "subject": "biology"   // null when not set
  },
  "usage": { "charactersUsed": 395, "remaining": 99605 }
}
POST /api/v1/grammar

Fix grammar, spelling and punctuation while keeping your wording. Counted: the characters of the text returned.

FieldTypeDescription
textstring, required3 to 1,550 words.
frozenstring[], optionalWords or phrases kept exactly as written (up to 30, each up to 60 characters).
keepQuotesboolean, optionaltrue keeps text in "double quotes" unchanged.
Request Body
{
  "text": "Your text with grammer errors..."
}
Response
{
  "success": true,
  "data": {
    "correctedText": "Your text with grammar errors...",
    "language": "English"
  },
  "usage": { "charactersUsed": 32, "remaining": 99968 }
}
POST /api/v1/detect

Check whether a text was written by AI - the same detector as the website's AI Detector, built for English text. Counted: the characters of the text checked.

FieldTypeDescription
textstring, required100 to 15,000 characters.
Request Body
{
  "text": "Text to check for AI..."
}
Response
{
  "success": true,
  "data": {
    "aiScore": 72,         // 0-100, higher = more likely AI
    "humanScore": 28,
    "verdict": "Likely AI-generated",
    "confidence": 64,
    "wordCount": 212,
    "sentences": [
      { "text": "...", "aiScore": 81, "label": "ai" },  // "ai" | "mixed" | "human"
      { "text": "...", "aiScore": 22, "label": "human" }
    ]
  },
  "usage": { "charactersUsed": 1342, "remaining": 98658 }
}
GET /api/v1/usage

Your characters used and remaining this month, and your plan.

Request Headers
X-API-Key: your_api_key
Response
{
  "success": true,
  "usage": {
    "used": 25000,
    "limit": 100000,       // null on Enterprise
    "remaining": 75000
  },
  "plan": {
    "tier": "starter",
    "name": "Starter",
    "rateLimit": "10 requests/minute"
  }
}
GET /api/v1/pricing

All API plans. No authentication required.

Response
{
  "success": true,
  "pricing": [
    { "id": "starter", "name": "Starter", "priceMonthly": 9, "priceYearly": 90,
      "charactersPerMonth": 100000, "approximateWords": 25000, "rateLimit": "10 requests/minute" },
    // ... pro, business, custom (Enterprise: prices null, limits "custom")
  ],
  "notes": {
    "characterCounting": "Characters of the text returned (paraphrase, grammar, the first humanized version) or checked (detect).",
    "allowance": "Monthly, also on yearly plans; unused characters do not carry over. Requests stop when it is used up.",
    "yearly": "Yearly billing = 2 months free."
  }
}
GET /health

Health check to verify the API is up. No authentication required.

Response
{
  "status": "healthy",
  "service": "WriteTone API",
  "version": "2.0.0",
  "timestamp": "2026-10-16T12:00:00.000Z"
}
Error codes
errorHTTPMeaning
API_KEY_MISSING401No X-API-Key header.
API_KEY_INVALID401The key is wrong, revoked or has no active plan.
MONTHLY_LIMIT_REACHED403This month's characters are used up. The response includes upgradeUrl.
RATE_LIMITED429Too many requests per minute for your plan. Wait and retry.
INVALID_REQUEST400A missing or invalid field (e.g. text, level, strategy, frozen).
INVALID_LENGTH400The text is shorter or longer than the endpoint allows.
CONTENT_BLOCKED400The content filter refused the text.
SERVICE_UNAVAILABLE503A service is temporarily unavailable. Retry shortly.
PROCESSING_ERROR500Processing failed. Retry the request.

Try It Now

Test your API key and see the endpoints in action. Calls count toward your plan.

Don't have an API key? Create a developer account and choose a plan to get one.
Output will appear here...

Code Examples

Get started quickly with examples in your favorite language

// JavaScript / Node.js 18+
async function writetone(endpoint, body) {
  const response = await fetch(`https://api.writetone.com/api/v1/${endpoint}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.WRITETONE_API_KEY
    },
    body: JSON.stringify(body)
  });

  const data = await response.json();
  if (!data.success) throw new Error(`${data.error}: ${data.message}`);
  return data;
}

// Humanize (30-1,550 words), keeping a brand name exactly as written
const { data, usage } = await writetone('humanize', {
  text: 'Your AI text here...',
  level: 'advanced',
  strategy: 'auto',
  frozen: ['WriteTone']
});
console.log(data.humanizedText, data.aiScore, usage.remaining);

// Check a text for AI (100-15,000 characters)
const check = await writetone('detect', { text: 'Text to check...' });
console.log(check.data.verdict, check.data.aiScore);

Ready to Get Started?

Create your developer account, choose a plan from $9/month and start using the API today

Create Developer Account