Clean Claude text
from code.
One endpoint. JSON in, cleaned text out. €0.0005 per request, billed separately from your web allowance.
01 / Start
Get a key in three steps.
- 1
Enable billing
Turn on metered API billing from your account. One Stripe checkout, then you are done.
- 2
Create a key
Generate a key on the same page. It starts with
cwr_and is shown once — copy it right away. - 3
Call the endpoint
Swap
YOUR_API_KEYinto any example below. Each successful request is metered.
02 / Examples
Copy, paste, run.
curl -X POST "https://removeclaudewatermark.net/v1/remove-watermark" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello\u200b world", "mode": "careful"}'
import requests
response = requests.post(
"https://removeclaudewatermark.net/v1/remove-watermark",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"text": "Hello\u200b world", "mode": "careful"},
timeout=60,
)
response.raise_for_status()
print(response.json()["text"])
const response = await fetch("https://removeclaudewatermark.net/v1/remove-watermark", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ text: "Hello\u200b world", mode: "careful" }),
});
if (!response.ok) throw new Error(await response.text());
const result = await response.json();
console.log(result.text);
{
"text": "Hello world",
"inspection_text": "Hello\u200b world",
"mode": "careful",
"input_characters": 12,
"output_characters": 11,
"removed_characters": 1,
"normalized": false,
"findings": [
{
"codepoint": "U+200B",
"tag": "ZWSP",
"label": "Zero-width space",
"note": "Invisible spacing character",
"count": 1,
"positions": [6],
"action": "removed",
"sensitive": false
}
],
"billing": {
"metered": true,
"price_eur_per_request": "0.0005",
"stripe_usage_record_id": "mbur_..."
}
}
The examples send \u200b, a zero-width space, so you can see a finding in the response. Cleaning plain text is valid and simply returns an empty findings array.
03 / Reference
Request and response fields.
Request body
| Field | Type | Notes |
|---|---|---|
text | string | Required. The Claude text to clean. The whole request body must stay under 2 MB. |
mode | string | Optional. careful (default) removes hidden Unicode only. thorough also rewrites the wording and accepts up to 20,000 characters. |
Response body
| Field | Type | Notes |
|---|---|---|
text | string | The cleaned result, NFC normalized. |
inspection_text | string | The text the findings describe. Your original input in careful, the rewritten text in thorough. |
mode | string | The mode that ran. |
input_charactersoutput_characters | integer | Length before and after cleaning. |
removed_characters | integer | How many characters were removed. |
normalized | boolean | Whether NFC normalization changed the text on top of the removals. |
findings | array | One entry per code point and outcome, with codepoint, tag, label, note, count, positions (first 8, 1-based), action (removed or preserved) and sensitive. Marks inside emoji sequences are preserved, not removed. |
billing | object | metered, price_eur_per_request and the stripe_usage_record_id for this call. The record id is null if Stripe could not be reached; the call is still logged for reconciliation. |
rewritesource_characters | object, integer | thorough only. rewrite reports requested, applied, model and a warning when the wording pass was skipped and only Unicode cleaning ran. |
04 / Errors
What can go wrong.
| Status | Code | Fix |
|---|---|---|
| 401 | api_key_required | Add the Authorization: Bearer header. |
| 401 | api_key_invalid | Key is wrong or revoked. Create a new one. |
| 402 | api_billing_required | Enable metered API billing on your account. |
| 429 | api_rate_limit_reached | Wait for the Retry-After header value. |
| 400 | — | No code field. Send a JSON object whose text is a string and whose mode is careful or thorough. |
| 400 | thorough_text_required | thorough needs text that is not blank. |
| 413 | thorough_text_too_large | Over the max_characters returned in the body. Shorten it or use careful. |
| 413 | — | The request body itself is over 2 MB. |
| 503 | thorough_unavailable | Thorough is off on this server. Use careful. |
Errors carry a human-readable error string, and a stable code wherever the table lists one. Rate limiting allows 60 requests per 60 seconds by default, counted per key and per account, so a second key does not raise your account ceiling. Only requests that reach cleaning are metered; rejected requests are never billed.