API Integration Guide

Learn how to integrate piisafe.eu's PII detection system with the anonym.legal API. Complete reference with examples, rate limits, and error handling.

Overview

The piisafe.eu scanner API is a small HTTP interface for starting a website scan, polling its progress and fetching its findings. A scan session is a server-side record that exists in memory only: it holds the crawl queue, the findings so far and the counters the browser polls, and it is deleted 35 minutes after the scan ends. A finding is a single detected entity — its type, the page it was found on and its position in that page's text.

piisafe.eu integrates with the anonym.legal PII detection API to scan websites for exposed personal information:

  • 58 entity types covering personal identifiers, financial data, contact details, health records and national IDs
  • 24 compliance presets (GDPR, HIPAA, PCI-DSS, regional)
  • 48 languages — 43 with a dedicated language model, 5 served by a fallback model

The API uses hybrid detection combining machine learning models with deterministic regex patterns for highly accurate PII identification across all 48 supported languages.

Note: Your browser talks to the piisafe.eu server, which proxies detection requests to anonym.legal with your API key. The key is saved in your browser's localStorage and passes through the server per request — it is never stored or logged server-side.

Detection API

anonym.legal

PII Detection & Anonymization

Entity Types: 58
Presets: 24 (GDPR, HIPAA, PCI-DSS, regional)
Languages: 48 (43 native models, 5 fallback)
Detection Method: ML + Regex hybrid
Character Limit: 50,000 per call
Rate Limits: by subscription tier
MCP Server: Available for integration
Entry Cost: from €3/month

API Endpoints

Base URL: https://anonym.legal

Endpoint Method Purpose
/api/presidio/analyze POST Detect PII entities in text
/api/presidio/anonymize POST Replace detected entities with placeholders
/api/presidio/deanonymize POST Restore original values from placeholders
/api/mcp/image POST Detect and redact PII in images
/api/health GET Service health check

piisafe.eu never calls these endpoints directly from the browser. It proxies them through its own routes:

piisafe.eu Route Method Purpose
/api/anonym/test POST Validate an API key
/api/anonym/catalog GET Entity, preset and language catalog
/api/anonym/analyze POST Analyze text for PII
/api/anonym/anonymize POST Anonymize text
/api/anonym/deanonymize POST De-anonymize text

Detection Capabilities

Entity Category anonym.legal Examples
Identifiers SSN, Tax ID, Passport, Driver License
Financial Credit Card, IBAN, SWIFT, Bank Account
Contact Email, Phone, Address, IP Address
Healthcare Medical Records, Insurance ID, Prescription
Regional Specific ✓ (All 48 languages) German Tax, French CNI, Italian CODICE

Getting Started

Step 1: Get an API Key

  1. Visit https://anonym.legal
  2. Choose a pricing plan (API access starts at €3/month)
  3. Access "Settings" → "API Credentials"
  4. Your API key is auto-generated
  5. Copy the key to use in piisafe.eu
Security: Never share your API key. In piisafe.eu it is saved in your browser's localStorage and sent with each scan request; it is never stored or logged server-side.

Step 2: Enter API Key in piisafe.eu

  1. Go to https://piisafe.eu/scanner.html
  2. Click "Scanner" in the navigation
  3. Enter your anonym.legal API key
  4. Click "Validate Key" to confirm

Step 3: Configure Detection Settings

After validation, choose:

  • Compliance Preset: GDPR, HIPAA, PCI-DSS, CCPA, or custom
  • Language: 48+ languages for region-specific patterns
  • Entity Threshold: Confidence score (60-95%)

API Flow Diagram

Here's how piisafe.eu orchestrates the scanning process:

┌─────────────────────────────────┐ │ User Enters Website URL │ │ + API Key + Settings │ └──────────────┬──────────────────┘ │ ▼ ┌──────────────────┐ │ URL Discovery │ │ (Sitemap/Crawl) │ └────────┬─────────┘ │ ┌────────▼──────────┐ │ User Selects │ │ Pages to Scan │ └────────┬──────────┘ │ ┌────────▼──────────────────┐ │ Fetch Page Content │ │ (HTML → Extract Text) │ └────────┬──────────────────┘ │ ┌────────▼───────────────┐ │ Check Text Length │ │ 50,000 chars limit? │ └────────┬───────────────┘ │ ┌─────────┴────────┐ │ │ YES NO │ │ ▼ ▼ CHUNKING SEND TO API (Split Text) (Direct) │ │ ├─────────┬────────┘ │ │ ▼ ▼ ┌──────────────────────┐ │ Call Detection API │ │ (anonym.legal) │ └────────┬─────────────┘ │ ┌─────▼──────┐ │ More Chunks? └─────┬──────┘ │ ┌───┴───┐ YES NO │ │ ▼ ▼ CONTINUE AGGREGATE (Loop) RESULTS │ ▼ ┌──────────────────────┐ │ Real-Time Results │ │ + Risk Grade (A-F) │ │ + Findings List │ │ + Statistics │ └────────┬─────────────┘ │ ▼ ┌──────────────────┐ │ User Exports: │ │ • HTML Report │ │ • JSON Data │ │ • CSV Spreadsheet│ └──────────────────┘

Supported Entity Types

anonym.legal detects and classifies 58 entity types, grouped into the following categories:

Core Entity Categories

  • Universal: CREDIT_CARD, CRYPTO, DATE_TIME, EMAIL_ADDRESS, IBAN_CODE, IP_ADDRESS, LOCATION, NRP, PERSON, PHONE_NUMBER, URL
  • Personal Identifiers: AGE
  • Financial Data: SWIFT_CODE
  • Health & Medical: ICD_CODE, MEDICAL_LICENSE, MEDICAL_RECORD_NUMBER
  • Digital & Technical: MAC_ADDRESS
  • Vehicle & Transport: VIN
  • Organization: ORGANIZATION
  • Education: STUDENT_ID
  • Legal: BAR_NUMBER, CASE_NUMBER
  • United Kingdom: UK_NHS, UK_DRIVER_LICENSE, UK_NINO, UK_PASSPORT
  • United States: US_BANK_NUMBER, US_DRIVER_LICENSE, US_ITIN, US_PASSPORT, US_SSN
  • European Union: BG_EGN, CZ_RODNE_CISLO, EE_ID_CARD, LV_ID_CARD, LV_PERSONAS_KODS, SK_RODNE_CISLO
  • Asia-Pacific: AU_ABN, AU_ACN, AU_MEDICARE, AU_TFN, AU_PASSPORT, AU_DRIVER_LICENSE, IN_AADHAAR, IN_PAN, IN_PASSPORT, NZ_PASSPORT, NZ_IRD, NZ_NHI, NZ_DRIVER_LICENSE, SG_UEN, SG_PASSPORT
  • Americas: CA_PASSPORT, CA_SIN, CA_DRIVER_LICENSE
  • Africa & Middle East: IL_ID_NUMBER, TR_DRIVER_LICENSE, TR_KIMLIK_NO

Regional & Language-Specific Entities

48 languages are supported for text analysis. Dedicated national identifier types exist for 14 countries:

  • United States: US_SSN, US_ITIN, US_PASSPORT, US_DRIVER_LICENSE, US_BANK_NUMBER
  • United Kingdom: UK_NINO, UK_NHS, UK_PASSPORT, UK_DRIVER_LICENSE
  • Australia: AU_TFN, AU_ABN, AU_ACN, AU_MEDICARE, AU_PASSPORT, AU_DRIVER_LICENSE
  • New Zealand: NZ_PASSPORT, NZ_IRD, NZ_NHI, NZ_DRIVER_LICENSE
  • India: IN_AADHAAR, IN_PAN, IN_PASSPORT
  • Canada: CA_SIN, CA_PASSPORT, CA_DRIVER_LICENSE
  • Turkey: TR_KIMLIK_NO, TR_DRIVER_LICENSE
  • Latvia: LV_ID_CARD, LV_PERSONAS_KODS
  • Bulgaria, Czechia, Slovakia, Estonia, Israel, Singapore: BG_EGN, CZ_RODNE_CISLO, SK_RODNE_CISLO, EE_ID_CARD, IL_ID_NUMBER, SG_UEN, SG_PASSPORT
  • Content from any other country is covered by the universal types: names, e-mail addresses, phone numbers, IBANs, credit cards, locations and organisations
Pro Tip: Select your target region's language in the "Configure" step for maximum accuracy on region-specific IDs.

Chunking Strategy (Smart Splitting)

Since the API has a 50,000 character limit per request, piisafe.eu uses intelligent chunking to analyze pages of any size:

How Chunking Works

  1. Measure: Check extracted text length
  2. Split: If > 49,500 chars, split at word boundaries
  3. Process: Send each chunk to API sequentially
  4. Offset: Adjust entity positions to original text location
  5. Aggregate: Combine results across all chunks

Chunking Configuration

Parameter Value Rationale
Max Characters 50,000 API hard limit
Safety Margin 49,500 Prevents boundary issues
Split Method Word Boundary Preserves sentence/word integrity
Processing Sequential Respects rate limits
Retry Logic 3 attempts per chunk Handles transient failures

Example: 65KB Page Scanning

Input: 65,000 character HTML page ↓ Exceeds 50,000 limit ↓ Chunk 1: Characters 0-49,500 Chunk 2: Characters 49,501-65,000 ↓ Send Chunk 1 → API → Detect entities Send Chunk 2 → API → Detect entities ↓ Aggregate Results - Adjust entity offsets to original document - Merge duplicate findings (if spans chunks) - Calculate overall statistics ↓ Return: Complete entity list with accurate positions
Benefit: Pages of unlimited size can be scanned. Before chunking, pages >50KB would fail. Now, 100% of text is analyzed.

Cost Trade-off: A 65KB page requires 2 API calls instead of 1, doubling token usage for that page. However, this is better than partial scanning (23% data loss).

Rate Limits & Quotas

piisafe.eu Rate Limiting (Server-Side)

Limit Value Applies To
API Requests 30 per minute /api/anonym/* general proxy
PII Scan Starts 20 per hour New PII scans
PII Scan Polling 120 per minute All /api/scanner/* routes
Dead-Link Scan Starts 30 per hour New dead-link scans
Dead-Link Scan Polling 120 per minute All /api/deadlinks/* routes
Max Pages/PII Scan 1,000 Per-scan cap
Max Pages/Dead-Link Scan 500 Per-scan cap
Session Timeout 35 minutes Abandoned scans
Request Body Size 10MB max POST payload sent to the API - this is not a cap on scan result size

Starting a PII scan consumes both buckets: the request counts against the 20-per-hour start limit and against the shared 120-per-minute limit that covers every /api/scanner/* route. There is no separate cap on how many scans may run at the same time.

  • €3/month entry tier (limited requests)
  • Higher plans available (contact sales)
  • Rate limits vary by tier
  • Token quotas per plan - see the anonym.legal dashboard

Handling Rate Limit Errors

If you receive a 429 (Too Many Requests) error:

  1. Wait 15-30 seconds before retrying
  2. Reduce concurrent scan count
  3. Verify your anonym.legal subscription is active
  4. Contact anonym.legal support if the issue persists
Note: Chunking increases API calls. A 100KB page = 2 API calls. Plan token budget accordingly.

Pricing & Costs

Plan Cost API Calls Features
Starter €3/month 100/month Individual use
Pro €19/month 1,000/month Teams, higher limits
Enterprise Custom Custom Unlimited, support, SLA

Cost Estimation

Example: Scanning 10 websites (average 20 pages per site = 200 pages total)

With anonym.legal (Starter):

  • €3/month base cost
  • 100 API calls/month included
  • Overflow calls billed separately (typically €0.01-0.05 per call)
  • 200 pages may require additional tier or overflow costs
Recommendation: Test with a small scan first to estimate token usage for your use case.

Error Handling & Troubleshooting

Common Error Codes

400 Bad Request
Meaning: Malformed API request or invalid parameters
Solution: Check API key format, ensure text encoding is UTF-8, verify entity list syntax
401 Unauthorized
Meaning: API key is invalid, expired, or missing
Solution: Regenerate API key in provider dashboard, verify key is copied correctly, check for extra spaces
403 Forbidden
Meaning: API key valid but account doesn't have permission for this operation
Solution: Verify account subscription is active, check if specific entities require higher tier
429 Too Many Requests
Meaning: Rate limit exceeded or token quota exhausted
Solution: Wait 15-30 seconds, reduce concurrent scans, upgrade account tier, or add tokens
500 Internal Server Error
Meaning: Provider API encountered an internal error
Solution: Wait 1-2 minutes, retry scan, contact provider support if persists
503 Service Unavailable
Meaning: API is temporarily down or undergoing maintenance
Solution: Wait and retry later, check provider status page, contact support
ContentLengthExceeded
Meaning: Text exceeds 50,000 character limit (shouldn't happen with chunking)
Solution: Verify chunking is enabled, check page wasn't corrupted during fetch, retry
InvalidEntityType
Meaning: Selected entity doesn't exist in API catalog
Solution: Use provided catalog dropdown, verify entity name spelling, refresh entity list

Network & Connectivity Issues

Timeout errors: If scan stalls after 30+ seconds, the API may be slow or unreachable:

  • Check your internet connection
  • Verify browser console for network errors (F12)
  • Try a smaller scan (fewer pages)
  • Check the API status at https://anonym.legal/api/health

CORS (Cross-Origin) errors: If you see "CORS policy" error in console:

  • This is expected for cross-domain API calls
  • piisafe.eu uses CORS proxying on backend
  • No action needed—should resolve automatically
  • If persists, contact support

Debug Mode

Open browser DevTools (F12) to see detailed error logs:

# In browser console, view API responses: localStorage.getItem('pii_scan_logs') // Recent scan errors localStorage.getItem('pii_api_errors') // API error details

For support, collect these details:

  • Error message (exact text)
  • URL being scanned
  • Browser console screenshot
  • Timestamp of error

Code Examples

Example 1: Validating API Key (JavaScript/Frontend)

// Test API key for anonym.legal async function validateApiKey(apiKey) { const response = await fetch('/api/anonym/test', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey }) }); const data = await response.json(); if (data.valid) { console.log('✓ Key valid'); localStorage.setItem('scanner_apiKey', apiKey); } else { console.error('✗ Invalid key:', data.error); } }

Example 2: Sending Text for Analysis

// Analyze text with the anonym.legal API async function analyzeText(text, entities, apiKey) { const response = await fetch('/api/anonym/analyze', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ apiKey, text, entityTypes: entities, language: 'en' }) }); const findings = await response.json(); return findings; // Array of detected entities }

Example 3: Chunking Text (50K Limit)

// Split text at word boundaries function chunkText(text, maxChars = 49500) { const chunks = []; let currentChunk = ''; text.split(/\s+/).forEach(word => { if ((currentChunk + word).length > maxChars) { if (currentChunk) chunks.push(currentChunk); currentChunk = word; } else { currentChunk += (currentChunk ? ' ' : '') + word; } }); if (currentChunk) chunks.push(currentChunk); return chunks; } // Usage const text = fetchPageContent('https://example.com'); const chunks = chunkText(text); for (let i = 0; i < chunks.length; i++) { const results = await analyzeText( chunks[i], entityList, apiKey ); console.log(`Chunk ${i+1}/${chunks.length}: ${results.length} entities found`); }

Example 4: Handling Real-Time Progress (Polling)

The status route answers with a single JSON document, not an event stream - poll it on an interval. This is what the scanner UI itself does.

// Poll scan progress until the scan finishes function watchScan(scanSessionId, intervalMs = 1000) { let misses = 0; const timer = setInterval(async () => { const response = await fetch(`/api/scanner/status/${scanSessionId}`); const result = await response.json(); if (!result.success) { // 404 once the session is gone, 429 while rate-limited - // stop after a few consecutive failures instead of spinning forever if (++misses >= 5) clearInterval(timer); return; } misses = 0; const p = result.progress; const percent = p.pagesTotal > 0 ? Math.round((p.pagesScanned / p.pagesTotal) * 100) : 0; // the API does not send a percent field console.log(`Pages: ${p.pagesScanned}/${p.pagesTotal}`); console.log(`PII Found: ${p.piiFound}`); console.log(`Progress: ${percent}%`); // terminal states: complete, stopped, error if (result.status !== 'running') { clearInterval(timer); } }, intervalMs); return () => clearInterval(timer); // call to stop watching early }

Example 5: Exporting Results

// Export scan results as JSON async function exportResults(scanId) { const response = await fetch(`/api/scanner/report/${scanId}?format=json`); const data = await response.json(); // Download JSON file const blob = new Blob([JSON.stringify(data, null, 2)]); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `pii-scan-${scanId}.json`; a.click(); } // Available formats: 'json', 'csv', 'html'

Frequently Asked Questions

Getting API Keys

Q: Can I use the same API key across multiple devices?

A: Yes. API keys are account-based, not device-specific. Store securely and avoid sharing publicly.

Q: What if I lose my API key?

A: Regenerate it in your provider dashboard. Old key becomes invalid immediately. Update piisafe.eu with new key.

Q: Is there a free tier?

A: Not for API access. anonym.legal's free plan does not include API keys; API plans start at €3/month. Check the anonym.legal dashboard for current tiers.

Scanning & Detection

Q: What happens if a page has no PII?

A: Scan completes successfully with an "A" grade. Findings list is empty. API call still counts against quota.

Q: Can I scan password-protected websites?

A: No. piisafe.eu scans public HTML only. For protected content, export HTML manually, then upload as raw text.

Q: How accurate is PII detection?

A: The API uses an ML + regex hybrid model. Accuracy: 85-95% depending on entity type and regional variations. Some false positives/negatives possible. Manual review recommended.

Q: Does the chunking affect detection accuracy?

A: No. Chunking splits at word boundaries, preserving context. Results are identical to single-chunk processing.

Pricing & Costs

Q: What's the cheapest way to scan many pages?

A: anonym.legal Pro (€19/month) offers 1,000 API calls/month — the lowest cost per scan. For higher volumes, the Enterprise tier scales beyond that.

Q: Do chunked pages cost more?

A: Yes. A 100KB page = 2 API calls = 2× token cost. However, 100% of text is analyzed vs. partial scanning before.

Q: Can I buy capacity in advance?

A: anonym.legal is subscription-based — you can upgrade your tier at any time.

Data Privacy

Q: Does piisafe.eu store my API key?

A: No. Your key is saved in your browser's localStorage and passes through the piisafe.eu server to anonym.legal on each request — it is never stored or logged server-side.

Q: Does piisafe.eu store scan results?

A: No. Results are held in server memory only and are never written to a database, disk or log. Finished sessions are automatically deleted within 35 minutes; a service restart clears them immediately.

Q: Can I use piisafe.eu for client/customer websites?

A: Yes! Perfect for consultants, security teams, compliance officers. Audit trail kept locally. No data leaves your device.

Technical

Q: What browsers are supported?

A: Modern browsers (Chrome, Firefox, Safari, Edge 2020+). Requires JavaScript and fetch API support. Mobile browsers supported.

Q: Can I integrate piisafe.eu into my own app?

A: Yes! Clone the repo from GitHub, customize backend routes, integrate with your own infrastructure. Full source code available.

Q: What's the difference between piisafe.eu and the APIs directly?

A: piisafe.eu adds: automatic chunking, visual UI, real-time progress, multiple export formats, easy entity selection, preset compliance profiles.

Q: Can I scan multiple websites simultaneously?

A: Yes - there is no separate concurrent-scan cap. Each scan you start counts toward the 20-scans-per-hour limit, and heavy simultaneous polling can hit the shared 120-requests-per-minute status-poll limit, so running many at once may return a 429 sooner.

↑ Back to Top