PII PII Guard API
v3.1.0 OpenAPI
PII Guard API · v1

Detect and redact personal data in one call

A single HTTPS endpoint finds names, emails, phone numbers, payment cards, national identifiers, addresses, IPs and more in free text — then replaces, masks, hashes or reversibly encrypts them. No models to host, no data retained.

Base URL https://pii.api.efficientstack.com · JSON in, JSON out · every response carries an X-Request-Id header — quote it in support requests.

Your first request


      

Try requests interactively — including operator configuration and batching — in the playground.

Authentication

Send your API key as a bearer token on every request. X-API-Key is accepted for clients that cannot set Authorization.

Authorization: Bearer pg_live_7f3kq9xw2mba_…

Keys are shown once at creation and stored only as an irreversible digest, so they cannot be recovered — rotate to replace a lost key. Each key carries a set of permissions (detect, redact, anonymize, deanonymize, read) and its own limits.

Keep keys server-side. Call the API from your backend, never from a browser or mobile client. Issue one key per service so you can rotate or disable them independently, and use test keys in non-production environments.

Billing & usage

Charges are computed per request from three components and a floor:

ComponentUnit priceApplies to
Per request$0.000050Every accepted API call.
Per 1,000 characters$0.000500Total input length across the request.
Minimum charge$0.000050Floor applied to the computed amount.

Failed requests are never charged. Validation errors, permission errors and service faults cost nothing. Only successfully processed calls are metered.

Every billable response reports what it cost in usage.amount, and the running period total is returned in the X-Usage-Month-Amount header. Call GET /v1/usage for period-to-date totals, per-task breakdown and remaining allowances. Billing periods are calendar months in UTC.

Batching is cheaper. The per-request component is charged once regardless of batch size, so submitting 256 documents in one texts array costs less than 256 single-document calls — and is dramatically faster.

Limits

LimitDefaultNotes
Documents per request256Length of the texts array.
Characters per request500,000Summed across all documents.
Request body4 MBHard ceiling.
Allow-list entries1,000Per request.
Operators64Per request.
Monthly allowancesaccount-specificOptional caps on requests, documents or spend. Reported in GET /v1/usage.

Request-shape limits and monthly allowances can both be raised per account. Contact your sales representative at support@efficientstack.com.

There is no fixed requests-per-second cap. Concurrency is shaped adaptively; if you receive a 503 capacity_unavailable, retry with exponential backoff and jitter.

Errors & retries

Errors return a single envelope. type is stable and safe to branch on; code is more specific and may gain new values over time.


      
HTTPtypeWhen
400invalid_requestMalformed body, unknown operator type, batch too large, threshold out of range.
401authentication_errorMissing, malformed, disabled, revoked or expired API key.
402limit_errorA monthly request, document or spend limit on the key has been reached.
403permission_errorThe key is not permitted to call this endpoint.
404not_foundUnknown endpoint, or a job that does not belong to this key.
413invalid_requestBody above 4 MB, or input above the character limit for the key.
429invalid_requestReserved. Concurrency is shaped, not hard-limited — retry with backoff if you receive it.
5xxservice_errorTransient service fault. Retry with exponential backoff; quote request_id if it persists.

Retry 5xx responses; do not retry 4xx without changing the request. A robust policy is three attempts at 1 s, 3 s and 9 s with ±20% jitter, carrying the same Idempotency-Key.

Idempotency

Send Idempotency-Key: <uuid> on any POST. The first successful response is stored for 24 hours and replayed verbatim for any retry using the same key, flagged with Idempotent-Replay: true. Retries are never charged twice.

-H "Idempotency-Key: 8f14e45f-ea0b-4d1c-9c1a-6b2f0e5c7a91"

POST /v1/detect

Locates personal data and returns spans with confidence scores. The document is never modified.

permission: detect billable
ParameterTypeDescription
text string A single document to analyze. Mutually exclusive with texts.
texts string[] A batch of documents processed in one call.
language string = "en" Analyzer language. See GET /v1/entities.
score_threshold number = 0.35 Minimum confidence, 0–1. Lower values find more entities with more false positives.
entities string[] Restrict detection to these entity types. Omit to run every recognizer.
allow_list string[] Exact strings suppressed before scoring — your own support address, test card numbers, and so on.
mode "full" | "fast" = "full" fast uses deterministic pattern recognizers only: lower latency, no contextual name detection.
include_text boolean = false Echo the matched substring in each entity. Off by default so detected values never travel back over the wire.

Request body


    

Response


  

POST /v1/redact

Detects and transforms in a single pass. Returns redacted_text per document plus an audit trail of every operator applied.

permission: redact billable
ParameterTypeDescription
text string A single document to analyze. Mutually exclusive with texts.
texts string[] A batch of documents processed in one call.
language string = "en" Analyzer language. See GET /v1/entities.
score_threshold number = 0.35 Minimum confidence, 0–1. Lower values find more entities with more false positives.
entities string[] Restrict detection to these entity types. Omit to run every recognizer.
allow_list string[] Exact strings suppressed before scoring — your own support address, test card numbers, and so on.
mode "full" | "fast" = "full" fast uses deterministic pattern recognizers only: lower latency, no contextual name detection.
include_text boolean = false Echo the matched substring in each entity. Off by default so detected values never travel back over the wire.
operators object Per-entity transformation map, keyed by entity type or DEFAULT. See Operators.

Request body


    

Response


  

POST /v1/anonymize

Same shape as redact, intended for reversible encrypt operators. Your encryption key is used in memory for the request and never stored.

permission: anonymize billable
ParameterTypeDescription
text string A single document to analyze. Mutually exclusive with texts.
texts string[] A batch of documents processed in one call.
language string = "en" Analyzer language. See GET /v1/entities.
score_threshold number = 0.35 Minimum confidence, 0–1. Lower values find more entities with more false positives.
entities string[] Restrict detection to these entity types. Omit to run every recognizer.
allow_list string[] Exact strings suppressed before scoring — your own support address, test card numbers, and so on.
mode "full" | "fast" = "full" fast uses deterministic pattern recognizers only: lower latency, no contextual name detection.
include_text boolean = false Echo the matched substring in each entity. Off by default so detected values never travel back over the wire.
operators object Per-entity transformation map, keyed by entity type or DEFAULT. See Operators.

Request body


    
  

POST /v1/deanonymize

Reverses an encrypt anonymization. operators is required and must carry the same key.

permission: deanonymize billable
ParameterTypeDescription
text * string A previously anonymized document.
operators * object Per-entity transformation map, keyed by entity type or DEFAULT. See Operators.

POST /v1/jobs

Queues a large batch and returns immediately with a job id. Use this for very large batches or when your client cannot hold a long-lived connection.

permission: detect / redact billable
ParameterTypeDescription
task * string detect, redact, anonymize or deanonymize.
text string A single document to analyze. Mutually exclusive with texts.
texts string[] A batch of documents processed in one call.
language string = "en" Analyzer language. See GET /v1/entities.
score_threshold number = 0.35 Minimum confidence, 0–1. Lower values find more entities with more false positives.
entities string[] Restrict detection to these entity types. Omit to run every recognizer.
allow_list string[] Exact strings suppressed before scoring — your own support address, test card numbers, and so on.
mode "full" | "fast" = "full" fast uses deterministic pattern recognizers only: lower latency, no contextual name detection.
include_text boolean = false Echo the matched substring in each entity. Off by default so detected values never travel back over the wire.

Response


  

GET /v1/jobs/{id}

Polls a queued job. Jobs are scoped to the API key that created them and expire after 24 hours.

permission: read no charge

GET /v1/entities

Every entity type the service can detect, per language.

permission: read no charge

GET /v1/info

Languages, entity types, the request limits that apply to your key, and your rate card.

permission: read no charge

GET /v1/health

Returns operational, or 503 with degraded. Safe to poll from an uptime monitor.

no charge

GET /v1/usage

Current billing-period counters for the calling key: requests, documents, characters, amount charged and remaining allowances.

permission: read no charge

Response


  

Operators

Operators drive /v1/redact, /v1/anonymize and /v1/deanonymize. Keys are entity types; DEFAULT catches everything not named explicitly.

TypeParametersBehaviour
replacenew_value?Substitutes a literal. Omit for the <ENTITY_TYPE> placeholder. Max 512 characters.
redactRemoves the span entirely.
maskmasking_char, chars_to_mask, from_endMasks N characters with one character, from the start or the end. N ≤ 1000.
hashhash_typeDeterministic sha256 / sha512 / md5 — preserves joinability without exposing values.
encryptkeyAES with a 16, 24 or 32-byte key. Reversible through /v1/deanonymize.
keepLeaves the span untouched — carve exceptions out of DEFAULT.

Example


    

Data handling

  • No document retention. Text exists only in memory for the lifetime of the request. It is never written to storage, logs or analytics.
  • Metering is metadata-only — request counts, document counts, character counts, entity counts, latency and the amount charged.
  • include_text is off by default, so detected values never travel back over the wire unless you ask for them.
  • Encryption keys stay yours. They are used for the request and discarded; they are never logged or stored.
  • TLS 1.2+ everywhere, terminated at the nearest edge location to your client.

Questions about data residency, DPAs or SOC 2 reporting: support@efficientstack.com.