Redact text in PDF
Enter falcon once and all three forms in a sentence, Falcon, FALCON and falcon, become ████, with a count of 3 to prove it. Use it on text taken from a PDF before you share, index or store it. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Terms
- falcon
- Redacted count
- 3
The PDF text redaction tool removes every case-insensitive occurrence of the terms you provide from text extracted from a PDF. Each detected occurrence is replaced with a visible black box marker, while the response also reports the exact number of replacements. It is useful when a workflow already has selectable or extracted PDF text and needs a predictable sanitation step before review, indexing, sharing, or storage. Matching is literal and deterministic, so punctuation in a term is treated as punctuation rather than as a pattern instruction.
Prepare the PDF text and the redaction list
Start with text extracted from a PDF, preserving the wording and line breaks that matter to the next stage of your workflow. Supply that value in the text field, then add one or more literal strings to the terms list. A term may be a name, account reference, project label, address fragment, or any other exact sequence that should no longer appear.
Matching ignores letter case, so a single entry such as “Falcon” also finds “FALCON” and “falcon.” The terms are not regular expressions. Characters such as periods, brackets, plus signs, and question marks are matched as ordinary characters, which prevents an innocent term from becoming an unintended search pattern.
Empty term lists are rejected because silently returning unchanged text could create a false impression that redaction occurred. Empty strings inside the list are rejected as well. This explicit input contract makes the operation suitable for automated pipelines where a missing policy value must stop processing rather than pass sensitive content forward.
Understand matching and replacement behavior
The tool scans the original text from beginning to end and replaces each non-overlapping match with the fixed marker “████.” Duplicate terms that differ only by case are treated as one search term, preventing the same span from being counted twice. If multiple supplied terms can begin at the same character, the longest term is considered first.
For example, listing both “North” and “North Harbor” redacts the complete phrase when that phrase occurs at a position. Matches never cascade: inserted box markers are output, not new input to search. The count can be zero when the list is valid but none of its terms occurs.
That distinction matters because zero confirms that the operation ran successfully, whereas an invalid or empty term list produces an error. Matching is literal and does not infer word boundaries, so a short term can also match inside a longer word. Include the exact phrase you intend to remove.
Use the result safely in a document workflow
This capability operates on PDF text supplied by the caller; it does not modify PDF page graphics, annotations, hidden layers, metadata, or the original binary file. Use it when extracted text is itself the output that will be displayed, indexed, summarized, logged, or passed to another system. If you must publish a visually redacted PDF, apply a PDF-native redaction process to the source document and verify that the underlying content cannot be recovered.
Consider retaining the count and policy version in an audit record without retaining the sensitive original. Review term selection carefully: literal matching is predictable, but it cannot discover variants you did not list. The same deterministic logic runs without network access, which keeps results stable across repeated calls with identical inputs.
What you can do with it
Sanitize text before indexing
Remove client names, internal project labels, or reference numbers before extracted PDF text enters a search index.
Prepare a review copy
Create a clearly marked text version for reviewers who should see the document wording but not specified confidential terms.
Enforce a known-term policy
Apply an approved list of sensitive phrases in an automated pipeline and record the replacement count for auditing.
FAQ
Does matching distinguish uppercase and lowercase letters?
No. Matching is case-insensitive, so one term covers uppercase, lowercase, and mixed-case occurrences.
Are terms interpreted as regular expressions?
No. Every term is treated literally, including punctuation and characters that have special meanings in regular expressions.
Does this edit the original PDF file?
No. It redacts text already extracted from a PDF. It does not alter the PDF binary, page graphics, metadata, or hidden content.
Can a short term black out part of a longer word?
Yes. Matching does not look for word boundaries, so a short term can also be found inside another word. Enter the exact phrase you want removed so you do not hide more than you meant.
Why can the count come back as zero?
Zero means the list was valid but none of its terms appears in the text, which confirms the step ran. An empty list, by contrast, is refused, so nobody believes text was redacted when it was not.
Related tools
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, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/pdf/redact-text \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Project Falcon belongs to FALCON Holdings.","terms":["falcon"]}'const res = await fetch("https://api.kit.forhosting.com/pdf/redact-text", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "Project Falcon belongs to FALCON Holdings.",
"terms": [
"falcon"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/redact-text",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "Project Falcon belongs to FALCON Holdings.",
"terms": [
"falcon"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/redact-text", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"Project Falcon belongs to FALCON Holdings.","terms":["falcon"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"Project Falcon belongs to FALCON Holdings.","terms":["falcon"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/redact-text", 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": "Project Falcon belongs to FALCON Holdings.",
"terms": [
"falcon"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.redact_text",
"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_mb | 25 |
max_pages | 200 |
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. |
Technical notes
Understand matching and replacement behavior
The response contains redacted_text and redacted_count, allowing a caller to use the sanitized text and separately verify how much changed.
Use the result safely in a document workflow
A practical automated flow extracts text, submits the text and an approved term list, checks redacted_count against an expected minimum, and stores only redacted_text in downstream search or review systems. The API price is $0.002 per request.
Technical questions
What happens when no term is found?
The original text is returned unchanged and redacted_count is zero.
What happens when the term list is empty?
The request fails with an invalid_input error because at least one non-empty term is required.