{"openapi":"3.0.3","info":{"title":"PII Redactor API","version":"1.0.0","description":"Detects and redacts PII (emails, Luhn-validated cards, MOD-97 IBANs, EU VATs, phones, IPs, SSNs, and HU tax/TAJ IDs) with reversible caller-only tokens and zero payload storage."},"servers":[{"url":"https://api.tinplate.dev","description":"Production Edge Gateway"}],"components":{"schemas":{"PiiRedactResponse":{"type":"object","properties":{"redacted_text":{"type":"string","example":"Contact Alice at [PII_EMAIL_1] or [PII_PHONE_1]. IBAN: [PII_IBAN_1]."},"findings":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["EMAIL","CREDIT_CARD","IBAN","PHONE","IPV4","SSN","EU_VAT","HU_TAX_ID","HU_TAJ"],"example":"IBAN"},"start":{"type":"integer","minimum":0,"example":17},"end":{"type":"integer","minimum":0,"example":35},"token":{"type":"string","example":"[PII_EMAIL_1]"},"locale":{"type":"string","enum":["GLOBAL","EU","HU"],"example":"EU","description":"Locale pack for region-specific PII detectors."},"validated":{"type":"boolean","example":true}},"required":["type","start","end","token","locale","validated"]}},"counts":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"example":{"EMAIL":1,"PHONE":1,"IBAN":1}},"total_redacted":{"type":"integer","minimum":0,"example":3},"tokens":{"type":"object","additionalProperties":{"type":"string"},"example":{"[PII_EMAIL_1]":"alice@tinplate.dev","[PII_PHONE_1]":"+36 30 123 4567","[PII_IBAN_1]":"HU42117730161111101800000000"},"description":"Reversible token map returned only to the caller (never stored server-side). Empty in 'mask' mode."}},"required":["redacted_text","findings","counts","total_redacted","tokens"]},"PiiRedactRequest":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":262144,"example":"Contact Alice at alice@tinplate.dev or +36 30 123 4567. IBAN: HU42117730161111101800000000.","description":"Input text to scan and redact (max 256 KB)."},"locales":{"type":"array","items":{"type":"string","enum":["GLOBAL","EU","HU"],"example":"EU","description":"Locale pack for region-specific PII detectors."},"minItems":1,"maxItems":3,"example":["GLOBAL","EU","HU"],"description":"Locale packs to enable (defaults to ['GLOBAL', 'EU'])."},"mode":{"type":"string","enum":["token","mask"],"example":"token","description":"'token' returns reversible [PII_<TYPE>_N] tokens + caller-only tokens map; 'mask' returns [REDACTED:<TYPE>] with an empty tokens map."},"types":{"type":"array","items":{"type":"string","enum":["EMAIL","CREDIT_CARD","IBAN","PHONE","IPV4","SSN","EU_VAT","HU_TAX_ID","HU_TAJ"],"example":"IBAN"},"minItems":1,"maxItems":15,"example":["EMAIL","IBAN","CREDIT_CARD"],"description":"Optional whitelist of PII entity types to redact."}},"required":["text"]},"PiiRestoreResponse":{"type":"object","properties":{"text":{"type":"string","example":"Contact Alice at alice@tinplate.dev."},"restored_count":{"type":"integer","minimum":0,"example":1}},"required":["text","restored_count"]},"PiiRestoreRequest":{"type":"object","properties":{"redacted_text":{"type":"string","minLength":1,"maxLength":262144,"example":"Contact Alice at [PII_EMAIL_1]."},"tokens":{"type":"object","additionalProperties":{"type":"string","maxLength":4096},"example":{"[PII_EMAIL_1]":"alice@tinplate.dev"}}},"required":["redacted_text","tokens"]},"ResponseMeta":{"type":"object","required":["request_id"],"properties":{"request_id":{"type":"string","format":"uuid"},"ms":{"type":"integer","minimum":0},"version":{"type":"string","example":"1.0.0"}}},"ErrorEnvelope":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"invalid_input"},"message":{"type":"string","example":"Request body failed validation"}}},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}},"parameters":{}},"paths":{"/v1/pii-redactor":{"post":{"tags":["03_PII_REDACTOR"],"summary":"Redact PII from text with optional reversible tokens","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PiiRedactRequest"}}}},"responses":{"200":{"description":"Redaction result","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/PiiRedactResponse"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"required":["ok","data","meta"]}}}},"400":{"description":"Invalid input or malformed JSON request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid authentication credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Request payload exceeds subscribed plan byte cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/pii-redactor/restore":{"post":{"tags":["03_PII_REDACTOR"],"summary":"Statelessly restore reversible PII tokens in redacted text","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PiiRestoreRequest"}}}},"responses":{"200":{"description":"Restored text","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/PiiRestoreResponse"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}},"required":["ok","data","meta"]}}}},"400":{"description":"Invalid input or malformed JSON request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid authentication credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Request payload exceeds subscribed plan byte cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}}}