We are in official beta.

Redaction & PII

Detect PII patterns, redact text or areas, and flatten PDFs for secure removal

4 endpoints in this category. All require X-API-Key header.


Analyze PDF for PII

POST /api/AnalyzePdf 1 token

Scans a PDF for PII patterns (SSN, email, credit card, phone, etc.) and returns match coordinates without modifying the document. Optionally accepts a template to auto-detect field locations via AI extraction. Use the results to preview what would be redacted.

Parameters
NameTypeRequiredDescription
pdf string required Base64-encoded PDF
patterns array optional PII pattern names to detect: ssn, email, credit_card, phone_us, date, currency, ip_address, etc.
customPatterns array optional Custom regex patterns: [{regex, label, color}]
templateId string optional UUID of a saved template — auto-detects field locations for redaction
template object optional Inline template definition: {prebuiltModel, fields: [{fieldKey, label, type}]}
redactFields array optional Template field keys to include (omit to detect all template fields)
pages string optional Pages to analyze: "all" or "1-3,5" (default: all)
padding number optional Padding around matches in points (default: 2)
Request Example
JSON
{"pdf": "<base64-pdf>", "patterns": ["ssn", "email", "credit_card", "phone_us"], "pages": "all", "padding": 2}
Response Example
JSON
{"success": true, "totalMatches": 5, "pagesAnalyzed": 3, "matches": [{"page": 1, "label": "SSN", "value": "***-**-1234", "x": 72.5, "y": 680.3, "width": 85.2, "height": 12.0, "color": "#FF0000"}]}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/AnalyzePdf" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"pdf": "<base64-pdf>", "patterns": ["ssn", "email", "credit_card", "phone_us"], "pages": "all", "padding": 2}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""pdf"": ""<base64-pdf>"", ""patterns"": [""ssn"", ""email"", ""credit_card"", ""phone_us""], ""pages"": ""all"", ""padding"": 2}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/AnalyzePdf", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/AnalyzePdf"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"pdf": "<base64-pdf>", "patterns": ["ssn", "email", "credit_card", "phone_us"], "pages": "all", "padding": 2}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/AnalyzePdf
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "pdf": "\u003Cbase64-pdf\u003E",
│      "patterns": [
│        "ssn",
│        "email",
│        "credit_card",
│        "phone_us"
│      ],
│      "pages": "all",
│      "padding": 2
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/AnalyzePdf"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Redact PDF by Text

POST /api/RedactPdfText 2 tokens

Finds text strings or regex patterns in a PDF and draws opaque colored rectangles over each match. Optionally accepts a template to auto-detect field locations for redaction. Fast overlay-based redaction — use RedactPdfFlatten for guaranteed text removal.

When a template is used, the response carries fieldResults, one entry per requested field with applied (true or false), a reason when false, and optional: true for an optional field that was not found. If a requested field cannot be blacked out, the call returns 422 with no PDF unless allowPartialFields is true; then it returns 207 with partialFields: true, unresolvedFields and a redactionWarning. With returnBase64: false the headers X-Redaction-Partial, X-Redaction-Fields-Unresolved and X-Redaction-Fields-Matched carry the warning. A text pattern that matches nothing is not an error.
Parameters
NameTypeRequiredDescription
pdf string required Base64-encoded PDF
redactions array optional Array of redaction rules: [{text, regex, color, caseSensitive}]
templateId string optional UUID of a saved template — auto-detects field locations for redaction
template object optional Inline template definition: {prebuiltModel, fields: [{fieldKey, label, type, optional}]}. A field marked optional: true that is not found in the document is reported in fieldResults, not refused. One that is found but cannot be blacked out still counts.
redactFields array optional Template field keys to redact (omit to redact all detected fields)
allowPartialFields boolean optional Accept a document in which some requested template fields could not be blacked out. Default false: any such field returns 422 with no PDF. When true, the response is 207, never 200. (default: false)
pages string optional Pages to redact: "all" or "1-3,5" (default: all)
padding number optional Padding around matches in points (default: 2)
returnBase64 boolean optional Return base64 JSON or raw binary (default: true)
Request Example
JSON
{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith", "color": "#000000", "caseSensitive": false}, {"regex": "\\b\\d{3}-\\d{2}-\\d{4}\\b", "color": "#FF0000"}], "pages": "all", "allowPartialFields": false, "returnBase64": true}
Response Example
PDF
{"pdf": "JVBERi0xLjcK...", "pageCount": 3, "totalRedactions": 7, "redactionsPerPage": {"1": 3, "2": 4}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/RedactPdfText" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith", "color": "#000000", "caseSensitive": false}, {"regex": "\\b\\d{3}-\\d{2}-\\d{4}\\b", "color": "#FF0000"}], "pages": "all", "allowPartialFields": false, "returnBase64": true}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""pdf"": ""<base64-pdf>"", ""redactions"": [{""text"": ""John Smith"", ""color"": ""#000000"", ""caseSensitive"": false}, {""regex"": ""\\b\\d{3}-\\d{2}-\\d{4}\\b"", ""color"": ""#FF0000""}], ""pages"": ""all"", ""allowPartialFields"": false, ""returnBase64"": true}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/RedactPdfText", content);
response.EnsureSuccessStatusCode();

// The response contains a base64-encoded file in the JSON body
var result = await response.Content.ReadAsStringAsync();
using var doc = System.Text.Json.JsonDocument.Parse(result);
var base64 = doc.RootElement.GetProperty("pdf").GetString();
var bytes = Convert.FromBase64String(base64!);
await File.WriteAllBytesAsync("output.pdf", bytes);
import requests
import json
import base64

url = "https://api.docbutterfly.com/api/RedactPdfText"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith", "color": "#000000", "caseSensitive": false}, {"regex": "\\b\\d{3}-\\d{2}-\\d{4}\\b", "color": "#FF0000"}], "pages": "all", "allowPartialFields": false, "returnBase64": true}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

# Decode the base64 PDF and save to file
data = response.json()
pdf_bytes = base64.b64decode(data["pdf"])
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("Saved to output.pdf")
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/RedactPdfText
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "pdf": "\u003Cbase64-pdf\u003E",
│      "redactions": [
│        {
│          "text": "John Smith",
│          "color": "#000000",
│          "caseSensitive": false
│        },
│        {
│          "regex": "\\b\\d{3}-\\d{2}-\\d{4}\\b",
│          "color": "#FF0000"
│        }
│      ],
│      "pages": "all",
│      "allowPartialFields": false,
│      "returnBase64": true
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/RedactPdfText"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed

To save the output file:
7. Add a "Parse JSON" action on the HTTP response body
8. Use base64ToBinary(body('Parse_JSON')?['pdf']) to convert
9. Pass the result to a "Create file" action (SharePoint, OneDrive, etc.)
Try in Testbed

Redact PDF by Area

POST /api/RedactPdfArea 1 token

Draws opaque colored rectangles at specified coordinates on PDF pages. Use for targeted redaction of known regions.

The response carries areaResults, one entry per area with applied (true or false) and a reason when false. If an area cannot be applied (its page is outside the document, or its width or height is not above zero), the call returns 422 with no PDF unless allowPartialAreas is true; then it returns 207 with partial: true, discardedAreas and a redactionWarning. If no area can be applied, it is always 422. With returnBase64: false the headers X-Redaction-Partial, X-Redaction-Areas-Applied and X-Redaction-Areas-Discarded carry the warning.
Parameters
NameTypeRequiredDescription
pdf string required Base64-encoded PDF
areas array required Array of areas: [{page, x, y, width, height, color}]
allowPartialAreas boolean optional Accept a document in which some areas could not be applied. Default false: any such area returns 422 with no PDF. When true, the response is 207, never 200. (default: false)
returnBase64 boolean optional Return base64 JSON or raw binary (default: true)
Request Example
JSON
{"pdf": "<base64-pdf>", "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20, "color": "#000000"}, {"page": 1, "x": 300, "y": 400, "width": 200, "height": 20, "color": "#000000"}], "allowPartialAreas": false, "returnBase64": true}
Response Example
PDF
{"pdf": "JVBERi0xLjcK...", "pageCount": 3, "areasApplied": 2}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/RedactPdfArea" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"pdf": "<base64-pdf>", "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20, "color": "#000000"}, {"page": 1, "x": 300, "y": 400, "width": 200, "height": 20, "color": "#000000"}], "allowPartialAreas": false, "returnBase64": true}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""pdf"": ""<base64-pdf>"", ""areas"": [{""page"": 1, ""x"": 100, ""y"": 200, ""width"": 150, ""height"": 20, ""color"": ""#000000""}, {""page"": 1, ""x"": 300, ""y"": 400, ""width"": 200, ""height"": 20, ""color"": ""#000000""}], ""allowPartialAreas"": false, ""returnBase64"": true}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/RedactPdfArea", content);
response.EnsureSuccessStatusCode();

// The response contains a base64-encoded file in the JSON body
var result = await response.Content.ReadAsStringAsync();
using var doc = System.Text.Json.JsonDocument.Parse(result);
var base64 = doc.RootElement.GetProperty("pdf").GetString();
var bytes = Convert.FromBase64String(base64!);
await File.WriteAllBytesAsync("output.pdf", bytes);
import requests
import json
import base64

url = "https://api.docbutterfly.com/api/RedactPdfArea"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"pdf": "<base64-pdf>", "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20, "color": "#000000"}, {"page": 1, "x": 300, "y": 400, "width": 200, "height": 20, "color": "#000000"}], "allowPartialAreas": false, "returnBase64": true}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

# Decode the base64 PDF and save to file
data = response.json()
pdf_bytes = base64.b64decode(data["pdf"])
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("Saved to output.pdf")
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/RedactPdfArea
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "pdf": "\u003Cbase64-pdf\u003E",
│      "areas": [
│        {
│          "page": 1,
│          "x": 100,
│          "y": 200,
│          "width": 150,
│          "height": 20,
│          "color": "#000000"
│        },
│        {
│          "page": 1,
│          "x": 300,
│          "y": 400,
│          "width": 200,
│          "height": 20,
│          "color": "#000000"
│        }
│      ],
│      "allowPartialAreas": false,
│      "returnBase64": true
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/RedactPdfArea"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed

To save the output file:
7. Add a "Parse JSON" action on the HTTP response body
8. Use base64ToBinary(body('Parse_JSON')?['pdf']) to convert
9. Pass the result to a "Create file" action (SharePoint, OneDrive, etc.)
Try in Testbed

Redact PDF (Secure Flatten)

POST /api/RedactPdfFlatten 3 tokens

Securely redacts a PDF by rasterizing each page as an image, compositing black rectangles over redaction areas, and reassembling as a new PDF. Guarantees text is permanently removed — not just covered. Supports text/regex search, coordinate-based areas, and template-based AI field detection.

At least one of 'redactions' or 'areas' must be provided. Higher DPI produces better quality but increases processing time and file size. When areas are sent, the response carries areaResults (one entry per area: applied true or false, and a reason when false). When a template is used, it carries fieldResults (one entry per requested field, with optional: true for an optional field that was not found). An area or a requested template field that cannot be applied returns 422 with no PDF, unless allowPartialAreas or allowPartialFields (respectively) is true; then the response is 207, never 200, with partial: true or partialFields: true and a redactionWarning. If no area can be applied, it is always 422. With returnBase64: false the X-Redaction-Partial header and its counts (X-Redaction-Areas-Applied, X-Redaction-Areas-Discarded, X-Redaction-Fields-Unresolved, X-Redaction-Fields-Matched) carry the warning.
Parameters
NameTypeRequiredDescription
pdf string required Base64-encoded PDF
redactions array optional Text/regex redactions: [{text, regex}]
areas array optional Area redactions: [{page, x, y, width, height}]
allowPartialAreas boolean optional Accept a document in which some areas could not be applied. Default false: any such area returns 422 with no PDF. When true, the response is 207, never 200. (default: false)
templateId string optional UUID of a saved template — auto-detects field locations for redaction
template object optional Inline template definition: {prebuiltModel, fields: [{fieldKey, label, type, optional}]}. A field marked optional: true that is not found in the document is reported in fieldResults, not refused. One that is found but cannot be blacked out still counts.
redactFields array optional Template field keys to redact (omit to redact all detected fields)
allowPartialFields boolean optional Accept a document in which some requested template fields could not be blacked out. Default false: any such field returns 422 with no PDF. When true, the response is 207, never 200. (default: false)
pages string optional Pages to process: "all" or "1-3,5" (default: all)
dpi number optional Render resolution (higher = better quality, slower) (default: 150)
color string optional Redaction rectangle color (default: #000000)
returnBase64 boolean optional Return base64 JSON or raw binary (default: true)
Request Example
JSON
{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith"}, {"regex": "\\d{3}-\\d{2}-\\d{4}"}], "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20}], "allowPartialAreas": false, "allowPartialFields": false, "dpi": 150, "returnBase64": true}
Response Example
PDF
{"pdf": "JVBERi0xLjcK...", "pageCount": 3, "textRedactions": 5, "areaRedactions": 1}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/RedactPdfFlatten" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith"}, {"regex": "\\d{3}-\\d{2}-\\d{4}"}], "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20}], "allowPartialAreas": false, "allowPartialFields": false, "dpi": 150, "returnBase64": true}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""pdf"": ""<base64-pdf>"", ""redactions"": [{""text"": ""John Smith""}, {""regex"": ""\\d{3}-\\d{2}-\\d{4}""}], ""areas"": [{""page"": 1, ""x"": 100, ""y"": 200, ""width"": 150, ""height"": 20}], ""allowPartialAreas"": false, ""allowPartialFields"": false, ""dpi"": 150, ""returnBase64"": true}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/RedactPdfFlatten", content);
response.EnsureSuccessStatusCode();

// The response contains a base64-encoded file in the JSON body
var result = await response.Content.ReadAsStringAsync();
using var doc = System.Text.Json.JsonDocument.Parse(result);
var base64 = doc.RootElement.GetProperty("pdf").GetString();
var bytes = Convert.FromBase64String(base64!);
await File.WriteAllBytesAsync("output.pdf", bytes);
import requests
import json
import base64

url = "https://api.docbutterfly.com/api/RedactPdfFlatten"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"pdf": "<base64-pdf>", "redactions": [{"text": "John Smith"}, {"regex": "\\d{3}-\\d{2}-\\d{4}"}], "areas": [{"page": 1, "x": 100, "y": 200, "width": 150, "height": 20}], "allowPartialAreas": false, "allowPartialFields": false, "dpi": 150, "returnBase64": true}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

# Decode the base64 PDF and save to file
data = response.json()
pdf_bytes = base64.b64decode(data["pdf"])
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("Saved to output.pdf")
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/RedactPdfFlatten
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "pdf": "\u003Cbase64-pdf\u003E",
│      "redactions": [
│        {
│          "text": "John Smith"
│        },
│        {
│          "regex": "\\d{3}-\\d{2}-\\d{4}"
│        }
│      ],
│      "areas": [
│        {
│          "page": 1,
│          "x": 100,
│          "y": 200,
│          "width": 150,
│          "height": 20
│        }
│      ],
│      "allowPartialAreas": false,
│      "allowPartialFields": false,
│      "dpi": 150,
│      "returnBase64": true
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/RedactPdfFlatten"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed

To save the output file:
7. Add a "Parse JSON" action on the HTTP response body
8. Use base64ToBinary(body('Parse_JSON')?['pdf']) to convert
9. Pass the result to a "Create file" action (SharePoint, OneDrive, etc.)
Try in Testbed