Developer API

Build document humanization into your product.

Submit DOCX files, follow each job, receive signed completion events, and return the final file through your own website.

Live request
200 OK
POST /v1/submit
x-api-key: tw_live_••••••••
file: thesis.docx
service: humanize_only
{ "job_id": "job_8f3a…", "status": "queued" }

01 · Setup

Start in four steps

1

Choose an API package

Buy a package with API access enabled.

2

Create your key

Generate it once from the API keys page.

3

Submit a DOCX

Authenticate with the x-api-key header.

4

Receive the result

Poll the job or listen for a signed webhook.

https://truewriter.ai/api/public/v1
DOCX only400–29,000 words60 requests/minute by default

02 · Reference

Four endpoints, one simple flow

Every request uses your live API key. Job status and downloads are isolated to the key that created the job.

POST/v1/submit
Send multipart form data with file, optional service, and optional reference and email. If service is omitted, humanize_only is used. One document is deducted after validation.
GET/v1/status/{job_id}
Status is one of queued, processing, completed or failed. Poll every 20–30 seconds, or use a webhook instead.
GET/v1/download/{job_id}
Request file=result, file=source or file=report&index=0 (index 0 = before, 1 = after). The returned link lasts 10 minutes.
GET/v1/balance
View every active API-enabled package and its remaining document balance.

Service values

humanize_only

Humanize only

humanize_first

Humanize, then check

standard

Check, humanize, check

03 · Responses

Exactly what each call returns

All responses are JSON. Errors always return { error: string } with the status codes listed below.

POST /v1/submit · 200
{
  "job_id": "9f1c3b6e-…",
  "status": "queued",
  "words": 2400,
  "service": "humanize_only"
}
GET /v1/status/{job_id} · 200
{
  "job_id": "9f1c3b6e-…",
  "reference": "order-1024",
  "status": "processing",
  "service": "humanize_only",
  "file_name": "paper.docx",
  "ai_score_before": 88,
  "ai_score_after": null,
  "similarity_score": null,
  "reports_available": 1,
  "result_ready": false,
  "created_at": "2026-09-22T18:04:11Z",
  "completed_at": null
}
GET /v1/download/{job_id} · 200
{
  "url": "https://…signed-link…",
  "expires_in": 600,
  "file_name": "Humanized_paper.docx"
}
GET /v1/balance · 200
{
  "packages": [
    {
      "package": "Humanize only",
      "service": "humanize_only",
      "api_access": true,
      "documents_total": 10,
      "documents_used": 2,
      "documents_remaining": 8,
      "expires_at": "2026-10-20T00:00:00Z"
    }
  ],
  "documents_remaining": 8
}

04 · Examples

Submit your first document

Pick a language, or open Full flow for the complete submit → poll → download integration.

cURL · submit
curl -X POST https://truewriter.ai/api/public/v1/submit \
  -H "x-api-key: tw_live_xxxxxxxxxxxxxxxx" \
  -F "file=@paper.docx" \
  -F "service=humanize_only" \
  -F "reference=order-1024"

05 · Events

Know the moment a job finishes

Add a webhook URL to your API key from the API keys page, then copy the signing secret from the same card. We POST JSON and retry on failure.

Event

job.completed

Signature

HMAC-SHA256

Header

x-signature

Webhook payload
{
  "event": "job.completed",
  "job_id": "9f1c3b6e-…",
  "reference": "order-1024",
  "status": "ready",
  "file_name": "paper.docx",
  "ai_score_before": 88,
  "ai_score_after": 0,
  "similarity_score": 4,
  "sent_at": "2026-09-22T18:22:40Z"
}
Node · verify webhook
const crypto = require("crypto");

app.post("/truewriter-hook", rawJson, (req, res) => {
  const expected = crypto
    .createHmac("sha256", process.env.TRUEWRITER_WEBHOOK_SECRET)
    .update(req.rawBody)
    .digest("hex");

  if (req.get("x-signature") !== expected) {
    return res.status(401).end();
  }

  // Match your own order with "reference" (the value you sent
  // at submit time). "job_id" is TrueWriter's internal id.
  const { reference, status, ai_score_after } = req.body;
  res.status(200).end();
});

06 · Errors

Clear, predictable responses

400

Invalid request

Wrong file type, bad service value, or outside the 400–29,000 word range.

401

Authentication failed

The API key is missing, invalid or revoked.

402

Balance empty

No API documents remain on an eligible package for that service.

403

Request blocked

The domain or IP is not on the key's allow list, or the account is suspended.

404

Job not found

The job ID does not exist or belongs to a different API key.

409

File not ready

The requested result or report has not been produced yet.

429

Rate limited

The key exceeded its requests-per-minute limit.

503

Temporarily unavailable

Processing is paused for maintenance. Retry shortly.

Ready to connect your product?

Create a live key, restrict its origins, and send your first document.

Open API keys