OpenAPI 3.1 document · pricing.json · Get a key
Authentication
Pass your key as a bearer token. Keys are created in the dashboard, stored only as a SHA-256 hash, and shown once.
Authorization: Bearer mw_live_...POST /api/v1/check
curl -X POST https://www.neverprompted.com/api/v1/check \
-H "Authorization: Bearer $WATERMARKREMOVERPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "The text you want to check...",
"language": "en",
"granularity": "sentence"
}'language is optional. Omit it and the engine identifies it, or returns language_undetermined rather than guessing. Supported: en, es, fr, de, pt.
POST /api/v1/calibrate
The lighter, deterministic layer behind the on-device rewrite engine: suggests word-frequency substitutions with before/after metrics, rather than producing a finished, targeted rewrite. Authentication is optional, as with /check; an anonymous call is capped at the no-account word limit rather than a tracked monthly allowance.
curl -X POST https://www.neverprompted.com/api/v1/calibrate \
-H "Authorization: Bearer $WATERMARKREMOVERPRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "The text you want to calibrate...",
"language": "en",
"mode": "preview",
"config": {
"excludedWords": ["NeverPrompted", "on-device AI detector"]
}
}'mode is preview (the default, returns suggested substitutions without applying them) or apply (returns the calibrated text). config.excludedWords lists words or phrases this call must never substitute, matched case-insensitively as whole words or phrases: useful for SEO keywords, product names or other terms that need to survive calibration unchanged. A substitution skipped for this reason is reported back with reason: "excluded" rather than silently omitted.
Reading the response
Every statistic is either a number or null. Null means the value was not computed, and the sibling status and detail fields say why. Rendering null as zero would turn “we could not measure this” into “we measured this and found nothing”, which are very different claims to make about someone’s document.
{
"result": {
"status": "ok",
"documentHash": "9f2c...", // SHA-256 of the exact text
"watermark": {
"keysTested": [ { "id": "openmark-ref-1", "vendorPublished": false } ],
"results": [ {
"status": "computed",
"trials": 412, // distinct word pairs, repeats counted once
"greenRate": 0.508,
"greenRateInterval": { "low": 0.460, "high": 0.556 },
"expectedGreenRate": 0.5,
"z": 0.32,
"pValue": 0.374
} ],
"anyDetected": false,
"coverageNotice": "Tested against 1 key ... no vendor publishes one ..."
},
"distribution": { "status": "computed", "compositeDeviation": 1.42, ... },
"passages": [ ... ],
"passageCorrection": { "method": "benjamini-hochberg", "tested": 34, "survived": 0 },
"limits": [ "A detected mark is not proof of authorship.", ... ]
},
"billing": { "words": 812, "billableUnits": 1, "pence": 2, "currency": "GBP" }
}coverageNotice and limits are part of the result, not decoration. If you surface this data to a user, surface those too, because a null watermark result quoted without its coverage notice says something the measurement does not support.
Status codes
- 200Analysis complete. Note that a successful call can still carry a result whose status is
language_undetermined, because the request worked and the measurement declined. - 400Body was not valid JSON, or failed validation.
issuesnames the fields. - 401Missing, unknown or revoked key.
- 402Outside your plan allowance. The message names the exact limit reached and when it resets.
- 503This deployment has no metering ledger, so metered access cannot be granted. It refuses rather than serving unmetered.
What this API does not offer
/calibrate above is the lighter, deterministic layer: word-frequency substitutions with before/after metrics, not a finished, targeted rewrite. There is no endpoint or parameter, on any plan, that runs the fuller rewrite engine over this REST API. That is a deliberate omission, not a missing feature: the targeted rewrite is on-device only, on every tier, and a REST endpoint that accepted your document text for it would break that guarantee. Call it instead via the MCP server's reduce_ai_evidence tool, or the published local package/CLI, both of which run in your own process and never transmit the document.