Core concepts
Fidelity checks
How every number, unit, name and link is verified, and why the API fails closed.
Rewriting tools change facts. In our own lab test, a humanizer we tested turned “14 days” into “14 weeks” while making a support policy sound friendlier. Nobody would catch that in a skim.
Every rewrite here extracts the protected facts from your source, finds them in the output, and compares them. If one changed, the request fails closed: you get an error, not a confident-sounding wrong answer.
Source: Our lab test, Oct 2026.What gets checked
| Check | Examples | Rule |
|---|---|---|
number_unit | 14 days, $49/mo, 3.5%, 1.2M credits | Value and unit must match. 14 days ≠ 2 weeks: we don't let the model convert units. |
date | 2 Aug 2026, Q3, last Tuesday | Same date or period. Relative dates stay relative. |
name | people, companies, products | Exact spelling and casing. Pronoun substitution is allowed after first mention. |
link | URLs, email addresses, @handles | Byte-for-byte identical, including query strings. |
quote | text inside quotation marks | Quoted words are never paraphrased. |
preserve | your preserve list | Each string must appear verbatim in the output. |
Strict and standard modes
| fidelity | If a fact changes | Billed |
|---|---|---|
strict | Request fails with 422 fidelity_failed. No text is returned. | No |
standard | Text is returned with fidelity.status: "warn" and the changed facts listed. | Yes |
strict is the default and the right choice for anything published without a human reading every line. Use standard when an editor reviews the diff anyway and you'd rather fix one fact than re-run.
Fail closed: the 14 days example
Here is what the “14 days → 14 weeks” change looks like when it happens inside a strict rewrite:
{
"error": {
"type": "fidelity_error",
"code": "fidelity_failed",
"message": "1 protected fact changed between source and output. Nothing was billed.",
"request_id": "rw_01JD4R2N7P",
"changed_facts": [
{
"type": "number_unit",
"source": "14 days",
"output": "14 weeks",
"position": {
"start": 112,
"end": 119
}
}
],
"doc_url": "/docs/errors#fidelity_failed"
}
}The right response is to retry once (a fresh generation usually keeps the fact), then route the draft to a person. Don't loosen to standard automatically.
Reading the fidelity report
Successful rewrites list every check performed, so you can show reviewers what was verified:
{
"status": "pass",
"checks": [
{
"type": "number_unit",
"source": "14 days",
"output": "14 days",
"ok": true
},
{
"type": "link",
"source": "https://example.com/returns",
"output": "https://example.com/returns",
"ok": true
},
{
"type": "name",
"source": "Acme Support",
"output": "Acme Support",
"ok": true
}
],
"changed_facts": []
}Protecting extra strings
Some things aren't facts we can detect but still mustn't change: a legal sentence, a product tagline, a price written in words. Add them to preserve:
{
"text": "…",
"fidelity": "strict",
"preserve": [
"Terms apply.",
"Pro plan",
"free for 30 days"
]
}What fidelity checks don't do
Warning:
Fidelity checks guarantee the output says what the source said; they don't check that the source is true. Qualitative wording (“most” vs “many”) isn't a protected fact, so readstrength: "deep" rewrites of sensitive claims before publishing.