DLP results
Every request sent through the Arbitex Gateway is inspected by the 5-tier DLP pipeline before it reaches the upstream provider, and again on the response before it reaches your application. This page covers the data-plane view: how DLP decisions affect your request in flight, what streaming events the gateway emits, and how to read DLP event records back through the API.
Admin operations — configuring detection rules, toggling the master DLP switch, bulk importing rule sets — are covered in the DLP admin guide.
Inline behavior
Section titled “Inline behavior”Pipeline inspection
Section titled “Pipeline inspection”The 5-tier DLP pipeline runs on every request and response:
| Tier | Technology | What it detects |
|---|---|---|
| Tier 0 | TF-IDF | Fast pre-screen to route likely-sensitive content to deeper tiers |
| Tier 1 | Regex | Pattern-matched entities (credit card numbers, SSNs, API keys, etc.) |
| Tier 2 | NER | Named entity recognition via spaCy (context-aware, reduces false positives) |
| Tier 3 | DeBERTa | Contextual classification with confidence scoring (Outpost deployments) |
| Tier 4 | CredInt | Credential intelligence — severity-bucketed detection of secrets and tokens |
Input (your prompt) is scanned before the request is forwarded to the upstream provider. Output (the model response) is scanned as it streams back. When output scanning finds a match mid-stream, the gateway can intervene before the full response reaches your application.
Policy actions
Section titled “Policy actions”When a DLP rule matches, the action configured on the matching rule is applied. If multiple rules match the same content, the highest-precedence action wins: block > cancel > redact > log_only.
| Action | What the caller sees |
|---|---|
log_only |
Request and response proceed normally. The match is recorded in the audit log. |
redact |
Matched text is replaced with a redaction token (e.g. [REDACTED]) before being passed to the upstream provider (for input) or returned to the caller (for output). The response body is otherwise complete. |
cancel |
The current streaming or non-streaming response is cancelled. The caller receives a 403 with error code policy_block. |
block |
The request is blocked before it is forwarded to the upstream provider. The caller receives a 403 with error code policy_block. |
A blocked or cancelled request returns:
{ "error": { "code": "policy_block", "message": "Request blocked by DLP policy.", "type": "policy_error", "rule_id": "550e8400-e29b-41d4-a716-446655440000" }}The X-Policy-Action response header is always present and set to BLOCK, CANCEL, or REDACT depending on the terminal action. X-Matched-Rule carries the rule ID that triggered it.
Tier 3 confidence routing
Section titled “Tier 3 confidence routing”Tier 3 (DeBERTa) produces a continuous confidence score. The gateway maps scores to enforcement zones:
| Zone | Confidence range | Default behavior |
|---|---|---|
| Hard block | > 0.70 | Blocked regardless of sensitivity setting |
| Ambiguous | 0.35 – 0.70 | Outcome depends on your org’s dlp_sensitivity setting (high → soft block with audit flag; standard → pass with elevated audit flag) |
| Pass | < 0.35 | Request proceeds normally |
Tier 4 (CredInt) applies separate routing by severity bucket (critical, high, medium, low). Critical and high severity credentials trigger a soft block under dlp_sensitivity: high.
Streaming DLP events
Section titled “Streaming DLP events”When stream: true is set in a chat completions request, the gateway may emit two Arbitex-specific server-sent event types in addition to the standard OpenAI data: chunks.
dlp_correction
Section titled “dlp_correction”Emitted when the DLP pipeline redacts content from the streaming response. The chunk containing the sensitive text is replaced with the redacted version before it is sent to the caller.
event: dlp_correctiondata: {"type":"dlp_correction","entity_type":"CREDIT_CARD","action":"redact","position":{"start":42,"end":58}}| Field | Type | Description |
|---|---|---|
type |
string | Always "dlp_correction" |
entity_type |
string | Entity classification label of the redacted content (e.g. CREDIT_CARD, SSN, API_KEY) |
action |
string | Action applied: "redact" |
position.start |
integer | Start character offset in the accumulated response text |
position.end |
integer | End character offset in the accumulated response text |
output_blocked
Section titled “output_blocked”Emitted when the DLP pipeline determines mid-stream that the response must be cancelled. The stream terminates immediately after this event; no further data: chunks follow.
event: output_blockeddata: {"type":"output_blocked","entity_type":"SSN","action":"block"}| Field | Type | Description |
|---|---|---|
type |
string | Always "output_blocked" |
entity_type |
string | Entity type that triggered the block |
action |
string | Action applied: "block" or "cancel" |
DLP events API
Section titled “DLP events API”DLP events are audit records written each time the pipeline produces a finding. They are available for review and triage through the following read endpoints. All endpoints require an admin-scoped API key.
Base URL: https://api.arbitex.ai
DLPEventResponse object
Section titled “DLPEventResponse object”All event endpoints return this schema:
| Field | Type | Description |
|---|---|---|
id |
string | Unique event identifier (UUID) |
user_id |
string | null | ID of the user whose request triggered the detection |
conversation_id |
string | null | ID of the conversation the request belongs to |
detector_name |
string | Name of the DLP rule that matched (e.g. "Visa/MC Credit Card Pattern") |
entity_type |
string | Entity classification label (e.g. CREDIT_CARD, SSN, API_KEY) |
matched_text |
string | The exact content that matched the rule |
action_taken |
string | Action that was applied: log_only, redact, cancel, or block |
status |
string | Lifecycle status: detected, investigating, resolved, or false_positive |
severity |
string | Severity level assigned by the pipeline |
direction |
string | Whether the match was in the input (prompt) or output (model response) |
resolution_notes |
string | null | Admin notes written when resolving the event |
resolved_by |
string | null | ID or email of the admin who resolved or closed the event |
resolved_at |
datetime | null | ISO 8601 timestamp when the event was resolved or marked false positive |
created_at |
datetime | ISO 8601 timestamp when the event was created |
version |
integer | Optimistic-lock counter — supply as expected_version in a PUT to prevent lost-update races (default: 1) |
Status lifecycle
detected → investigating → resolved ↘ false_positiveresolved and false_positive are terminal states. When an event transitions to either, resolved_by and resolved_at are set automatically.
List DLP events
Section titled “List DLP events”GET /api/v1/dlp/eventsReturns a paginated list of DLP events for your organization, ordered newest first. Supports filtering on all major dimensions.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
status |
string | — | Filter by lifecycle status: detected, investigating, resolved, or false_positive |
entity_type |
string | — | Filter by entity classification label (e.g. CREDIT_CARD) |
severity |
string | — | Filter by severity level |
direction |
string | — | Filter by detection direction: input or output |
user_id |
UUID string | — | Filter by the user who triggered the detection |
date_from |
datetime | — | Return events created on or after this ISO 8601 timestamp |
date_to |
datetime | — | Return events created on or before this ISO 8601 timestamp |
page |
integer | 1 |
Page number (1-based) |
page_size |
integer | 50 |
Items per page (min 1, max 200) |
Request
curl "https://api.arbitex.ai/api/v1/dlp/events?status=detected&entity_type=CREDIT_CARD&page=1&page_size=20" \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
{ "items": [ { "id": "evt_01HZ_CC_DETECTION", "user_id": "usr_01HZ_ALICE", "conversation_id": "conv_01HZ_XYZ", "detector_name": "Visa/MC Credit Card Pattern", "entity_type": "CREDIT_CARD", "matched_text": "4111111111111111", "action_taken": "redact", "status": "detected", "severity": "high", "direction": "input", "resolution_notes": null, "resolved_by": null, "resolved_at": null, "created_at": "2026-06-29T10:22:00Z", "version": 1 } ], "total": 1, "page": 1, "page_size": 20}Get DLP event
Section titled “Get DLP event”GET /api/v1/dlp/events/{event_id}Returns a single DLP event by UUID.
Path parameters
| Parameter | Description |
|---|---|
event_id |
UUID of the DLP event |
Request
curl "https://api.arbitex.ai/api/v1/dlp/events/evt_01HZ_CC_DETECTION" \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK — a single DLPEventResponse.
Error responses
| Status | Description |
|---|---|
404 |
Event not found |
Get DLP event summary
Section titled “Get DLP event summary”GET /api/v1/dlp/events/summaryReturns aggregate counts for DLP events across your organization, grouped by status, entity type, and severity. Use this to build dashboards or alert on detection volume.
Request
curl "https://api.arbitex.ai/api/v1/dlp/events/summary" \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
{ "by_status": { "detected": 14, "investigating": 3, "resolved": 41, "false_positive": 7 }, "by_entity_type": { "CREDIT_CARD": 22, "SSN": 8, "API_KEY": 19, "EMAIL": 16 }, "by_severity": { "critical": 5, "high": 28, "medium": 21, "low": 11 }, "total": 65}| Field | Type | Description |
|---|---|---|
by_status |
object | Event counts keyed by lifecycle status |
by_entity_type |
object | Event counts keyed by entity classification label |
by_severity |
object | Event counts keyed by severity level |
total |
integer | Total number of DLP events in your organization |
Update DLP event status
Section titled “Update DLP event status”PUT /api/v1/dlp/events/{event_id}Transitions a DLP event to a new lifecycle status. When transitioning to resolved or false_positive, resolved_by and resolved_at are set automatically using the identity of the calling admin.
Supports optimistic locking: include expected_version (from the last GET response) to detect concurrent modifications. If another admin has updated the event since you last fetched it, a 409 Conflict is returned so you can re-fetch and retry.
Path parameters
| Parameter | Description |
|---|---|
event_id |
UUID of the DLP event to update |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | Yes | New status: detected, investigating, resolved, or false_positive |
resolution_notes |
string | No | Admin notes on the resolution or investigation findings |
expected_version |
integer | No | Optimistic-lock version from the last GET. Omit for last-write-wins behavior |
Request
curl -X PUT "https://api.arbitex.ai/api/v1/dlp/events/evt_01HZ_CC_DETECTION" \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "resolved", "resolution_notes": "Confirmed real card number. User notified. Redaction was correct.", "expected_version": 1 }'Response 200 OK — the updated DLPEventResponse.
Error responses
| Status | Code | Description |
|---|---|---|
404 |
not_found |
Event not found |
409 |
conflict |
expected_version was supplied but a concurrent modification was detected — re-fetch and retry |
422 |
unprocessable_entity |
Invalid status value |
Error responses (common)
Section titled “Error responses (common)”| Status | Code | Description |
|---|---|---|
401 |
invalid_api_key |
API key not found, revoked, or malformed |
403 |
forbidden |
API key does not have admin permissions |
404 |
not_found |
Event not found |
See also
Section titled “See also”- Chat completions — full reference for streaming, including
dlp_correctionandoutput_blockedevent handling - DLP admin guide — configuring detection rules, master DLP toggle, and bulk rule import/export (admin only)
- DLP deep dive — pipeline architecture, spaCy and DeBERTa configuration, confidence threshold tuning