FastPII Docs
Detection API

Detection API

Production REST API for PII detection and validation with Intelligence Engine auto-detection.

Detection API

The Detection API is FastPII's production REST API for detecting and validating PII at https://api.fastpii.com/api/v1/. It is separate from the open-source SDK's built-in FastAPI integration, which you can self-host inside your own application.

If you want the in-process SDK workflow instead of the hosted API, see the SDK Detection guide and the FastAPI integration guide.

Authentication

Send your API key in the Authorization header for every request:

Authorization: Bearer fpk_your_api_key

Requests without a valid API key return 401 Unauthorized.

Base URL

https://api.fastpii.com/api/v1/

Rate limits

The Detection API applies per-key rate limiting to protect shared production capacity.

LimitValue
Default request rate60 requests per minute
Burst limit10 concurrent requests
Batch detectionCounts as 1 request toward rate limits

When you hit the limit, the API returns 429 Too Many Requests. Rate limit headers may include:

HeaderDescription
X-RateLimit-LimitRequests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp for the next reset
Retry-AfterSeconds to wait before retrying

POST /api/v1/detect

Detect and validate PII entities in a single text payload. If country is omitted or set to null, the Intelligence Engine auto-detects the most likely countries from the content.

Request body

DetectRequest

FieldTypeRequiredDescription
textstringYesInput text to analyze, 1 to 50000 characters
countrystring | nullNoISO country code. If null, the API auto-detects the country or countries
languagestring | nullNoLanguage hint such as "en", "de", or "fr"
privacy_presetstringNoDetection sensitivity preset: "conservative", "balanced", or "aggressive"
{
  "text": "Customer email is jana.novakova@example.cz and rodne cislo 8053121234.",
  "country": "CZ",
  "language": "cs",
  "privacy_preset": "balanced"
}

Response body

DetectResponse

FieldTypeDescription
textstringOriginal input text
entitiesDetectedEntity[]Detected and validated entities
countries_detectedCountryDetection[]Countries inferred from the text
privacy_presetstringEffective privacy preset used for detection
processing_time_msintegerEnd-to-end processing time in milliseconds
api_versionstringAPI version that served the request

DetectedEntity

FieldTypeDescription
typestringEntity type such as "email", "rodne_cislo", "pesel", or "phone_number"
originalstringExact matched text from the input
countrystring | nullCountry associated with the detector
confidencenumberConfidence score from 0 to 1
validatedbooleanWhether the value passed checksum or structural validation
startintegerZero-based start offset
endintegerZero-based end offset
metadataobjectDetector-specific metadata

CountryDetection

FieldTypeDescription
codestringISO country code
confidencenumberConfidence score from 0 to 1

Example: simple single-country detection

curl -X POST "https://api.fastpii.com/api/v1/detect" \
  -H "Authorization: Bearer fpk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Contact Jana Novakova at jana.novakova@example.cz or 775 123 456.",
    "country": "CZ",
    "language": "cs",
    "privacy_preset": "balanced"
  }'
import requests

response = requests.post(
    "https://api.fastpii.com/api/v1/detect",
    headers={
        "Authorization": "Bearer fpk_your_api_key",
        "Content-Type": "application/json",
    },
    json={
        "text": "Contact Jana Novakova at jana.novakova@example.cz or 775 123 456.",
        "country": "CZ",
        "language": "cs",
        "privacy_preset": "balanced",
    },
    timeout=30,
)

print(response.status_code)
print(response.json())

Response:

{
  "text": "Contact Jana Novakova at jana.novakova@example.cz or 775 123 456.",
  "entities": [
    {
      "type": "email",
      "original": "jana.novakova@example.cz",
      "country": "CZ",
      "confidence": 0.99,
      "validated": true,
      "start": 25,
      "end": 49,
      "metadata": {
        "normalized": "jana.novakova@example.cz"
      }
    },
    {
      "type": "phone_number",
      "original": "775 123 456",
      "country": "CZ",
      "confidence": 0.95,
      "validated": true,
      "start": 53,
      "end": 64,
      "metadata": {
        "e164": "+420775123456",
        "line_type": "mobile"
      }
    }
  ],
  "countries_detected": [
    {
      "code": "CZ",
      "confidence": 0.99
    }
  ],
  "privacy_preset": "balanced",
  "processing_time_ms": 18,
  "api_version": "v1"
}

Example: multi-country auto-detection

Use country: null when your input may contain identifiers from more than one market.

curl -X POST "https://api.fastpii.com/api/v1/detect" \
  -H "Authorization: Bearer fpk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "PESEL 44051401458 belongs to Jan Kowalski. French billing record includes SIREN 552120222 and email compta@exemple.fr.",
    "country": null,
    "language": "en",
    "privacy_preset": "balanced"
  }'
import requests

response = requests.post(
    "https://api.fastpii.com/api/v1/detect",
    headers={
        "Authorization": "Bearer fpk_your_api_key",
        "Content-Type": "application/json",
    },
    json={
        "text": "PESEL 44051401458 belongs to Jan Kowalski. French billing record includes SIREN 552120222 and email compta@exemple.fr.",
        "country": None,
        "language": "en",
        "privacy_preset": "balanced",
    },
    timeout=30,
)

print(response.json())

Response:

{
  "text": "PESEL 44051401458 belongs to Jan Kowalski. French billing record includes SIREN 552120222 and email compta@exemple.fr.",
  "entities": [
    {
      "type": "pesel",
      "original": "44051401458",
      "country": "PL",
      "confidence": 1.0,
      "validated": true,
      "start": 6,
      "end": 17,
      "metadata": {
        "birth_date": "1944-05-14",
        "gender": "male",
        "checksum_valid": true
      }
    },
    {
      "type": "siren",
      "original": "552120222",
      "country": "FR",
      "confidence": 1.0,
      "validated": true,
      "start": 83,
      "end": 92,
      "metadata": {
        "checksum_valid": true
      }
    },
    {
      "type": "email",
      "original": "compta@exemple.fr",
      "country": "FR",
      "confidence": 0.98,
      "validated": true,
      "start": 103,
      "end": 120,
      "metadata": {
        "normalized": "compta@exemple.fr"
      }
    }
  ],
  "countries_detected": [
    {
      "code": "FR",
      "confidence": 0.96
    },
    {
      "code": "PL",
      "confidence": 0.94
    }
  ],
  "privacy_preset": "balanced",
  "processing_time_ms": 27,
  "api_version": "v1"
}

Example: selective detection with privacy_preset

Use a stricter preset when you only want high-confidence matches, or an aggressive preset when you would rather catch more possible PII for review.

curl -X POST "https://api.fastpii.com/api/v1/detect" \
  -H "Authorization: Bearer fpk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Reach me at maria.schmidt@example.de, tax id 86095742719, office line 030 1234567.",
    "country": "DE",
    "language": "de",
    "privacy_preset": "aggressive"
  }'
import requests

payload = {
    "text": "Reach me at maria.schmidt@example.de, tax id 86095742719, office line 030 1234567.",
    "country": "DE",
    "language": "de",
    "privacy_preset": "aggressive",
}

response = requests.post(
    "https://api.fastpii.com/api/v1/detect",
    headers={
        "Authorization": "Bearer fpk_your_api_key",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=30,
)

print(response.json())

Response:

{
  "text": "Reach me at maria.schmidt@example.de, tax id 86095742719, office line 030 1234567.",
  "entities": [
    {
      "type": "email",
      "original": "maria.schmidt@example.de",
      "country": "DE",
      "confidence": 0.99,
      "validated": true,
      "start": 12,
      "end": 37,
      "metadata": {
        "normalized": "maria.schmidt@example.de"
      }
    },
    {
      "type": "steuer_id",
      "original": "86095742719",
      "country": "DE",
      "confidence": 1.0,
      "validated": true,
      "start": 46,
      "end": 57,
      "metadata": {
        "checksum_valid": true
      }
    },
    {
      "type": "phone_number",
      "original": "030 1234567",
      "country": "DE",
      "confidence": 0.88,
      "validated": true,
      "start": 71,
      "end": 82,
      "metadata": {
        "e164": "+49301234567",
        "line_type": "fixed_line"
      }
    }
  ],
  "countries_detected": [
    {
      "code": "DE",
      "confidence": 0.98
    }
  ],
  "privacy_preset": "aggressive",
  "processing_time_ms": 21,
  "api_version": "v1"
}

POST /api/v1/validate

Validate a single value against a specific entity type and optional country.

Request body

ValidateRequest

FieldTypeRequiredDescription
valuestringYesRaw value to validate
entity_typestringYesEntity type to validate against
countrystring | nullNoISO country code when validation should be country-specific
{
  "value": "44051401458",
  "entity_type": "pesel",
  "country": "PL"
}

Response body

ValidateResponse

FieldTypeDescription
valuestringOriginal input value
entity_typestringEntity type used for validation
countrystring | nullCountry used during validation
validbooleanWhether the value passed validation
confidencenumberConfidence score from 0 to 1
metadataobjectValidation metadata such as checksum status or normalized values
curl -X POST "https://api.fastpii.com/api/v1/validate" \
  -H "Authorization: Bearer fpk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "value": "44051401458",
    "entity_type": "pesel",
    "country": "PL"
  }'
import requests

response = requests.post(
    "https://api.fastpii.com/api/v1/validate",
    headers={
        "Authorization": "Bearer fpk_your_api_key",
        "Content-Type": "application/json",
    },
    json={
        "value": "44051401458",
        "entity_type": "pesel",
        "country": "PL",
    },
    timeout=30,
)

print(response.json())

Response:

{
  "value": "44051401458",
  "entity_type": "pesel",
  "country": "PL",
  "valid": true,
  "confidence": 1.0,
  "metadata": {
    "checksum_valid": true,
    "birth_date": "1944-05-14",
    "gender": "male"
  }
}

GET /api/v1/detectors

List available detectors. You can filter the catalog by country code.

Query parameters

ParameterTypeRequiredDescription
countrystringNoISO country code filter such as CZ, DE, FR, or PL

Response body

DetectorsResponse

FieldTypeDescription
detectorsDetectorInfo[]Available detectors
countintegerNumber of returned detectors

DetectorInfo

FieldTypeDescription
namestringStable detector name
descriptionstringHuman-readable detector summary
regionstringRegion or country code
categorystringDetector category such as identity, contact, or financial
curl -X GET "https://api.fastpii.com/api/v1/detectors?country=DE" \
  -H "Authorization: Bearer fpk_your_api_key"
import requests

response = requests.get(
    "https://api.fastpii.com/api/v1/detectors",
    headers={"Authorization": "Bearer fpk_your_api_key"},
    params={"country": "DE"},
    timeout=30,
)

print(response.json())

Response:

{
  "detectors": [
    {
      "name": "steuer_id",
      "description": "German tax identification number with checksum validation.",
      "region": "DE",
      "category": "identity"
    },
    {
      "name": "phone_de",
      "description": "German landline and mobile phone number detection.",
      "region": "DE",
      "category": "contact"
    },
    {
      "name": "address_de",
      "description": "German address pattern detection with city and postal code support.",
      "region": "DE",
      "category": "location"
    },
    {
      "name": "iban",
      "description": "International bank account number detection and validation.",
      "region": "DE",
      "category": "financial"
    }
  ],
  "count": 4
}

Error responses

The API uses standard HTTP status codes and returns a JSON error payload.

StatusMeaningTypical cause
400Bad RequestInvalid JSON, missing required fields, or text outside allowed limits
401UnauthorizedMissing API key or invalid bearer token
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server-side failure

400 Bad Request

{
  "error": {
    "code": "invalid_request",
    "message": "Field 'text' must contain between 1 and 50000 characters.",
    "details": {
      "field": "text"
    }
  }
}

401 Unauthorized

{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid API key."
  }
}

429 Too Many Requests

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry after 12 seconds."
  }
}

500 Internal Server Error

{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred while processing the request."
  }
}

Next steps

Use the hosted Detection API when you want managed production infrastructure, API keys, and centralized rate limiting. If you want embedded detection inside your Python app, continue with the SDK Detection guide.

On this page