POST /api/humanize
The rewrite engine. Every client — the web app, the extension, curl — calls this one endpoint. Anthropic keys stay on the server; you never hold one.
Drafts are not stored.
Auth
Either:
- a session cookie, for same-origin browser calls, or
Authorization: Bearer hn_..., for everything else.
A Bearer header that is not a valid key returns 401. It does not fall through
to the anonymous allowance.
Create keys at rewr.it/account while signed in. The secret is shown once. Up to 5 active keys. Quota follows the key's owner.
Request
{
"text": "It is important to note that we should leverage this.",
"register": "email",
"mode": "rewrite",
"templateId": null,
"voiceProfileId": null,
"fromNotes": false,
"previousRewrite": "",
"protectedSpans": [],
"modelTier": "standard"
}
| Field | Required | Values |
|---|---|---|
text | yes | The draft, or the notes when fromNotes is true |
register | yes | slack | email | skip_level | linkedin |
mode | no | rewrite (default) | expand | vary | closer |
templateId | no | A custom template you own. Pro. Unresolvable ids fall back to register |
voiceProfileId | no | A voice profile you own. Unresolvable ids fall back to the default voice |
fromNotes | no | text is bullet notes, not a draft. Implied by mode: "expand" |
previousRewrite | for vary / closer | The prior rewrite. Not a source of new facts |
protectedSpans | no | Exact substrings to keep verbatim. Max 20, 4,000 characters |
modelTier | no | standard | fast | auto. Plan-gated |
fromNotes on a retryvary and closer describe what to do with the previous output and say
nothing about the input. Retrying an expansion must carry fromNotes: true, or
the server reads your notes as a draft.
Response
Content-Type: text/event-stream.
data: {"type":"delta","text":"We should "}
data: {"type":"delta","text":"look at this properly."}
data: {"type":"usage","plan":"pro","modelTier":"standard","inputTokens":12,"outputTokens":40,"requests":3,"fundingSource":"wallet","creditsUsed":2,"creditBalance":10998}
data: {"type":"done"}
Concatenate every delta.text. A trailing NOTES: block, if present, is the
model's commentary — split it off before showing the rewrite.
An error inside a stream that has already started arrives as an event:
data: {"type":"error","message":"Rewrite failed. Try again."}
An error before the stream starts is a JSON body with an HTTP status. See Errors.
Do not log the draft
The endpoint does not, and neither should your client. That is most of the privacy promise, and it is the one part of it that lives in your code rather than in ours.
CORS
Browser and extension callers send an Origin. Allowed:
NEXT_PUBLIC_APP_URLchrome-extension://<id>for each id inHUMANIZER_EXTENSION_IDS- anything in
HUMANIZER_CORS_ORIGINS - on loopback (
localhost,127.0.0.1,::1), anychrome-extension://<id>, so an unpacked build works againstnext devwithout configuring env
OPTIONS is implemented on /api/humanize and /api/usage. Production requires
ids in HUMANIZER_EXTENSION_IDS.
curl
curl -N https://rewr.it/api/humanize \
-H "Authorization: Bearer hn_..." \
-H "Content-Type: application/json" \
-d '{"text":"It is important to note that we should leverage this.","register":"email"}'
-N matters. Without it curl buffers and the stream looks like it hangs.