An API for getting rid of AI writing fingerprints
Use Unslop to find familiar AI writing patterns and review small edits. A free API for clearer drafts, reusable writing preferences, and checks on what changed.
Use Unslop to find familiar AI writing patterns and review small edits. A free API for clearer drafts, reusable writing preferences, and checks on what changed.
Unslop helps remove the familiar wording and patterns which make AI-assisted writing sound generic. The free API checks drafts and proposes limited edits, with controls to preserve facts, quotations, links, and the writer's own voice.
Stock transitions, inflated language, repeated phrasing, and sentences split off for dramatic emphasis are the habits I mean by "AI writing fingerprints." Unslop helps you find and edit them so the useful information is easier to get through. You can use the browser workbench for one passage or call the API from your own editing workflow.
My VOICE.md file records many of these recurring quirks and helped inform the project. I previously wrote about the /unslop skill, which gives an AI editor writing guidance. The API adds measured findings and checks on a proposed rewrite, so you can see what changed before using it.
accepted and validation before using the returned text, then review the edit in context. A failed check keeps the original text available.This is a small, free project. I'm not trying to turn it into a business. The website deliberately looks like something I would have hand-coded in Notepad on Windows XP in high school. The workbench lets you try the checks and editing controls before writing an integration.
The initial checks run on the server without calling a language model. Style rules flag phrases and punctuation worth reviewing. Harper, running locally on the server in WebAssembly, supplies grammar and spelling checks. Reading-level estimates give you another way to inspect a passage's difficulty.
The rhythm report describes sentence and paragraph lengths, repeated phrasing, and vocabulary. Uniform paragraphs can be a useful thing to notice, but a list of instructions may need the same structure on every line. Repeating the name of a function can be clearer than finding a new synonym each time. I don't want to replace useful repetition just to improve a number.
These measurements cannot establish who wrote a passage. A high style score means more matched patterns, not a probability of AI authorship. Human writing can contain every one of those patterns. The research references separate the published work from Unslop's own heuristics and explain their limits. There is no promise of making writing undetectable or removing a watermark.
Reading targets are estimates too. You can choose a US grade, an approximate age, or a reading-level ceiling. The age option maps age to grade by subtracting five; it doesn't assess a particular child's comprehension or whether the subject is appropriate for them. A ceiling lets already-easier writing pass. Asking for an exact target can conflict with a small edit budget, and the API will reject a candidate which can't satisfy both.
Unslop scores the original before spending model calls. By default, AI editing requires at least 50 prose words and a style score of 20 or higher. Otherwise it returns the original with a skip reason. You can adjust those cutoffs through rewrite_gate, or disable the gate when you deliberately want an edit regardless of score.
The current editor works on short passages from the original, rather than asking a model to regenerate the whole document. Each replacement is limited to 8 words and 60 Unicode characters per side by default. Code checks the edits and combines the accepted ones. Later model calls don't rewrite an earlier model's output.
The default is up to four editing calls, alternating between OpenAI and Anthropic. Choose one provider explicitly if you want all AI processing to stay with that provider. Set micro.max_calls to limit the work per request; unreviewed passages stay unchanged. This makes the API useful for a controlled editing pass even when you only have a few calls available.
The default total change budget is now 0.15, before any profile or request overrides. The example below explicitly allows 0.35. Both count added plus removed prose word and punctuation tokens, divided by the original prose tokens. Replacing a word charges both the removal and the addition. A 0.35 budget isn't permission to replace 35% of the words and ignore the new ones.
Numbers, quotations, URLs, and common Markdown formatting have protections. You can also supply protected terms and spans. Markdown protection is conservative, so I would still extract prose from a template or explicitly protect complex MDX components before submitting it. A formatter can't tell me whether a change to a personal story is true.
Optional meaning review makes a separate model call to look for changed claims, missing qualifications, and other meaning changes. A reported problem rejects the candidate. The reviewer can still miss things, so I read the proposed edit myself. This fits the way I already use AI while writing.
A voice profile saves instructions, rules, defaults, and optional writing samples in your workspace. Put preferences in the instructions and prose you approve of in the samples. My built-in nathan profile belongs to my owner workspace; new accounts should create their own profile or pass instructions with each request. You can list your profiles with GET /v1/profiles.
The descriptive voice comparison needs at least two prose samples with 20 sentences between them. It withholds the ranges when the declared genres don't match. Those ranges describe the samples; they aren't a voice-match score or a target to force every paragraph into. The API accepts up to four request samples of 5,000 UTF-16 units each, which also count toward submitted-word usage.
Create a free account with a username and password. Save the API key and the one-time recovery code in a password manager when they're shown. Keep the recovery code separate from anything you share as an API example.
Open the workbench, paste your API key into its key field, press Connect, and add your text. The key stays in page memory rather than browser storage. Run Analyze text first. Read the findings, then choose a provider, profile, and editing constraints before running Rewrite with AI. Enable meaning review if you want the extra check, and compare the returned text with the original before copying it elsewhere.
Set UNSLOP_API_KEY in your shell from your password manager or local secret storage. Keep the real value out of saved commands, source control, and URLs. The API guide has more examples, and the OpenAPI schema lists the current request fields.
This analysis request doesn't need a profile or a model call:
curl --fail-with-body --silent --show-error \
https://unslopapi.vercel.app/v1/analyze \
-H "Authorization: Bearer $UNSLOP_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @- <<'JSON'
{
"text": "I keep project notes in one file. Before editing, I read the notes and check the links. The file gives me enough context to pick up the work the next morning.",
"format": "markdown"
}
JSON
The response includes score, quality, and explanations of the findings. Read the explanations before deciding to change anything.
For a rewrite, explicitly choose the provider and controls. This short example disables the score and length gate so it can request an edit. It allows one editing call and one meaning-review call, with retries off:
curl --fail-with-body --silent --show-error \
https://unslopapi.vercel.app/v1/rewrite \
-H "Authorization: Bearer $UNSLOP_API_KEY" \
-H 'Content-Type: application/json' \
--data-binary @- <<'JSON'
{
"text": "I utilize this file to keep my project notes in one place. Before editing, I read the notes and check the links. I want to preserve the details so I can pick up the work the next morning.",
"format": "markdown",
"provider": "openai",
"allow_ai": true,
"semantic_review": true,
"retry_on_failure": false,
"rewrite_gate": { "enabled": false },
"micro": { "max_calls": 1 },
"instructions": "Edit lightly. Prefer plain words. Preserve every fact and qualification, and leave good sentences alone.",
"constraints": {
"max_change_ratio": 0.35,
"preserve_numbers": true,
"preserve_quotes": true,
"preserve_formatting": true
}
}
JSON
Check accepted before using the returned text. An HTTP 200 only tells you the request completed. Inspect validation for the constraint checks and semantic_review for the optional meaning review. If accepted is false, text is the original; a rejected candidate may still appear under validation.comparison for diagnosis. Don't apply those candidate edits automatically. An accepted result can also be unchanged. Check status and micro_editing.spans_remaining too: a skipped request made no edits, and a partially rewritten result still has unreviewed passages.
Check GET /v1/capabilities for the currently configured models and connections, and GET /v1/usage for your own remaining allowances. Long documents need splitting at paragraph or section boundaries. Each submitted text is limited to 20,000 UTF-16 units, so leave room instead of treating the limit as a word count.
I checked the live public signup configuration on September 24, 2026. New accounts receive 20 requests per minute, 500 requests per day, 10,000 submitted words per day, and five AI or external calls per day. Public accounts share a daily pool of 100 AI calls. Having personal calls left doesn't guarantee shared capacity is available.
The default four editing calls plus a meaning review can use all five of a free account's daily AI calls. Meaning reviews, retries, and failed provider attempts use calls. Instructions and submitted samples also use the word allowance. Daily limits reset at midnight UTC. The signup page and your usage response are the places to check as these limits change. My owner account has different limits, so its quota isn't the free signup allowance.
Submitted text reaches the Unslop server even for analysis. Rewriting and optional AI review send the relevant text and guidance to OpenAI, Anthropic, or both, depending on your provider setting. A configured direct provider key uses that provider's API; otherwise the connection can use Vercel AI Gateway. The response identifies the connection.
The application doesn't persist submitted drafts or revisions. Saved profiles do persist the instructions, rules, samples, and preferences you choose to save. Hosting and model providers have their own processing and retention terms; OpenAI requests set store: false, which doesn't remove those terms. Read the text-handling explanation before submitting material you need to keep confidential.