API reference
Base URL: https://sitrdata.com
Get started
All endpoints under /v1 require a Bearer token. Request an API key at hello@sitrdata.com or via the dashboard.
curl https://sitrdata.com/v1/detect \
-H "Authorization: Bearer gpk_live_..." \
-H "Content-Type: application/json" \
-d '{"text":"Ahmad QID 28845001234","country_packs":["qa"]}'Authentication
Include your API key as a Bearer token in the Authorization header of every request.
Authorization: Bearer gpk_live_<your-key>
Keys are organisation-scoped. Rate limits apply per organisation. Pass Accept-Language: ar to receive error messages in Arabic.
POST/v1/detect
Detect PII entities in a text string. Returns positions and confidence scores. Text is never stored.
Request body
| text | string | required | Input text. Max 50,000 characters. |
| country_packs | string[] | optional | Packs to activate: "qa" "sa" "ae" "bh" "kw" "om" "common". Default: ["qa","common"]. |
| entity_types | string[] | optional | Limit detection to specific types. Detects all if omitted. |
| min_score | number | optional | Minimum confidence threshold 0–1. Default: 0.4. |
| include_values | boolean | optional | Include matched text in each entity object. Default: false. |
Response
{
"entities": [
{
"type": "QA_QID",
"start": 12,
"end": 23,
"score": 0.95,
"text": "28845001234" // only present when include_values: true
}
]
}Example
curl https://sitrdata.com/v1/detect \
-H "Authorization: Bearer gpk_live_..." \
-H "Content-Type: application/json" \
-d '{
"text": "Send to Ahmad Al-Mansouri, QID 28845001234",
"country_packs": ["qa", "common"],
"include_values": true
}'POST/v1/redact
Detect and mask PII in a single call. Returns redacted text and an encrypted mapping for later restoration.
Request body
| text | string | required | Input text. Max 50,000 characters. |
| mode | string | required | "mask" replaces with ███. "tag" uses [QA_QID]. "hash" is deterministic. "pseudonymize" uses consistent placeholders and returns an encrypted mapping. |
| country_packs | string[] | optional | Country packs to activate. |
| entity_types | string[] | optional | Limit to specific entity types. |
| min_score | number | optional | Minimum confidence. Default: 0.4. |
Response
{
"redacted_text": "Please contact [PERSON_1] at [EMAIL_1].",
"entities": [...],
"encrypted_mapping": "base64url..." // pseudonymize mode only
}POST/v1/redact/batch
Redact multiple texts in one request. Max 100 texts per call.
Request body
| texts | string[] | required | Array of input texts. Max 100 items. |
| mode | string | required | Same options as /v1/redact. |
| country_packs | string[] | optional | Country packs to activate. |
| entity_types | string[] | optional | Limit to specific entity types. |
Response
{
"results": [
{ "redacted_text": "...", "entities": [...] },
{ "redacted_text": "...", "entities": [...] }
]
}POST/v1/restore
Restore real values into a pseudonymized text. The mapping is never stored server-side: you supply it from the prior redact response.
Request body
| text | string | required | Pseudonymized text with placeholders like [PERSON_1] or [QA_QID_1]. |
| encrypted_mapping | string | required | The encrypted_mapping value from the prior /v1/redact response. |
Response
{
"restored_text": "Please contact Ahmad Al-Mansouri at hr@company.qa."
}POST/v1/chat/completions
OpenAI-compatible LLM gateway. Sitr masks PII in every message before forwarding to your provider, then restores real values in the reply. Streaming (SSE) and non-streaming both work.
Request body
Standard OpenAI request body, plus Sitr extensions:
| model | string | required | Any supported model: gpt-4o, claude-3-5-sonnet-20241022, gemini-2.0-flash, etc. |
| messages | object[] | required | Standard OpenAI messages array. |
| stream | boolean | optional | Enable SSE streaming. Default: false. |
| sitr_packs | string[] | optional | Country packs to apply. Default: ["qa","common"]. |
| sitr_mask_entities | string[] | optional | Limit masking to specific entity types. |
| encrypted_mapping | string | optional | Pass the mapping from a prior turn for consistent cross-turn pseudonymization. |
Provider keys
Add provider keys in your organisation dashboard. Sitr selects the right key based on the model prefix. Keys are envelope-encrypted at rest and never logged.
Response
Standard OpenAI response with a sitr extension field:
{
"id": "chatcmpl-...",
"choices": [{
"message": {
"role": "assistant",
"content": "Ahmad Al-Mansouri's contract is ready."
}
}],
"sitr": {
"entities_masked": 3,
"encrypted_mapping": "base64url..." // pass this back on the next turn
}
}Example
curl https://sitrdata.com/v1/chat/completions \
-H "Authorization: Bearer gpk_live_..." \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"messages": [
{ "role": "user", "content": "Summarise the contract for Ahmad, QID 28845001234." }
],
"sitr_packs": ["qa", "common"]
}'Financial Mode
Financial Mode hides confidential numbers from the LLM (revenue, salaries, deal sizes, balances) while letting the model write calculation formulas that Sitr evaluates locally with the real figures.
How it works
When Financial Mode is active, Sitr detects AMOUNT entities in addition to PII. Each amount is replaced with a placeholder before the request reaches the model:
Input: Q3 revenue was QAR 48.2M and costs were QAR 31.5M. Masked: Q3 revenue was [AMOUNT_1] and costs were [AMOUNT_2].
The model is instructed to write formulas instead of computing results directly:
Model response:
Your operating margin is {{calc: ([AMOUNT_1] - [AMOUNT_2]) / [AMOUNT_1] | percent}}.Sitr evaluates the formula locally and returns the result to the caller:
Restored response: Your operating margin is 34.6%.
Formula syntax
{{calc: <expression> | <format>}}
Operators: + - * / and parentheses.
Functions: sum(), avg(), min(), max(), abs(), round()
Formats: amount (currency + auto-scale), percent, number, ratio. Optional decimal places: percent:1
{{calc: ([AMOUNT_1] - [AMOUNT_2]) / [AMOUNT_1] | percent}} → 34.6%
{{calc: sum([AMOUNT_1], [AMOUNT_2]) | amount}} → QAR 79.7M
{{calc: [AMOUNT_1] * 1.1 | amount:0}} → QAR 53,020,000Enabling via API
Add "financial" to country_packs and include financial_options:
POST /v1/redact
{
"text": "Revenue QAR 48.2M, costs QAR 31.5M.",
"mode": "pseudonymize",
"country_packs": ["qa", "common", "financial"],
"financial_options": { "mode": "amounts" }
}Enabling via Gateway
Set X-Sitr-Financial: on header (when your organisation allows per-request overrides), or configure Financial Mode in your dashboard settings.
curl https://sitrsecure.com/v1/chat/completions \
-H "Authorization: Bearer gpk_live_..." \
-H "X-Sitr-Financial: on" \
-d '{ "model": "gpt-4o", "messages": [...] }'sitr_warnings field
In non-streaming responses, if the model response contains numbers that look like financial results but were not computed by Sitr, they appear in sitr.sitr_warnings:
"sitr": {
"entities_redacted": 2,
"amounts_masked": 2,
"formulas_computed": 1,
"sitr_warnings": [
{ "type": "unverified_number", "text": "35%", "index": 142 }
]
}Limitations
- · The model can still misunderstand a question even with correct figures.
- · Mixed currencies in one formula are refused. Amounts in different currencies are each masked separately.
- · Always review important computed figures before acting on them.
- · The model instruction improves formula compliance but does not guarantee it across all providers.
Entity types
Use these identifiers in entity_types and sitr_mask_entities fields.
qaQA_QIDQA_PHONEQA_IBANQA_PASSPORTQA_CRQA_ADDRESSsaSA_NATIONAL_IDSA_IQAMASA_IBANSA_PHONEaeAE_EMIRATES_IDAE_IBANAE_PHONEbhBH_CPRBH_IBANBH_PHONEkwKW_CIVIL_IDKW_IBANKW_PHONEomOM_CIVIL_IDOM_IBANOM_PHONEcommonPERSONEMAILCREDIT_CARDIP_ADDRESSPASSPORT