> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stealthgpt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Text Preservation

> Keep links, HTML, headings and other marked spans unchanged while the rest of the text is humanized

Send `preservation: true` and mark every span that must not change with a marker such as `[[T1]]`. Everything outside the markers is humanized. Every marker comes back byte-for-byte, in the same order. It works on [`POST /api/stealthify`](https://docs.stealthgpt.ai/api-reference/endpoints/stealthify) and [`POST /api/stealthify/runs`](https://docs.stealthgpt.ai/api-reference/endpoints/stealthify-runs) with `rephrase: true`.

```json theme={null}
{
  "prompt": "Hello [[T1]], how are you?",
  "rephrase": true,
  "model": "super",
  "preservation": true
}
```

returns something like:

```json theme={null}
{
  "result": "Greetings [[T1]], how have you been?",
  "preservation": { "frozenCount": 1, "preservedCount": 1, "mode": "inline", "fallbackUsed": false }
}
```

The marker text itself is always copied from your input, never from the model.

## What counts as a marker

A marker is `[[`, then at most 10 characters, then `]]`. `[[T1]]`, `[[LINK_3]]` and `[[/a]]` are markers. A `[[` with no `]]` within those 10 characters is ordinary text and is humanized like the rest. Markers can sit anywhere: mid-sentence, around link text, next to each other, or at the start or end of the text.

For HTML, replace each tag or link with a unique marker on your side, send the text, then swap the markers back:

```text theme={null}
Read [[A1]]our pricing guide[[A2]] before you buy.
```

The text between two markers (link text, a heading) is humanized too. To keep a whole span unchanged, replace the entire span with a single marker.

## Parameters

| Parameter | Type | Default | Description |
| - | - | - | - |
| `preservation` | boolean | `false` | Turns preservation on. Requires `rephrase: true` |
| `preservationOpen` | string | `[[` | Opening delimiter, 1-10 characters, no spaces |
| `preservationClose` | string | `]]` | Closing delimiter, 1-10 characters, no spaces, different from the opening one |
| `preservationMaxLookahead` | number | `10` | Most characters allowed between the delimiters (1-64) |
| `preservationMode` | string | `inline` | `inline` or `split`, see below |

## Modes

**`inline`** (default): the markers are swapped for placeholders and the text is rewritten in one pass, so sentences keep their flow. Every placeholder has to come back once and in order. If one doesn't, that text falls back to `split`.

With `super`, `inline` works differently: the markers never go to the model. The whole text is rewritten in one pass without them, and the rewrite is put back around the markers sentence by sentence:

* A marker on its own line, or between two sentences, stays exactly where it was.
* A short heading or label right before a marker between sentences, like `Beach.[[T1]] Sand and water` or `Meal Prep Tip:[[T2]] Cook a big batch`, stays as you wrote it: up to 8 words from the start of the line or the previous marker, 12 if it ends in a colon.
* A sentence with a marker inside it is rewritten on its own with the marker held in place. If the model can't keep it, that sentence stays as you wrote it.

This keeps most of the detection-bypass of a plain `super` rewrite. For the best results, put markers for headings and other blocks on their own line or between sentences.

**`split`**: every stretch of text between two markers is rewritten on its own and the markers are put back between them. It never depends on the model keeping a placeholder, but short fragments read choppier and are easier to detect. A stretch of fewer than 3 words stays as it is.

In both modes, punctuation and spacing next to a marker are kept. If the rewrite of `Hello [[T1]], how` drops the comma, it comes back.

## Response

With `preservation: true`, the response (and the completed run status) includes:

**preservation** `object`

**properties**

**frozenCount** `number`

Markers found in the input.

**preservedCount** `number`

Markers returned unchanged. Always equal to `frozenCount` in a successful response.

**mode** `string`

The mode you asked for: `inline` or `split`. `fallbackUsed` tells you when `inline` fell back.

**fallbackUsed** `boolean`

In `inline` mode, `true` when the text fell back to `split`. Always `false` in `split` mode.

If the markers can't be returned unchanged, the request fails instead of returning a broken text: `500` on `POST /api/stealthify`, a `failed` run on `POST /api/stealthify/runs`. Nothing is charged for a failed request.

## Billing and limits

Words inside markers are not billed. The 3,000-word limit of `POST /api/stealthify` still counts the whole text, markers included.

> [!WARNING]
>
> Preserving text can reduce detection-bypass scores, because frozen text is not humanized. Placeholders in the text also cost some bypass, which is why `super` leaves them out. `split` mode, and `inline` after it falls back to `split`, rewrite short fragments on their own, which bypass detectors less well than one pass over the whole text. `fallbackUsed: true` tells you when that happened.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.