Anonymize text
Deleting a name from a sentence is easy; keeping the sentence useful afterward is the hard part. This text anonymization API rewrites personal references so the underlying meaning, structure and analytical value of a document survive, while the specific people in it become impossible to trace back or reassemble from what's left.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
Why simple masking isn't always enough
Blacking out a name is easy, but a document can still identify someone through what's left behind — a job title, a city, an age and a rare medical condition together can point to exactly one person even with every name removed. text.anonymize is built for that harder problem: it doesn't just hide the obvious identifiers, it also handles the surrounding detail that could let a reader reconstruct who's being described, which is the actual bar that data protection regulation sets for calling something anonymized rather than merely masked.
How the process works
You submit text to POST /text/anonymize, the task processes asynchronously, and what comes back reads naturally — generic but grammatically coherent replacements stand in for names, locations, dates and other identifying detail, rather than the bracketed placeholders a redaction tool would leave behind. That distinction is deliberate: an anonymized transcript can go into a training dataset, a public research paper or an analytics pipeline and still read like real language, because it is, just without a specific person attached to it.
Where the line with redaction sits
Redaction and anonymization solve related but different problems. Redaction masks known identifiers and leaves the rest of the text untouched — fast and auditable, but the residual context can sometimes still narrow down who's being discussed. Anonymization is the stronger guarantee, built for the cases where a document genuinely needs to lose its connection to specific individuals: research corpora, datasets shared outside an organization, or any text that will live somewhere the original subject never agreed to be identifiable in.
A brief note on why this discipline exists
Data protection frameworks like GDPR draw a sharp legal line between personal data and anonymized data — once information can no longer be linked back to an individual by any reasonable means, it generally falls outside the strictest handling rules. That distinction is precisely why anonymization is worth doing properly rather than approximated with a find-and-replace: a document that still allows re-identification through remaining context hasn't actually crossed that line, no matter how many names were removed from it.
Fitting it into automated data handling
Results arrive by signed webhook by default, which suits pipelines that anonymize records the moment they're created or exported — a support ticket closes, gets anonymized, and only the anonymized version ever reaches an analytics warehouse. For batch or ad hoc runs, the signed link stays valid for 24 hours. Pricing is $0.003 per request plus $0.0135 per 1000 words processed, there's no free tier or trial balance, and a task that fails after three automatic retries is never billed.
What you can do with it
Research datasets and academic sharing
Anonymize interview transcripts or survey responses before they're published or shared with outside researchers.
Training data preparation
Strip personal identifiers and re-identifying context from real conversations before using them to build or fine-tune internal models.
Cross-border and cross-team data sharing
Anonymize customer records before they move to a team, region or vendor with a different data-handling agreement.
Long-term analytics storage
Convert support or product-feedback logs into anonymized form before they enter a long-term analytics warehouse.
FAQ
What's the difference between anonymization and redaction?
Redaction masks known identifiers with placeholders; anonymization goes further, also handling surrounding context that could allow re-identification, which is what text.anonymize is designed to do.
Does anonymized text still read naturally?
Yes, identifying details are replaced with generic but grammatically coherent equivalents rather than bracketed placeholders, so the output reads like ordinary text.
Is this API GDPR-compliant on its own?
The API performs the anonymization step properly, reducing re-identification risk from remaining context; whether a given use case meets your full regulatory obligations still depends on your own data-handling practices.
How is text anonymization priced?
It's $0.003 per request plus $0.0135 per 1000 words processed, with no charge for tasks that fail after their automatic retries.
Is there a free way to try anonymizing text?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
Can I anonymize large datasets in bulk?
Yes, submissions are processed asynchronously, so large batches of documents or transcripts can run in the background while results arrive via webhook.
How do I receive the anonymized output?
Through a signed webhook, recommended for automated pipelines, or via a signed link that stays valid for 24 hours.
Does anonymization work across multiple languages?
The model reads context and structure rather than relying on English-only patterns, which lets it anonymize identifying detail across languages.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/text/anonymize \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/anonymize", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/anonymize",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/anonymize", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/anonymize", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.anonymize",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_tokens | 20000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |