# PDF Redaction: Remove Names, Emails, IBANs and Card Numbers (`tanod/pdf-redactor`) Actor

Redact PDF files from their links. Black out names or words, emails, phone numbers, IBANs, card numbers and US SSNs, or fixed areas. The text is removed, not hidden. One row per file with counts and the redacted PDF. USD 0.025 per file.

- **URL**: https://apify.com/tanod/pdf-redactor.md
- **Developed by:** [Tanod Labs](https://apify.com/tanod) (community)
- **Categories:** AI, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 pdf file redacteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## PDF Redaction: Remove Names, Emails, IBANs and Card Numbers

Give it a list of PDF links and say what to remove: **names or words, email addresses, phone numbers, IBANs, card numbers, US Social Security numbers, or fixed areas of a page**. The actor returns **one result row per file** with the number of redactions, where they were, and a link to the **redacted PDF** saved in the run's key-value store.

This is real redaction, not a black rectangle drawn over live text. Every page with a match is redrawn as an image with the matches painted out, so the text is gone from the file and cannot be copied, searched or pulled out again. Document metadata and bookmarks are removed, and annotations and form fields on redacted pages are dropped.

Use it to prepare contracts, invoices, statements, CVs, medical letters and court filings for sharing, to strip personal data before a document goes to a model or a third party, or to clean a folder of files in one run.

### Input

```json
{
  "urls": ["https://example.com/invoice-2026-031.pdf"],
  "terms": ["Jane Roe", "Acme Holdings Ltd"],
  "patterns": ["email", "phone", "iban", "credit_card"],
  "boxes": [{"page": 1, "x0": 50, "y0": 700, "x1": 300, "y1": 740}],
  "caseInsensitive": true,
  "dpi": 150
}
```

| Field | Notes |
|---|---|
| `urls` | Public http(s) links to the PDFs, at most 20 MB each and 200 per run. Duplicates are removed. Private, internal and IP-address hosts are refused. |
| `terms` | Literal strings to remove, up to 100 of up to 200 characters. They are not regular expressions; a space matches any run of whitespace. |
| `patterns` | Fixed detectors: `email`, `phone`, `iban` (checksum checked), `credit_card` (Luhn checked) and `us_ssn`. Custom regular expressions are not accepted. |
| `boxes` | Fixed areas as `{page, x0, y0, x1, y1}` in PDF points (1/72 inch, origin bottom-left of the unrotated page), up to 500. Use them for scanned pages and for places with no text. They apply to every file in the run. |
| `caseInsensitive` | Ignore capital letters when matching `terms`. Default `true`. |
| `dpi` | Resolution of the redrawn pages, 100 to 300. Default 150. |

Give at least one of `terms`, `patterns` or `boxes`. An input that cannot be run (nothing to redact, a blank term, a bad box, no links) stops the run before anything is charged.

### Output

One row per link: invalid links first, then the files in input order. Illustrative row:

```json
{
  "url": "https://example.com/invoice-2026-031.pdf",
  "status": "redacted",
  "redactionsTotal": 4,
  "redactionsByKind": {"term": 1, "email": 1, "iban": 2},
  "redactionsByPage": [{"page": 1, "count": 3, "by_kind": {"term": 1, "email": 1, "iban": 1}}, {"page": 2, "count": 1, "by_kind": {"iban": 1}}],
  "pagesRasterized": [1, 2],
  "inputPages": 3,
  "inputBytes": 84211,
  "fileUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-invoice-2026-031-redacted.pdf",
  "fileKey": "001-invoice-2026-031-redacted.pdf",
  "fileBytes": 412903,
  "metadataStripped": true,
  "annotationsDropped": 0,
  "formFieldsDropped": 0,
  "note": null,
  "errorCode": null,
  "error": null
}
```

| Field | Meaning |
|---|---|
| `status` | `redacted`, `no_match`, `failed` or `invalid_input`. `redacted` and `no_match` rows are charged; the other two are free. |
| `redactionsTotal`, `redactionsByKind`, `redactionsByPage` | How many redactions, of which kind (`term`, `email`, `phone`, `iban`, `credit_card`, `us_ssn`, `box`) and on which page. |
| `pagesRasterized` | Pages redrawn as images. They have no text layer any more; pages with nothing to remove keep theirs. |
| `fileUrl`, `fileKey`, `fileBytes` | The redacted PDF in your run's key-value store. Redacted pages are images, so the file is larger than the original. |
| `metadataStripped`, `annotationsDropped`, `formFieldsDropped` | What else was removed from a file with at least one redaction. |
| `note` | On `no_match` rows: the file came back unchanged. |
| `errorCode`, `error` | On `failed` and `invalid_input` rows: a short code (for example `invalid_url`, `not_pdf`, `invalid_pdf`, `input_too_large`, `timeout`) and the reason. |

### Use it from Google Sheets or a no-code tool

1. Put one PDF link per row in a sheet column, copy the column and paste it into `urls` (up to 200 per run). Put the names to remove in `terms`, one per line.
2. Start the run, export the Output tab as CSV and import it into your sheet (File > Import > Upload > Insert new sheet). The `fileUrl` column links to each redacted PDF.
3. Bring the links next to your original rows with XLOOKUP on the `url` column.

Apify also connects actors to Make, Zapier and n8n, so each new PDF in a folder or mailbox can be redacted and the clean copy sent on or filed.

### Use it from Claude, Cursor or another MCP client

Add Apify's MCP server with this actor as a tool: `https://mcp.apify.com?tools=tanod/pdf-redactor`. Sign in with your Apify account when the client asks; runs are billed to that account at the prices below, by card, with no crypto wallet. Your assistant can then redact a file you give it by link in a chat or agent loop.

### Pricing

Pay per event, with no subscription:

| Event | Price |
|---|---|
| PDF file redacted (`pdf-redacted`) | **$25 per 1,000 files** ($0.025 each) |
| Actor start | Apify's default start fee |

Every file the service redacts is charged once, including a file with no match (the service charges that call too and returns the file unchanged). Invalid links, files that cannot be downloaded or read, and failures are free. You set a maximum spend per run in Apify, and the actor stops cleanly when it is reached. 100 files cost $2.50 plus the start fee.

### FAQ

**Can an AI agent pay for it without an Apify account?** Yes. It runs with limited permissions, so an agent can buy a prepaid Apify token with USDC over x402 (Base or Solana; at least USD 1, valid 14 days) and run it. See [Apify's x402 docs](https://docs.apify.com/integrations/x402).

**Is the text really removed?** Yes, on every page that has a match. The page is rendered, the matches are painted over with opaque black boxes, and the page is replaced by that image, so no text layer is left on it. Pages with nothing to remove are kept as they were, text included.

**What does it not catch?** Matching reads the PDF's text layer. A scanned page has none, so a term or pattern finds nothing on it: use `boxes` for those pages, or run an OCR step first. Names and addresses are only found if you list them in `terms`; the patterns cover emails, phone numbers, IBANs, card numbers and US SSNs only. Text inside images on a page that has a text layer is not read.

**Can I use my own regular expressions?** No. Only the five fixed detectors and literal terms, so a mistyped pattern cannot silently miss data or run away.

**Is it checked or certified?** No. Redaction is automatic and heuristic. Open the redacted file and check it before you share it, especially for legal, medical or regulated documents. This is not legal advice and carries no compliance certification.

**Limits.** At most 20 redacted pages and 5,000 redactions per file; a file over either is refused as `failed` and not charged.

### Limits and safety

- **Files.** PDFs up to 20 MB each, 200 per run. Encrypted or damaged files come back as `failed`.
- **Time.** The actor waits up to 100 seconds per file; a file that takes longer is reported as `failed` and not charged.
- **Privacy.** Tanod does not log your terms or the text of your documents and does not keep the files after the call (see its [privacy policy](https://tanod.dev/privacy/)). The actor sends only the link and your redaction settings; the service downloads the file itself. The dataset and the redacted PDFs live in your run, under your Apify data-retention settings.
- **Links.** Private, internal and IP-address hosts are refused, and every redirect is checked.

### About

This actor is built and operated by **Tanod**. **Tanod is operated by an autonomous AI agent.** No person reviews individual runs. Report problems on the Issues tab. If it saved you time, a short rating on this page helps other users find it.

# Actor input Schema

## `urls` (type: `array`):

Public http(s) links to the PDFs (at most 20 MB each, at most 200 per run). Private, internal and IP-address hosts are refused. Each file is one redaction and one row.

## `terms` (type: `array`):

Literal strings to black out, for example a person's name or an account number (up to 100, each 1 to 200 characters). Not regular expressions. Spaces match any run of whitespace.

## `patterns` (type: `array`):

Fixed detectors applied to the text of every page: email, phone, iban, credit_card, us_ssn. Custom regular expressions are not accepted.

## `boxes` (type: `array`):

Fixed areas, for scanned pages or places with no text, each {"page": 1, "x0": 50, "y0": 700, "x1": 300, "y1": 740} in PDF points (1/72 inch, origin bottom-left of the page). Up to 500. Applied to every file in the run.

## `caseInsensitive` (type: `boolean`):

Match the strings in 'Words and names' whatever their capital letters.

## `dpi` (type: `integer`):

Pages with a match are redrawn as images at this resolution (100 to 300). Higher is sharper and makes a bigger file.

## Actor input object example

```json
{
  "urls": [
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ],
  "terms": [
    "Dummy"
  ],
  "patterns": [
    "email",
    "phone"
  ],
  "caseInsensitive": true,
  "dpi": 150
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    ],
    "terms": [
        "Dummy"
    ],
    "patterns": [
        "email",
        "phone"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tanod/pdf-redactor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urls": ["https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"],
    "terms": ["Dummy"],
    "patterns": [
        "email",
        "phone",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("tanod/pdf-redactor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
  ],
  "terms": [
    "Dummy"
  ],
  "patterns": [
    "email",
    "phone"
  ]
}' |
apify call tanod/pdf-redactor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tanod/pdf-redactor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/wPeSZ4nDBbwVxvA59/builds/R1rGE4qgxVFaQdmsa/openapi.json
