Docs
Developer Documentation

Documentation

Everything you need to integrate Reglint's Layer 2 Agent Monitor into your AI pipeline, and how employees and admins use the Chrome Extension and Command Center.

Arabic Detection Benchmark

We measured the deployed engine on 305 Arabic test cases across the four major dialects (MSA, Gulf, Egyptian, Levantine) and all 24 base categories of the engine's 29-category taxonomy, balanced with 50 hard negatives. Every number comes straight from the run — no rounding up, no cherry-picking. The 5 extended categories (AML_STRUCTURING, KYC_BYPASS, UNAUTHORIZED_FINANCIAL_ACTION, UNAUTHORIZED_DISCLOSURE, UNSOLICITED_MARKETING) are detected by the engine but not yet stratified in this benchmark — coming in the next revision.

100% recall (95% CI 98.2–100)
99.5% precision (95% CI 97.3–99.9)
0.0% false-negative rate (95% CI 0–1.8)

205 violations caught, 0 missed, 1 false positive of 95 clean cases (a masked card with Eastern-Arabic digits). Single full-mode run on the deployed engine.

Full methodology, per-category and per-dialect tables, and honest limitations →
0

Getting Started

Get your API key and send your first compliance scan in minutes.

1

Get your API Key

Sign up at reglint.ai, then go to Settings → API Keys → Generate Key. Copy your key — it is shown once only.
2

Send your first request

Call the monitor endpoint with your agent's output and your API key:
javascript
const response = await fetch(
  'https://reglint.ai/api/monitor/scan',
  {
    method: 'POST',
    headers: {
      'x-api-key': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agent_output: "Your agent's response here",
      agent_name: "my-agent",
      industry: "healthcare",
      mode: "fast"
    })
  }
);
const result = await response.json();
if (!result.safe_to_deliver) {
  return "Request blocked due to compliance violation.";
}
return result.redacted_output || result.original_output;

Step 3 — Handle the response

The monitor returns a structured JSON object with the decision and all violations found:

json
{
  "scan_id": "uuid",
  "final_decision": "BLOCK | REDACT | ALERT | PASS",
  "safe_to_deliver": false,
  "violations_count": 1,
  "violations": [
    {
      "violation_id": "SSN_EXPOSURE",
      "law": "HIPAA § 164.514",
      "description": "SSN detected in agent output",
      "violating_text": "123-45-6789",
      "action": "BLOCK",
      "severity": "critical",
      "fine_range": "up to $50,000 per violation"
    }
  ],
  "original_output": "Your SSN is 123-45-6789...",
  "redacted_output": "Your SSN is [REDACTED: SSN_EXPOSURE]...",
  "processing_time_ms": 340
}

Monitor Endpoint

POSThttps://reglint.ai/api/monitor/scan
HEADERx-api-key: YOUR_API_KEY
1

How It Works

Understand the Layer 2 Agent Monitor and the scan lifecycle.

What is Layer 2 Agent Monitor?

Traditional compliance tools scan inputs (documents, code, forms). The Layer 2 Agent Monitor sits downstream of your AI agent and inspects the agent's output before it reaches the end user. It acts as a real-time compliance filter — catching PII, protected health information, and regulatory violations that a language model may inadvertently expose.

Scan Lifecycle

💬

Agent Response

Your AI agent generates a text response

🔍

Reglint Scans

Regex rules run against the output in milliseconds

⚖️

Decision

BLOCK · REDACT · ALERT · PASS

👤

User Sees Result

Safe or redacted response delivered; violations logged

BLOCKResponse suppressed entirely

The agent output is never delivered. The most severe violations (e.g. bare SSNs, credit card numbers) trigger this.

REDACTSensitive text replaced

Matched substrings are replaced with [REDACTED] and the sanitised response is delivered instead.

ALERTResponse passes, team notified

The response is delivered unchanged, but a compliance alert is emailed to your configured receivers and logged in your Agents dashboard.

ALERT_HITLAlert held for human approval

A variant of ALERT: instead of being finalized automatically, the item is routed to a pending Review Queue for a person to approve, reject, or edit. Whether an item becomes ALERT_HITL is determined by the engine.

PASSNo violations found

The output is clean. The scan completes in milliseconds and the response is forwarded immediately.

ALERT_HITLReview Queue — human-in-the-loop

When the engine assigns ALERT_HITL, the item is held for human review rather than being finalized automatically. It appears in the pending Review Queue at /dashboard/agents/queue (linked from the Violations Hub). A reviewer resolves each pending item with one of three actions:

  • Approve — accept the pending item.
  • Reject — decline the pending item.
  • Edit — revise the item, optionally with a note, before resolving.
2

Industries

Pass industry in your API call to focus Reglint on the regulations that matter most to you.

The industry field is optional but recommended. When set, Reglint prioritises the rule sets most relevant to your sector, improving signal quality and reducing noise.

Supported values and their primary regulation coverage:

healthcare
HIPAAHITECHGINAADA
fintech
PCI-DSSGLBAFCRAECOA
privacy
GDPRCCPAEU AI ActBIPA
hr
Title VIIADEAADAGINA
general
All 69 regulations

Usage

Add the industry field to your request payload:

json
{
  "agent_output": "...",
  "agent_name":   "MedicalAdvisorBot",
  "industry":     "healthcare",
  "mode":         "full"
}
3

Scan Mode

Choose between instant regex scanning or deep RAG + Claude analysis.

fastRules Engine only
  • Regex pattern matching only
  • Milliseconds latency
  • Fully deterministic
  • No legal citations or context
fullDefault
  • Rules Engine → RAG → Claude
  • 2–8 seconds
  • Contextual + legal citations
  • Fine ranges per violation
javascript
// Fast — rules engine only, milliseconds
body: JSON.stringify({ agent_output: agentResponse, mode: "fast" })

// Full — RAG + Claude deep analysis (default)
body: JSON.stringify({ agent_output: agentResponse, mode: "full" })
4

Default Action

Override how Reglint handles all violations in a single request.

default_action lets you override the action for all violations in a single request — useful for testing, or when you want a blanket policy for a specific agent.

AUTO

Reglint uses each rule's own default action (recommended). Same as omitting the field.

BLOCK

All violations trigger BLOCK — output is suppressed entirely.

REDACT

All violations trigger REDACT — sensitive text is masked in the response.

ALERT

All violations trigger ALERT — response is delivered, compliance team is notified.

Note: default_action overrides rules_config for all violations. If not set, per-rule configuration applies.

javascript
// AUTO — Reglint decides per rule (recommended)
body: JSON.stringify({ agent_output: agentResponse, default_action: "AUTO" })

// BLOCK — suppress everything
body: JSON.stringify({ agent_output: agentResponse, default_action: "BLOCK" })

// REDACT — mask sensitive data only
body: JSON.stringify({ agent_output: agentResponse, default_action: "REDACT" })

// ALERT — deliver + notify compliance team
body: JSON.stringify({ agent_output: agentResponse, default_action: "ALERT" })
5

Per-Rule Configuration

Override the action for individual rules stored in your customer config.

Each customer can store a rules_config map in DynamoDB. When Reglint processes a request for your customer ID, it merges your overrides with the Reglint defaults. Set a rule to IGNORE to disable it entirely.

Example config stored for your customer:

json
{
  "SSN_EXPOSURE":          "BLOCK",
  "EMAIL_EXPOSURE":        "REDACT",
  "MEDICAL_DATA_EXPOSURE": "ALERT",
  "PHONE_EXPOSURE":        "IGNORE"
}
Valid values:BLOCKREDACTALERTIGNORE

How Reglint Decides Severity

Reglint evaluates each scan in two layers. Understanding this helps you choose the right mode for your use case.

Layer 1: Rules Engine (Fast Mode)

Each of the 50 rules has a documented default action (BLOCK / REDACT / ALERT). The rules engine runs in both fast and full modes and follows these defaults exactly.

Layer 2: Claude AI (Full Mode Only)

In mode: full, Claude evaluates the violation in the context of your industry. Claude may upgrade severity (e.g., ALERT → REDACT) if the legal framework requires stricter handling. Claude does not downgrade.

Choosing Your Mode

  • Fast mode: ~1.5s, predictable. Best for high-throughput screening.
  • Full mode: ~10–15s, context-aware. Best for healthcare, finance, HR.

Enforcement Patterns: When Reglint Intervenes

Reglint returns a decision + a redacted version of the AI response. You decide when and how to act on it. Three common patterns are shown below — pick the one that matches your industry's compliance posture.

Pattern 1: Pre-Display Enforcement (Strict)

Hold the AI response, scan it through Reglint, then display based on the decision. The user never sees a violation. Best for: healthcare (HIPAA), finance (GLBA), HR (EEOC).

async function handleUserMessage(userMessage) {
  // 1. Get AI response (held in memory, not displayed yet)
  const aiResponse = await callAIAgent(userMessage);

  // 2. Scan with Reglint BEFORE showing user
  const scan = await fetch('https://reglint.ai/api/monitor/scan', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.REGLINT_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agent_output: aiResponse,
      industry: 'healthcare',
      mode: 'full'
    })
  }).then(r => r.json());

  // 3. Apply decision — user sees only the safe version
  switch (scan.final_decision) {
    case 'BLOCK':
      return 'Sorry, I cannot help with that request.';
    case 'REDACT':
      return scan.redacted_output;  // Reglint provides this
    case 'ALERT':
    case 'PASS':
    default:
      return aiResponse;
  }
}

User experience: safe content only. Latency cost: ~1–2s (fast mode) or ~10s (full mode).

Pattern 2: Post-Display Warning (Soft)

Display the AI response immediately, scan in parallel, then show a warning if a violation is detected. Best for: marketing chatbots, internal tools, low-risk content.

async function handleUserMessage(userMessage) {
  // 1. Get AI response and display immediately
  const aiResponse = await callAIAgent(userMessage);
  displayInChat(aiResponse);

  // 2. Scan in background (non-blocking)
  fetch('https://reglint.ai/api/monitor/scan', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.REGLINT_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agent_output: aiResponse,
      industry: 'general',
      mode: 'fast'
    })
  })
  .then(r => r.json())
  .then(scan => {
    // 3. Show warning AFTER the response if violation detected
    if (scan.final_decision !== 'PASS') {
      showWarning(`Compliance flag: ${scan.violations[0].violation_id}`);
    }
  });
}

User experience: fast response, occasional warnings. Latency cost: 0ms (scan runs in parallel).

Pattern 3: Audit-Only Logging (Silent)

Display AI responses without intervention. Use Reglint to log every interaction for compliance reporting and audits. Best for: enterprise audit trails, regulated industries requiring records, monitoring without UX changes.

async function handleUserMessage(userMessage) {
  // 1. Get AI response and display immediately — no intervention
  const aiResponse = await callAIAgent(userMessage);
  displayInChat(aiResponse);

  // 2. Log to Reglint for compliance audit (silent, fire-and-forget)
  fetch('https://reglint.ai/api/monitor/scan', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.REGLINT_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agent_output: aiResponse,
      user_input: userMessage,
      industry: 'finance',
      mode: 'full',
      consent_for_training: false
    })
  });
  // No await — fire and forget. Audit happens server-side.
}

User experience: identical to no Reglint. Compliance benefit: full audit trail in your Reglint dashboard.

Which Pattern Should You Use?

Industry / Use CaseRecommended PatternWhy
Healthcare (HIPAA)Pre-Display (Strict)PHI must never reach unauthorized users
Finance (GLBA, SOX)Pre-Display (Strict)Financial data exposure has legal liability
HR / HiringPre-Display (Strict)Discrimination prevention is non-negotiable
Marketing chatbotsPost-Display (Soft)Speed matters more than strict compliance
Internal toolsAudit-OnlyEmployees trusted, but need audit trail
Customer support (general)Post-Display or Pre-DisplayDepends on data sensitivity
Education / EdTech (FERPA)Pre-Display (Strict)Student records protected by federal law

Reglint provides the decision. You provide the policy. The same rules can produce different user experiences depending on your enforcement pattern. This flexibility lets Reglint serve every industry without forcing a one-size-fits-all approach.

All 69 Rule IDs

Use any of these IDs as keys in your rules_config:

#Rule IDDefault ActionSeverityLaw
1SSN_EXPOSUREREDACTcriticalPrivacy Act 1974, GDPR Article 9
2CREDIT_CARD_EXPOSUREREDACTcriticalPCI DSS Requirement 3.2
3EMAIL_EXPOSUREALERThighGDPR Article 5, CCPA §1798.100
4PHONE_EXPOSUREALERThighTCPA, GDPR Article 5
5MEDICAL_DATA_EXPOSUREBLOCKcriticalHIPAA §164.514, GDPR Article 9
6FINANCIAL_DATA_EXPOSUREREDACTcriticalGLBA, PCI DSS
7PASSWORD_EXPOSUREBLOCKcriticalGDPR Article 32, NIST SP 800-63B
8DISCRIMINATORY_CONTENTBLOCKcriticalTitle VII, ECOA, ADA
9BIOMETRIC_DATABLOCKcriticalBIPA, GDPR Article 9
10CHILD_DATABLOCKcriticalCOPPA, GDPR Article 8
11LOCATION_TRACKINGALERThighCCPA, State Location Privacy Laws
12DATA_BULK_EXPOSUREBLOCKcriticalGDPR Article 5(1)(c), CCPA
13FERPA_STUDENT_DATABLOCKcriticalFERPA 20 U.S.C. §1232g
14TCPA_MARKETINGALERThighTCPA 47 U.S.C. §227
15CAN_SPAM_VIOLATIONALERThighCAN-SPAM Act 15 U.S.C. §7704
16VPPA_VIDEO_DATAALERThighVPPA 18 U.S.C. §2710
17DPPA_DRIVER_DATAREDACTcriticalDPPA 18 U.S.C. §2721
18ECPA_WIRETAPBLOCKcriticalECPA 18 U.S.C. §2511
19GINA_GENETIC_DATABLOCKcriticalGINA 42 U.S.C. §2000ff
20FTC_DARK_PATTERNSALERThighFTC Dark Patterns Report 2022
21EU_AI_ACT_HIGH_RISKALERTcriticalEU AI Act Article 6
22GDPR_CONSENT_VIOLATIONBLOCKcriticalGDPR Article 7
23AGE_DISCRIMINATIONBLOCKcriticalADEA 29 U.S.C. §623
24IMMIGRATION_STATUSBLOCKcriticalImmigration and Nationality Act
25RACIAL_LANGUAGEBLOCKcriticalCivil Rights Act Title VI
26GLBA_FINANCIAL_PRIVACYBLOCKcriticalGLBA 15 U.S.C. §6802
27SOX_FINANCIAL_MANIPULATIONALERThighSOX Section 302
28ROUTING_NUMBERREDACTcriticalGLBA, Reg E
29ACCOUNT_NUMBER_EXPOSUREREDACTcriticalGLBA, Reg E
30FCRA_BACKGROUND_CHECKALERThighFCRA 15 U.S.C. §1681
31PASSPORT_EXPOSUREREDACTcriticalPrivacy Act 1974, GDPR Article 9
32CONTACT_PHI_COMBINATIONREDACThighHIPAA §164.514, GDPR Article 5
33INSURANCE_ID_EXPOSUREREDACThighHIPAA §164.514, GLBA
34CFAA_UNAUTHORIZED_ACCESSBLOCKcriticalCFAA 18 U.S.C. §1030
35HITECH_BREACH_NOTIFICATIONALERTcriticalHITECH Act 42 U.S.C. §17931
36FTC_DECEPTIVE_CLAIMSALERThighFTC Act Section 5 15 U.S.C. §45
37ADA_ACCESSIBILITY_BARRIERALERThighADA Title II, WCAG 2.1 AA
38CMIA_HEALTH_DATABLOCKcriticalCMIA Cal. Health & Safety Code §56
39SHIELD_ACT_DATA_EXPOSUREALERThighNY SHIELD Act N.Y. Gen. Bus. Law §899-aa
40EPRIVACY_TRACKING_CONSENTALERThighePrivacy Directive 2002/58/EC
41ADPPA_DATA_MINIMIZATIONALERThighADPPA (proposed) H.R. 8152
42STATE_PRIVACY_DATA_RIGHTSALERThighState Privacy Laws (TX, FL, CT, OR, MT, DE, IA, IN, TN, ND, NH, NJ, KY)
43MEDICAL_PHI_SOLICITATIONBLOCKcriticalHIPAA §164.508(a)(3)
44DISCRIMINATORY_SOLICITATIONBLOCKcriticalECOA Reg B 12 CFR §202.5, Title VII 42 U.S.C. §2000e, Fair Lending
45PHI_TARGETED_MARKETINGBLOCKcriticalHIPAA §164.508(a)(3)
46FINANCIAL_PII_INSECURE_REQUESTALERThighGLBA Safeguards Rule 16 CFR §314, PCI DSS Req 3.2, NIST SP 800-53 IA-5
47SANCTIONS_AWARENESSALERThighOFAC Regulations (31 CFR Chapter V), IEEPA, Executive Orders
48ELDER_FINANCIAL_ABUSEBLOCKcriticalElder Justice Act, State Elder Abuse Statutes, FCRA
49PREGNANCY_DISCRIMINATION_CONTEXTALERThighPregnancy Discrimination Act (PDA), Title VII, FMLA
50RELIGIOUS_DISCRIMINATION_CONTEXTALERThighTitle VII, EEOC Religious Discrimination Guidelines
51NATIONAL_ORIGIN_DISCRIMINATIONALERThighTitle VII, IRCA (Immigration Reform and Control Act), EEOC
52MENTAL_HEALTH_DISCRIMINATIONALERThighADA (Americans with Disabilities Act), Mental Health Parity Act
53VETERAN_STATUS_DISCRIMINATIONALERThighUSERRA, VEVRAA, Title VII
54FAMILIAL_STATUS_DISCRIMINATIONALERThighTitle VII (sex discrimination), Family Responsibilities Discrimination
55AGE_DISCRIMINATION_LANGUAGEALERThighADEA (Age Discrimination in Employment Act), Title VII
56PRIVACY_ACT_THIRD_PARTYREDACTcritical5 U.S.C. § 552a(b)
57EG_NATIONAL_IDREDACThighقانون حماية البيانات الشخصية 151/2020، المادة 1 + اللائحة التنفيذية قرار 816/2025
58SA_NATIONAL_IDREDACThighنظام حماية البيانات الشخصية السعودي، المادة 1 + اللوائح التنفيذية
59AE_EMIRATES_IDREDACThighالمرسوم بقانون اتحادي 45/2021 بشأن حماية البيانات الشخصية (الإمارات)
60QA_QIDREDACThighقانون رقم 13 لسنة 2016 بشأن حماية خصوصية البيانات الشخصية (قطر)
61KW_CIVIL_IDREDACThighقانون حماية البيانات (الكويت، لائحة CITRA)
62BH_CPRALERTmediumقانون رقم 30 لسنة 2018 بشأن حماية البيانات الشخصية (البحرين)
63GCC_EG_IBANREDACThighقوانين حماية البيانات الخليجية/المصرية + تعليمات ساما لحماية عملاء البنوك
64AR_PHONE_EXPOSUREALERTmediumقوانين حماية البيانات الخليجية/المصرية (بيانات الاتصال)
65AR_ID_SOLICITATIONBLOCKhighقوانين حماية البيانات الخليجية/المصرية (طلب بيانات تعريفية في المحادثة)
66AR_PASSWORD_EXPOSUREBLOCKcriticalقوانين حماية البيانات + معايير أمن المعلومات (كشف كلمات المرور)
67AR_MEDICAL_DATABLOCKhighاللائحة التنفيذية 816/2025 (بيانات حساسة) / نظام حماية البيانات السعودي المادة 1 (البيانات الصحية)
68AR_DOBALERTmediumقوانين حماية البيانات الخليجية/المصرية (بيانات تعريفية)
69AR_KYC_BYPASS_SOLICITATIONBLOCKcriticalمتطلبات مكافحة غسل الأموال وتمويل الإرهاب (KYC) — السعودية/الإمارات/مصر/قطر/الكويت/البحرين
6

How to Adjust Rules

Compliance rules are regex patterns paired with an enforcement action and severity level.

Each rule is a plain JavaScript / JSON object. Reglint evaluates rules in order of severity — critical first — and takes the highest-priority action that matches. A single scan can detect multiple violations.

Rules are maintained in your Lambda layer configuration and hot-reloaded on deploy. Contact support@reglint.ai or edit the rules file directly in your infrastructure repository to add, remove, or tune patterns.

Rule Object Shape

Every rule must include these fields:

typescript
// A single compliance rule object
const rule = {
  pattern:      "\\b(?!000|666|9\\d{2})\\d{3}-(?!00)\\d{2}-(?!0000)\\d{4}\\b",
  violation_id: "SSN_EXPOSURE",
  law:          "HIPAA § 164.514 / CCPA",
  description:  "Social Security Number detected in agent output",
  action:       "BLOCK",    // "BLOCK" | "REDACT" | "ALERT"
  severity:     "critical", // "critical" | "high" | "medium"
};
FieldTypeDescription
patternstring (RegExp)Regular expression source (no delimiters). Flags i and g are applied automatically.
violation_idstringUnique machine-readable identifier. Appears in logs and dashboard.
lawstringThe regulation this rule enforces — e.g. "HIPAA § 164.514", "GDPR Art. 9".
descriptionstringHuman-readable explanation of what the rule catches.
action"BLOCK" | "REDACT" | "ALERT"Enforcement action when the pattern matches.
severity"critical" | "high" | "medium"Controls prioritisation when multiple rules fire.

When to use BLOCK vs REDACT vs ALERT

BLOCK

Use when exposure of any kind is unacceptable.

SSN\b\d{3}-\d{2}-\d{4}\bbare Social Security Number
Credit Card\b(?:4\d{12}(?:\d{3})?|5[1-5]\d{14})\bLuhn-valid card numbers
REDACT

Use when the response is still useful after masking the sensitive token.

Date of Birth\b(0?[1-9]|1[0-2])[\/\-](0?[1-9]|[12]\d|3[01])[\/\-](\d{2}|\d{4})\bMM/DD/YYYY or MM-DD-YY
Phone Number\b(\+1[\s.-]?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}\bUS phone formats
ALERT

Use when you need visibility but the data is low-risk or contextually acceptable.

MRNMRN[:\s#]*\d{5,10}Medical Record Number reference
ICD Code\b[A-Z]\d{2}(?:\.\d{1,2})?\bICD-10 diagnostic codes
7

How to Add a Webhook

Send scan results from your agent infrastructure directly to Reglint.

1

Obtain your webhook secret

Go to Settings → API & Integrations in the Reglint dashboard and copy the value of AGENT_MONITOR_SECRET. Store it as an environment variable in your agent host — never hard-code it.
2

Configure the endpoint

Point your agent to the webhook URL below. The endpoint is public and does not require a JWT — it is secured solely by the shared secret header.
POSThttps://reglint.ai/api/agent-monitor/webhook
HEADERx-reglint-secret: <your-secret>
3

Build the payload

Construct a JSON body matching the WebhookPayload interface. The four required fields are scan_id, customer_id, agent_name, and final_decision. All other fields are optional but recommended for full dashboard visibility.
4

Handle the response

On success the server returns HTTP 200 with { "received": true, "id": "agv_..." }. The endpoint is idempotent on scan_id — retrying a duplicate payload with the same ID will update mutable fields without creating a duplicate record.

Full Payload Shape

TypeScript interface — all optional fields are marked with ?.

typescript
// Full WebhookPayload shape (TypeScript)
interface LambdaViolation {
  violation_id?:   string;  // e.g. "SSN_EXPOSURE"
  type?:           string;  // legacy alias for violation_id
  law?:            string;  // e.g. "HIPAA § 164.514"
  description?:    string;
  violating_text?: string;  // the exact matched substring
  action?:         string;  // BLOCK | REDACT | ALERT
  severity?:       string;  // critical | high | medium
}

interface WebhookPayload {
  scan_id:             string;          // unique scan UUID (idempotency key)
  customer_id:         string;          // your Reglint user ID
  agent_name:          string;          // human-readable agent label
  industry?:           string;          // e.g. "healthcare", "finance"
  final_decision:      string;          // "BLOCK" | "REDACT" | "ALERT" | "PASS"
  violations_count:    number;
  violations:          LambdaViolation[];
  original_output?:    string;          // raw agent text before redaction
  redacted_output?:    string;          // text with PII replaced by [REDACTED]
  agent_endpoint?:     string;          // URL of the calling agent (optional)
  processing_time_ms?: number;          // scan duration
}

JavaScript Example

Using the native fetch API (Node 18+, browser, Deno, Bun).

javascript
// JavaScript — send a scan result to Reglint
const payload = {
  scan_id:          crypto.randomUUID(),
  customer_id:      "usr_YOUR_REGLINT_USER_ID",
  agent_name:       "MedicalAdvisorBot",
  industry:         "healthcare",
  final_decision:   "BLOCK",
  violations_count: 1,
  violations: [
    {
      violation_id:   "SSN_EXPOSURE",
      law:            "HIPAA § 164.514",
      description:    "SSN detected in agent response",
      violating_text: "123-45-6789",
      action:         "BLOCK",
      severity:       "critical",
    },
  ],
  original_output:    "Your SSN is 123-45-6789, here is your summary…",
  redacted_output:    "Your SSN is [REDACTED], here is your summary…",
  processing_time_ms: 42,
};

const res = await fetch(
  "https://reglint.ai/api/agent-monitor/webhook",
  {
    method:  "POST",
    headers: {
      "Content-Type":    "application/json",
      "x-reglint-secret": process.env.REGLINT_WEBHOOK_SECRET,
    },
    body: JSON.stringify(payload),
  }
);

const data = await res.json();
// { received: true, id: "agv_..." }
console.log(data);

Python Example

Using the requests library.

python
# Python — send a scan result to Reglint
import os
import uuid
import requests

payload = {
    "scan_id":          str(uuid.uuid4()),
    "customer_id":      "usr_YOUR_REGLINT_USER_ID",
    "agent_name":       "MedicalAdvisorBot",
    "industry":         "healthcare",
    "final_decision":   "BLOCK",
    "violations_count": 1,
    "violations": [
        {
            "violation_id":   "SSN_EXPOSURE",
            "law":            "HIPAA § 164.514",
            "description":    "SSN detected in agent response",
            "violating_text": "123-45-6789",
            "action":         "BLOCK",
            "severity":       "critical",
        }
    ],
    "original_output":    "Your SSN is 123-45-6789, here is your summary…",
    "redacted_output":    "Your SSN is [REDACTED], here is your summary…",
    "processing_time_ms": 42,
}

response = requests.post(
    "https://reglint.ai/api/agent-monitor/webhook",
    json=payload,
    headers={
        "x-reglint-secret": os.environ["REGLINT_WEBHOOK_SECRET"],
    },
    timeout=10,
)

data = response.json()
# {'received': True, 'id': 'agv_...'}
print(data)

Response Codes

StatusMeaning
200 OKPayload received and stored (or idempotent duplicate).
400 Bad RequestMissing required fields: scan_id, customer_id, agent_name, or final_decision.
401 UnauthorizedThe x-reglint-secret header is missing or does not match.
500 Internal Server ErrorUnexpected server error — retry with exponential back-off.

Implementation tip

Generate a fresh scan_id (UUID v4) for every unique scan. If your infrastructure retries on failure, reuse the same scan_id — Reglint will upsert rather than duplicate. Use a queue (SQS, RabbitMQ) to buffer webhooks and retry on 5xx with exponential back-off.

8

Complete Integration Example

A production-ready pattern for wrapping any AI agent with Reglint compliance.

This example wraps any AI agent call with Reglint and handles all four decision outcomes. Drop it into your backend as a utility and call it wherever you invoke an agent.

javascript
const REGLINT_ENDPOINT =
  'https://reglint.ai/api/monitor/scan';

async function runAgentWithReglint(userMessage, agentName, industry) {
  const agentResponse = await myAIAgent.run(userMessage);

  const result = await fetch(REGLINT_ENDPOINT, {
    method: 'POST',
    headers: {
      'x-api-key': process.env.REGLINT_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      agent_output: agentResponse,
      agent_name: agentName,
      industry: industry,
      mode: 'full',
      default_action: 'AUTO'
    })
  }).then(r => r.json());

  switch (result.final_decision) {
    case 'BLOCK':
      return {
        delivered: false,
        message: "Unable to process this request due to compliance restrictions.",
        violations: result.violations
      };
    case 'REDACT':
      return {
        delivered: true,
        message: result.redacted_output,
        violations: result.violations
      };
    case 'ALERT':
      return {
        delivered: true,
        message: agentResponse,
        violations: result.violations
      };
    case 'PASS':
    default:
      return {
        delivered: true,
        message: agentResponse,
        violations: []
      };
  }
}
BLOCK

delivered: false — show a generic error to the user.

REDACT

delivered: true — serve redacted_output instead of the original.

ALERT

delivered: true — serve original. Compliance team is notified via email.

PASS

delivered: true — serve original. No violations found, no action needed.

9

Supported Integrations

Reglint is model-agnostic. Any LLM output, any framework, any language.

Reglint exposes a plain HTTP REST API — there is no SDK required and no vendor lock-in. If your agent can make an HTTP POST request, it works with Reglint. The table below lists tested integrations with copy-paste examples.

Pass agent_name as a human-readable label so violations are correctly attributed in your Agents dashboard.

Provider / FrameworkTypeagent_name suggestionNotes
OpenAI (GPT-4, GPT-3.5)LLM"gpt4o-agent"Scan chat.completions response before returning to user.
Anthropic ClaudeLLM"claude-agent"Scan message.content[0].text from Messages API.
Google GeminiLLM"gemini-agent"Scan response.candidates[0].content.parts[0].text.
Meta Llama (via Ollama)Local LLM"ollama-llama3"Run Ollama locally; scan response.response field.
MistralLLM"mistral-agent"Mistral API or local — scan the text output.
CohereLLM"cohere-agent"Scan response.text from Co.generate or Co.chat.
LangChainFramework"langchain-chain"Intercept chain.invoke() result before returning.
LlamaIndexFramework"llamaindex-query"Wrap QueryEngine.query() response.response.
CrewAIFramework"crewai-crew"Scan crew.kickoff() final output string.
Any custom model (HTTP API)Custom"custom-model"Works with any model accessible via HTTP — local or hosted.

TypeScript + OpenAI (GPT-4o)

Full compliance wrapper using the OpenAI Node SDK and fetch.

typescript
import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const REGLINT_ENDPOINT = 'https://reglint.ai/api/monitor/scan';

async function runCompliantAgent(userMessage: string): Promise<{
  delivered: boolean;
  message: string;
  violations: unknown[];
}> {
  // 1. Get GPT-4o response
  const completion = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user',   content: userMessage },
    ],
  });
  const rawOutput = completion.choices[0].message.content ?? '';

  // 2. Scan with Reglint
  const scan = await fetch(REGLINT_ENDPOINT, {
    method: 'POST',
    headers: {
      'x-api-key': process.env.REGLINT_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      agent_output: rawOutput,
      agent_name:   'gpt4o-assistant',
      industry:     'general',
      mode:         'full',
    }),
  }).then(r => r.json());

  // 3. Enforce decision
  switch (scan.final_decision) {
    case 'BLOCK':
      return { delivered: false, message: 'Response blocked due to compliance violation.', violations: scan.violations };
    case 'REDACT':
      return { delivered: true, message: scan.redacted_output ?? rawOutput, violations: scan.violations };
    default:
      return { delivered: true, message: rawOutput, violations: scan.violations ?? [] };
  }
}

const result = await runCompliantAgent('Summarize the customer account.');
console.log(result.delivered ? result.message : '⛔ Blocked');

Python + Anthropic Claude

Using the anthropic Python SDK with Reglint compliance scanning.

python
import os
import requests
import anthropic

claude = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
REGLINT_API_KEY  = os.environ["REGLINT_API_KEY"]
REGLINT_ENDPOINT = "https://reglint.ai/api/monitor/scan"


def run_compliant_claude(user_message: str, industry: str = "general") -> dict:
    """Run a Claude agent and scan its output with Reglint before returning."""

    # 1. Call Claude
    message = claude.messages.create(
        model="claude-opus-4-7",
        max_tokens=1024,
        messages=[{"role": "user", "content": user_message}],
    )
    raw_output = message.content[0].text

    # 2. Scan with Reglint
    scan = requests.post(
        REGLINT_ENDPOINT,
        json={
            "agent_output":   raw_output,
            "agent_name":     "claude-opus-4-agent",
            "industry":       industry,
            "mode":           "full",
            "default_action": "AUTO",
        },
        headers={"x-api-key": REGLINT_API_KEY},
        timeout=15,
    ).json()

    decision = scan.get("final_decision", "PASS")

    if decision == "BLOCK":
        return {
            "delivered": False,
            "message":   "Blocked — compliance violation detected.",
            "violations": scan.get("violations", []),
        }
    elif decision == "REDACT":
        return {
            "delivered": True,
            "message":   scan.get("redacted_output", raw_output),
            "violations": scan.get("violations", []),
        }
    else:  # ALERT or PASS
        return {
            "delivered": True,
            "message":   raw_output,
            "violations": scan.get("violations", []),
        }


if __name__ == "__main__":
    result = run_compliant_claude("Show me the patient's latest test results.", industry="healthcare")
    if result["delivered"]:
        print("Agent:", result["message"])
    else:
        print("Blocked:", result["message"])
        for v in result["violations"]:
            print(f"  • {v.get('violation_id')} — {v.get('law')}")

Python + Llama (via Ollama)

Run a local Llama model with Ollama and scan its output — zero cloud LLM dependency.

python
import os
import requests

# Ollama runs locally at http://localhost:11434 by default
OLLAMA_ENDPOINT  = "http://localhost:11434/api/generate"
REGLINT_API_KEY  = os.environ["REGLINT_API_KEY"]
REGLINT_ENDPOINT = "https://reglint.ai/api/monitor/scan"


def run_compliant_llama(prompt: str, model: str = "llama3.2") -> dict:
    """Run a local Llama model via Ollama and scan its output with Reglint."""

    # 1. Call Ollama / local Llama
    ollama_res = requests.post(
        OLLAMA_ENDPOINT,
        json={"model": model, "prompt": prompt, "stream": False},
        timeout=60,
    ).json()
    raw_output = ollama_res.get("response", "")

    # 2. Scan with Reglint — use "fast" mode for low latency in local dev
    scan = requests.post(
        REGLINT_ENDPOINT,
        json={
            "agent_output": raw_output,
            "agent_name":   f"ollama-{model}",
            "industry":     "privacy",
            "mode":         "fast",
        },
        headers={"x-api-key": REGLINT_API_KEY},
        timeout=15,
    ).json()

    decision = scan.get("final_decision", "PASS")
    latency  = scan.get("processing_time_ms")
    print(f"[Reglint] decision={decision}, violations={scan.get('violations_count', 0)}, latency={latency}ms")

    if decision == "BLOCK":
        return {"delivered": False, "message": "Response blocked.",                      "violations": scan.get("violations", [])}
    elif decision == "REDACT":
        return {"delivered": True,  "message": scan.get("redacted_output", raw_output),  "violations": scan.get("violations", [])}
    else:
        return {"delivered": True,  "message": raw_output,                               "violations": []}


if __name__ == "__main__":
    result = run_compliant_llama("Tell me about this user's medical history.")
    if result["delivered"]:
        print("Output:", result["message"])
    else:
        print("Blocked — not delivered to user.")

Works With Any Language

Reglint is a plain REST API — no SDK needed. Any programming language that can send an HTTP POST request works out of the box. The integration is always the same three steps:

  1. Get your agent's raw output.
  2. POST it to the Reglint monitor endpoint with your API key.
  3. Check final_decision and enforce accordingly.
PythonTypeScriptJavaScriptGoRustJavaRubyPHPC#KotlinSwiftBash / cURL
bash
# The simplest possible integration — any language, any shell
curl -X POST https://reglint.ai/api/monitor/scan \
  -H "x-api-key: $REGLINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_output":   "'"$AGENT_OUTPUT"'",
    "agent_name":     "my-agent",
    "industry":       "healthcare",
    "mode":           "fast"
  }' | jq '.final_decision'
10

Email Alerts

Configure who gets notified when violations are detected — per agent, per severity, per team.

Reglint can email your team when compliance violations are detected. You control which decisions trigger an alert, minimum severity, and which addresses receive the notification — all in your request payload.

The email_alerts field is optional. When omitted, alerts fall back to the account-level alert email set in Settings → Notifications.

Default Behavior (no email_alerts)

Omit email_alerts and Reglint sends violation alerts to the account-level alert email for any BLOCK or violation-producing scan.

javascript
// Without email_alerts — uses account default alert email (Settings → Notifications)
const response = await fetch('https://reglint.ai/api/monitor/scan', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    agent_output: agentResponse,
    agent_name:   'my-bot',
    industry:     'healthcare',
    mode:         'full',
  }),
});

Custom Email Routing

Add email_alerts to your request body to route alerts to specific teams based on decision and severity:

javascript
// With email_alerts — custom routing to compliance team
const response = await fetch('https://reglint.ai/api/monitor/scan', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    agent_output: agentResponse,
    agent_name:   'healthcare-bot',
    industry:     'healthcare',
    mode:         'full',
    email_alerts: [
      {
        alert_on:     ['BLOCK', 'REDACT'],
        severity_min: 'high',
        receivers:    ['compliance@yourcompany.com'],
      },
    ],
  }),
});

Configuration Schema

typescript
// TypeScript — email_alerts schema
email_alerts?: Array<{
  enabled?:      boolean;                           // default: true — set false to skip
  alert_on?:     ('BLOCK' | 'REDACT' | 'ALERT')[]; // default: all three
  severity_min?: 'low' | 'medium' | 'high' | 'critical'; // default: 'low'
  receivers:     string[];  // required: one or more email addresses
}>

enabled — disable an alert config without removing it

Set enabled: false to temporarily silence a config entry. Useful during deployments, incident response, or testing — the config stays in your code so you can re-enable with a one-character change.

javascript
// Temporarily disable alerts without deleting the config
email_alerts: [{
  enabled:      false,          // ← flip to true to re-enable
  alert_on:     ['BLOCK', 'REDACT', 'ALERT'],
  severity_min: 'high',
  receivers:    ['compliance@company.com'],
}]

alert_on — decisions that trigger an alert

BLOCK

Critical violations — request was suppressed entirely

REDACT

Sensitive data was masked in the response

ALERT

Borderline issues flagged but response delivered

Default: all three when omitted.

severity_min — minimum severity threshold

critical

Only critical violations (SSN, PHI, PCI, credentials)

high

Critical + High (medical data, financial info, location)

medium

Critical + High + Medium (emails, phone numbers)

low

All violations — broadest coverage, most noise

Default: low (sends for all severities).

Multi-Team Routing

Pass multiple configs in the array — each entry is evaluated independently. Different teams get different alerts from the same scan:

javascript
body: JSON.stringify({
  agent_output: agentResponse,
  agent_name:   'customer-service-prod',
  industry:     'general',
  email_alerts: [
    {
      // Critical incidents → CISO immediately
      alert_on:     ['BLOCK'],
      severity_min: 'critical',
      receivers:    ['ciso@company.com'],
    },
    {
      // All violations → Compliance team
      alert_on:     ['BLOCK', 'REDACT', 'ALERT'],
      severity_min: 'low',
      receivers:    ['compliance@company.com'],
    },
    {
      // High-severity → Security team
      alert_on:     ['BLOCK', 'REDACT'],
      severity_min: 'high',
      receivers:    ['security@company.com'],
    },
  ],
})

Industry Examples

Healthcare — Compliance Team

email_alerts: [{
  alert_on: ['BLOCK', 'REDACT', 'ALERT'],
  severity_min: 'low',
  receivers: ['hipaa-compliance@hospital.com'],
}]

Banking — Fraud + Compliance

email_alerts: [{
  alert_on: ['BLOCK', 'REDACT'],
  severity_min: 'high',
  receivers: [
    'fraud@bank.com',
    'compliance@bank.com',
  ],
}]

HR — Legal Team

email_alerts: [{
  alert_on: ['BLOCK', 'ALERT'],
  severity_min: 'medium',
  receivers: ['hr-legal@company.com'],
}]

SaaS — On-Call Only Critical

email_alerts: [{
  alert_on: ['BLOCK'],
  severity_min: 'critical',
  receivers: ['oncall@company.com'],
}]

Environment-Based Routing

Use different alert configs per environment to avoid dev noise in production inboxes:

javascript
// Development — critical only, dev team
const devAlerts = [{
  alert_on:     ['BLOCK'],
  severity_min: 'critical',
  receivers:    ['dev-team@company.com'],
}];

// Staging — high severity, QA team
const stagingAlerts = [{
  alert_on:     ['BLOCK', 'REDACT'],
  severity_min: 'high',
  receivers:    ['qa-team@company.com'],
}];

// Production — all violations, multiple teams
const prodAlerts = [{
  alert_on:     ['BLOCK', 'REDACT', 'ALERT'],
  severity_min: 'low',
  receivers:    ['compliance@company.com', 'security@company.com', 'oncall@company.com'],
}];

const email_alerts = process.env.NODE_ENV === 'production' ? prodAlerts
                   : process.env.NODE_ENV === 'staging'    ? stagingAlerts
                   : devAlerts;

How It Works

1

Your agent sends a scan request with optional email_alerts config.
2

Reglint scans the output and determines final_decision and per-violation severity.
3

For each email_alerts entry, Reglint checks: is final_decision in alert_on? Is top severity ≥ severity_min?
4

If both conditions match, an alert is sent to every address in receivers.
5

Multiple configs → multiple independent email batches. One scan, many teams.

What's in Each Alert Email

Agent name
Industry
Final decision
Violation count
Top violations with severity
Scan ID
Timestamp
Dashboard link
Laws violated

Do

  • Use severity_min: "high" for production critical paths
  • Send to security@ AND compliance@ for critical violations
  • Use distribution lists, not personal emails
  • Test with alert_on: ["BLOCK"] first, then expand
  • Use different configs per environment

Don't

  • Send severity_min: "low" to executive emails (too noisy)
  • Hardcode personal email addresses
  • Set alert_on: ["ALERT"] only — you'll miss BLOCK events
  • Forget to test your alert config before going to production

Per-scan recipient control

Alert recipients are configured per-scan via the email_alerts array in your Reglint config. Each entry can target different receivers, severity thresholds, and decision filters — giving you full control without a shared account-level setting.

11

Request-Level Customization

Override rule actions per-scan without touching your DynamoDB config — useful for testing, staging, or context-specific agents.

Reglint supports two levels of rule customization:

DB

Stored config (DynamoDB)

Persistent, per-customer overrides. Supports BLOCK, REDACT, ALERT, and IGNORE. Set via the Reglint dashboard or direct DynamoDB update. Applied to all scans for your customer ID.

API

Per-request override (API body)

One-time overrides sent in the request body as rules_config. Supports BLOCK, REDACT, ALERT only (not IGNORE). Applied only to this scan — no persistence.

How to Send Per-Request Overrides

Include rules_config directly in your scan request body:

javascript
// Override specific rules for this scan only — no DynamoDB update needed
body: JSON.stringify({
  agent_output: agentResponse,
  agent_name:   'medical-chatbot',
  industry:     'healthcare',
  mode:         'full',
  rules_config: {
    SSN_EXPOSURE:          'REDACT',   // downgrade from BLOCK for this scan
    MEDICAL_DATA_EXPOSURE: 'ALERT',    // downgrade from BLOCK for demo purposes
    LOCATION_TRACKING:     'ALERT',    // keep at default (no change needed if same)
  }
})

Priority Order

When multiple configuration levels exist, Reglint resolves them in this priority order (highest wins):

javascript
// Priority order (highest wins):
// 1. per-request rules_config  ← this request's body
// 2. default_action            ← blanket override, if set
// 3. DynamoDB customer config  ← stored per-customer overrides
// 4. Reglint built-in default  ← each rule's default_action field

// Example: rule SSN_EXPOSURE has built-in default = BLOCK
// DynamoDB config says SSN_EXPOSURE = REDACT
// This request says rules_config.SSN_EXPOSURE = ALERT
// → Final action = ALERT  (per-request wins)
PrioritySourceScopeSupports IGNORE?
1 (highest)Per-request rules_configThis scan onlyNo
2default_action (body field)All rules, this scanNo
3DynamoDB customer configAll scans, this customerYes
4 (lowest)Reglint built-in defaultUniversal fallbackN/A

Rule Groups

Instead of naming every rule, rules_config also accepts group keys whose value is { default_action }. A group sets the action for a whole set of rules at once:

Group keyApplies to
enAll non-Arabic (Layer-1) rules
arAll 13 Arabic Layer-1 rules
ar.sa · ar.ae · ar.eg · ar.qa · ar.kw · ar.bhThat country’s national-ID rule
json
{
  "rules_config": {
    "ar": { "default_action": "alert_hitl" },   // all Arabic rules → hold for review
    "ar.sa": { "default_action": "block" },      // …but Saudi national-ID → block
    "AR_MEDICAL_DATA": "REDACT"                   // …and this one rule → redact
  }
}

Group precedence (highest wins): per-rule id override › country group (ar.sa) › language group (ar/en) ›default_action. Group keys persist in a key›s saved policy exactly like per-rule overrides. A malformed group value is ignored (never weakens enforcement).

Common Use Cases

Testing / Staging environments

Downgrade BLOCK rules to ALERT during test runs so violations are visible in logs but responses aren't suppressed.

Context-specific agents

A legal research agent that legitimately quotes PHI in anonymized case studies can downgrade HIPAA rules to ALERT for that specific agent only.

Gradual rollout

Start with all rules at ALERT, validate your pipeline, then upgrade to BLOCK once you're confident in your integration.

HR training / compliance education tools

Training bots that teach employees about discrimination may intentionally generate examples of prohibited language. Use per-request overrides to audit-log without blocking.

Example: HR Training Mode

Downgrade all 9 employment discrimination rules from BLOCK/ALERT to ALERT for a training agent:

javascript
// HR compliance agent — tone down employment discrimination alerts for training mode
body: JSON.stringify({
  agent_output:   agentResponse,
  agent_name:     'hr-training-bot',
  industry:       'hr',
  mode:           'full',
  rules_config: {
    // During training/testing, downgrade BLOCK to ALERT so responses aren't suppressed
    DISCRIMINATORY_CONTENT:           'ALERT',
    RACIAL_LANGUAGE:                  'ALERT',
    AGE_DISCRIMINATION:               'ALERT',
    PREGNANCY_DISCRIMINATION_CONTEXT: 'ALERT',
    RELIGIOUS_DISCRIMINATION_CONTEXT: 'ALERT',
    MENTAL_HEALTH_DISCRIMINATION:     'ALERT',
    VETERAN_STATUS_DISCRIMINATION:    'ALERT',
    FAMILIAL_STATUS_DISCRIMINATION:   'ALERT',
    AGE_DISCRIMINATION_LANGUAGE:      'ALERT',
  }
})

Full mode: Claude may escalate above your override

In mode: full, Claude AI performs deep legal analysis and may upgrade the decision above your rules_config setting if the regulatory context demands it (e.g., Claude may return BLOCK for a pattern you set to ALERT if it detects severe PHI exposure in context). In mode: fast, your rules_config values are applied exactly. Use mode: fast when you need deterministic enforcement.

12

Trusted User Access

Allow the AI to share PII with verified users while keeping fraud and sanctions protection active.

Security Warning

Setting trusted_users_access: true is intended only for authenticated contexts where the user's identity has been verified. Do not enable this for public chatbots, anonymous users, or any flow before authentication. The customer is responsible for verifying user identity and data entitlement.

A single boolean controls whether Reglint allows data sharing for the current request. Behavioral compliance protections (fraud, sanctions, abuse) remain fully active regardless.

true

Authenticated portal mode

Reglint dismisses PII exposure, account, and transaction disclosure violations. The AI can share the user's own data freely. Wire fraud, sanctions, elder abuse, and other behavioral violations are still caught.

false

Standard mode (default)

All violations are active. PII exposure is blocked. This is the safe default for public-facing deployments.

javascript
const reglintConfig = {
  api_key: "rgl_...",
  endpoint: "https://reglint.ai/api/monitor/scan",
  industry: "finance",
  mode: "full",

  // true  → AI can share PII with verified user (fraud/sanctions still caught)
  // false → all violations active (safe default for public deployments)
  trusted_users_access: true,
};

Good fit

  • Authenticated banking portal (logged-in user, own balance)
  • Healthcare patient portal (verified patient, own records)
  • Enterprise internal tool (verified employee credentials)
  • Logged-in customer service AI assistant

Not a good fit

  • Public website chatbot
  • Marketing AI on landing pages
  • Any flow before user authentication
  • Multi-user shared sessions

Always enforced — even when trusted_users_access: true

Federal Crimes

  • Wire fraud (18 U.S.C. § 1343)
  • Structuring (31 U.S.C. § 5324)
  • AML violations
  • OFAC sanctions bypass
  • Bank fraud

Vulnerable Populations

  • Elder financial abuse
  • Child data (COPPA)
  • Deceased account fraud
  • Impersonation of authority

Compliance Bypass

  • KYC bypass
  • Customer notification bypass
  • Authentication bypass
  • Loan underwriting fraud
json
{
  "final_decision": "PASS",
  "trusted_users_access": true,
  "violations": [],
  "metadata": {
    "v3_dismissed_count": 3,
    "scan_mode": "full"
  }
}
13

Custom Policies

Your own organizational rules, enforced by AI in real time alongside 69 deterministic regulatory patterns.

Custom Policies let your admin write plain-language prohibitions that Reglint enforces on every scan — in addition to built-in regulatory rules. They are evaluated by the same Claude AI that handles HIPAA, GDPR, and the rest of the ruleset. Custom policies are additive only: they can never dismiss or weaken a regulatory violation.

How to write a good rule

One clear prohibition per rule, in plain language. Concrete beats vague:

Good ruleToo vague — avoid
“Never state prices or discounts before manager approval.”“Be careful with pricing.”
“Do not name any competitor in agent output.”“Avoid competitor mentions.”
“Never share internal headcount or revenue figures with external users.”“Keep financials confidential.”

Rule fields

FieldValuesDescription
idCP-001, CP-002 …Auto-assigned sequential ID
rulestring ≤ 300 charsPlain-language prohibition
actionBLOCK · REDACT · ALERTEnforcement action when violated
applies_tohuman · agent · bothWhich actor type this rule targets
channelsnull or channel arraynull = all 8 channels; or restrict to a subset
enabledtrue · falsePer-rule toggle — disabled rules are ignored

How violations appear

Custom policy violations arrive inside the existing violations[] array, indistinguishable to the extension UI. You can tell them apart in the raw payload by two fields:

  • violation_id: the CP id, e.g. “CP-001”
  • source: “custom_policy” (regulatory violations have “rules_engine” or “claude_analysis”)

They appear in the Violations Hub like any other violation. The rule's configured action contributes to the final decision on the same BLOCK > REDACT > ALERT ladder as regulatory rules.

Limits

  • Max 20 rules per API key
  • Max 300 characters per rule
  • Custom policies are additive — they never override or dismiss a regulatory violation
  • The master kill switch (custom_policies_enabled: false) disables all custom rules without deleting them

Example JSON

json
{
  "custom_policies_enabled": true,
  "custom_policies": [
    {
      "id": "CP-001",
      "rule": "Never state prices or discounts before manager approval.",
      "action": "BLOCK",
      "applies_to": "both",
      "channels": null,
      "enabled": true
    },
    {
      "id": "CP-002",
      "rule": "Do not name any competitor in agent output.",
      "action": "ALERT",
      "applies_to": "agent",
      "channels": ["slack", "gmail"],
      "enabled": true
    }
  ]
}
For Humans — Extension + Command Center

Chrome Extension & Command Center

Install the Reglint browser extension to protect Gmail, Outlook, Slack, WhatsApp, and LinkedIn. Admins configure team compliance policy from the Command Center — no local settings needed.

A

Install the Extension

Add Reglint to Chrome in under two minutes.

1

Install from the Chrome Web Store

Search for Reglint in the Chrome Web Store and click Add to Chrome. The extension icon appears in your browser toolbar.
2

Open Settings

Click the Reglint icon in your toolbar, then click the settings gear (or right-click the icon → Options).
3

Enter your API Key

Paste your rgl_… key in the API Key field. Get it from reglint.ai/settings/api-keys. Click Save Settings — the badge turns green (ON).
4

Test the connection

Click Test Connection to confirm your key is valid and the server is reachable. You should see Connected — API responded (decision: PASS).

Your key is shown once. If you lose it, generate a new one from Settings → API Keys. The old key can be revoked from the same page.

B

Supported Channels

Reglint intercepts outgoing messages on five platforms before they are sent.

Gmail

mail.google.com

Intercepts Send button clicks and Ctrl/Cmd+Enter. Scans subject + body combined. Supports subject redaction.

Outlook

outlook.live.com / outlook.office.com

Intercepts the Send button in the compose pane. Scans subject + body combined.

Slack

app.slack.com

Intercepts Enter key and Send button in message input boxes.

WhatsApp Web

web.whatsapp.com

Intercepts Enter key and Send icon in the message composer.

LinkedIn

linkedin.com

Intercepts message Send in Messaging and InMail compose windows.

How it works on every channel

  1. Employee clicks Send (or presses the keyboard shortcut).
  2. Reglint intercepts the action and shows a scanning spinner.
  3. The message text is sent to the Reglint API using the configured API key.
  4. If the scan passes, the message is sent normally.
  5. If a violation is detected, a compliance modal appears — employee can review, proceed with redaction, or cancel.
C

Device Settings

Settings stored on the employee's browser. Each employee configures these once.

API Keyrequired

Your personal or team rgl_… key from reglint.ai/settings/api-keys. Stored encrypted in Chrome sync storage.

e.g. rgl_abc123…
API Endpointrequired

The scan endpoint. Leave at the default unless your organisation self-hosts Reglint.

e.g. https://www.reglint.ai/api/monitor/scan
Employee Display Name / Emailoptional

Override how the sender appears in violation logs. Leave blank to auto-detect from the Chrome profile or the open platform (Gmail, etc.).

e.g. alice@company.com
On API Erroroptional

Fail Open (default) — allow send if the Reglint API is unreachable. Fail Closed — block send if the API is unreachable. Admins can override this via server-side key policy.

e.g. fail-open

Scan policy is not set in the extension. Industry, scan mode, violation behavior, and per-rule configuration are all controlled by your admin in the Command Center and applied server-side to every employee using the same API key.

D

Admin Policy via Command Center

Admins set team compliance policy on each API key — no employee action required.

1

Go to Settings → API Keys

Sign in to your Reglint account and navigate to Settings → API Keys. Each key represents a team or department.
2

Click "Edit Policy" on a key

Each key row has an Edit Policy button. This opens the policy editor modal.
3

Configure the policy

The editor has two views — Form and JSON. Both are kept in sync.

Policy Fields

FieldOptionsWhat it controls
Team LabelAny textHuman-readable name shown in violation logs and alerts.
Industryhealthcare · fintech · hr · privacy · generalFilters the per-rule table to show relevant rules and tells the scan engine which regulations to prioritise.
Scan Modefast · fullfast = regex only (ms). full = RAG + Claude (2–8s, contextual).
Default ActionBLOCK · REDACT · ALERTBlanket enforcement for all violations when no per-rule override exists.
Violation Behaviorblock · warn-only · log-onlyblock = prevent send, show modal. warn-only = show modal, allow override. log-only = silent, no modal.
On API Errorfail-open · fail-closedWhat happens when the Reglint API is unreachable.
Trusted Users Accesson / offAllow the AI to share PII with authenticated users (fraud/sanctions still caught).
Per-Rule OverridesBLOCK · REDACT · ALERT · IGNORE per ruleOverride the default action for individual compliance rules.

Industry filter on the per-rule table

When you select an Industry in the Form view, the per-rule configuration table automatically filters to show only the rules relevant to that industry — for example, selectinghealthcareshows HIPAA, HITECH, CMIA, and GINA rules; selectinghr shows Title VII, ADEA, ADA, and GINA rules. Leave industry unset to see all 55 rules.

JSON View

Switch to the JSON tab to view and edit the full policy as structured JSON. The Form and JSON views stay in sync — changes in either are reflected in the other.

json
{
  "teamLabel":          "Clinical AI Team",
  "industry":           "healthcare",
  "mode":               "full",
  "defaultAction":      "BLOCK",
  "behavior":           "block",
  "failMode":           "fail-closed",
  "trustedUsersAccess": false,
  "rulesConfig": {
    "MEDICAL_DATA_EXPOSURE": "REDACT",
    "CONTACT_PHI_COMBINATION": "ALERT",
    "LOCATION_TRACKING": "IGNORE"
  }
}
E

Policy Hierarchy

Server-side key policy overrides all local extension defaults — employees see the effect automatically.

When the Reglint API processes a scan request from the extension, it applies the policy attached to the API key server-side. The employee never has to change anything locally — the admin's policy takes effect for every scan on that key.

1 (highest)

Server key policy

Set by admin in Command Center. Overrides everything below.

2

Extension device defaults

Fail mode set by employee in Options page. Applies only if server policy field is null.

3 (lowest)

Reglint built-in defaults

industry=general, mode=full, behavior=block — applied when neither policy nor extension sets the field.

What admins control (server-side)

  • Industry & scan mode
  • Default violation action (BLOCK / REDACT / ALERT)
  • Violation behavior (block / warn-only / log-only)
  • Fail mode (open / closed)
  • Trusted users access
  • Per-rule action overrides

What employees control (device-side)

  • API key (required)
  • API endpoint (default unless self-hosting)
  • Display name / email override (optional)
  • On API Error fallback (if not set by admin)
14

Action-Level Scanning (beta)

Scan a proposed tool call before the agent executes it.

In addition to scanning agent output text, you can ask Reglint to evaluate a proposed tool call before it executes. Pass the two optional fields alongside your normal request — when absent, behaviour is identical to today.

New optional request fields

proposed_actionobject | null — the tool call the agent wants to make: { tool: string, args: object }
declared_rationalestring | null — the agent's stated reason for the action (max 1 000 chars)

How it works

1

Rules engine on action args (fast + full mode)

The action is serialised to JSON and run through the existing 41-rule engine. PII inside args — e.g. an SSN in an email body — is caught by the same patterns that guard output text. The result appears as a normal rules_engine violation.
2

LLM risk evaluation (full mode only)

In full mode the LLM (Claude / Gemini) also receives the proposed action and rationale. It flags HIGH_RISK_ACTION when the operation is irreversible (payments, transfers, deletions, mass sends), when the args contain third-party sensitive data, or when the rationale does not justify the action.

Request example

json
POST /api/monitor/scan
x-api-key: rgl_...

{
  "agent_output": "I will process the wire transfer now.",
  "proposed_action": {
    "tool": "transferMoney",
    "args": { "amount": 50000, "to_account": "external-unverified" }
  },
  "declared_rationale": "customer asked",
  "mode": "full"
}

Response — HIGH_RISK_ACTION violation

json
{
  "final_decision": "ALERT",
  "violations": [
    {
      "violation_id": "HIGH_RISK_ACTION",
      "severity": "high",
      "law": "Operational Compliance",
      "description": "Agent proposes an irreversible $50,000 wire transfer to an unverified external account with insufficient rationale.",
      "recommended_action": "ALERT",
      "source": "gemini_analysis"
    }
  ]
}
Beta notice: Action-level scanning is available today with no schema changes required. HIGH_RISK_ACTION is a normal LLM-added violation — it is subject to privacy mode filtering, customer config ceilings, and all existing dismissal rules. It is not a hard-floor violation.
15

Human-in-the-Loop (HITL)

Hold high-risk output for a person to approve, reject, or edit before it is delivered.

ALERT_HITL

Signal, not execution

When the engine assigns ALERT_HITL, the item is held — not delivered — and routed to your pending Review Queue at /dashboard/agents/queue. A reviewer resolves it with Approve, Reject, or Edit. Three rules apply to every integration below:

  • 1.Reglint provides the signal; your client executes. On approval Reglint flips a status — it never sends, delivers, or acts on your behalf. Your code performs the action and your credentials never leave your system.
  • 2.HITL requires Full mode. Deep review runs in mode: "full". In Fast mode a would-be HITL item degrades to a plain ALERT (delivered + logged, never held).
  • 3.The review email is mandatory. A held item always emails your alert address (and any email_alerts receivers). It bypasses alert_on / severity_min and cannot be disabled.

HITL Status Endpoint (polled)

GEThttps://reglint.ai/api/agent-monitor/disposition-status?scan_id=<id>
HEADERx-api-key: YOUR_API_KEY

Read-only. Returns { scan_id, hitl_status, final_decision } where hitl_status none | pending | approved | rejected | edited. Rate-limited to ~60 requests/min per key — poll politely.

Guide 1 — Chrome Extension (automatic hold & release)

For teams using the Reglint extension. No code — the extension does the hold and the poll for you.

1

Set a HITL rule

In Team Policy, set a rule (or the default action) to HITL. When an outgoing message triggers it across Gmail, Outlook, Slack, Teams, WhatsApp, LinkedIn, or ChatGPT / Claude web chat, the extension intercepts the send.
2

The send is held

The draft stays in the composer — no "send anyway" override. A mandatory email alert fires and the item appears in the Review Queue as pending.
3

The extension polls (~6s)

While the compose window stays open, the extension polls the status endpoint every ~6 seconds and shows a live "watching the Review Queue" indicator.
4

Release on decision

On Approve → the message auto-sends. On Reject → it stays held (edit and try again). On Edit → it is not auto-sent; open the queue to see the reviewer's version.
Honest caveat: auto-release works only while the composer stays open (up to a 15-minute cap). If you close the window before approval, the poll stops — approve the item in the Review Queue, then re-send the message manually. Nothing is ever sent without a scan.

Guide 2 — n8n (Wait + poll pattern)

For n8n workflows that scan agent output, then gate the delivery action on a human decision.

1

HTTP Request — Scan

POST to /api/monitor/scan withmode: "full" and headerx-api-key.
2

IF — is it held?

Branch on {{ $json.final_decision === 'ALERT_HITL' }}. False → deliver as normal. True → capture scan_id in a Set node.
3

Wait → poll loop

Wait 10–30s → HTTP Request GET the status endpoint → IF onhitl_status. Loop back to Wait while pending. Add a max-iteration guard (a sensible timeout) so the loop can't run forever.
4

Act on the decision

approved → run your delivery action.rejected → stop.edited → deliver the returned edited_content (the reviewer's edit is the final decision).
text
[Trigger]
   │
[HTTP Request: POST /api/monitor/scan]   body: { agent_output, agent_name, mode: "full" }
   │                                       header: x-api-key: YOUR_API_KEY
[IF  {{ $json.final_decision === 'ALERT_HITL' }}]
   ├─ false ─▶ [Deliver action]           (PASS / ALERT / REDACT handled as usual)
   └─ true  ─▶ [Set: scan_id = {{ $json.scan_id }}]
                  │
              ┌─▶ [Wait  20s]
              │      │
              │  [HTTP Request: GET /api/agent-monitor/disposition-status?scan_id={{ $json.scan_id }}]
              │      │                       header: x-api-key: YOUR_API_KEY
              │  [Switch on {{ $json.hitl_status }}]
              │      ├─ pending  ─┘ (loop back to Wait; cap at e.g. 45 iterations ≈ 15 min)
              │      ├─ approved ─▶ [Deliver action]
              │      ├─ rejected ─▶ [Stop / notify]
              │      └─ edited   ─▶ [Deliver {{ $json.edited_content }} — the reviewer's edit is final]
Poll politely. A 20s Wait ≈ 3 requests/min — far under the ~60/min per-key limit. Don't drop below ~10s. On edited, the status response includes the reviewer'sedited_content — deliver that; the reviewer's edit is the final decision.

Guide 3 — Custom Agent / API (the developer contract)

The raw contract for any custom integration. Three steps: scan, poll, act.

1

Scan → maybe held

POST your output to /api/monitor/scan. A held response returns final_decision: "ALERT_HITL",safe_to_deliver: false, and ascan_id. Do not deliver — hold your action.
2

Poll the status endpoint

GET /api/agent-monitor/disposition-status?scan_id=<id>with your x-api-key untilhitl_status leaves pending.
3

Act — your code, your credentials

approvedyour code executes the action (Reglint only signals). rejected → discard.edited → deliver the returnededited_content (the reviewer's edit is the final decision).
javascript
const BASE = 'https://reglint.ai';

// 1) Scan. A held item comes back ALERT_HITL / safe_to_deliver:false / scan_id.
async function scan(agentOutput) {
  const r = await fetch(BASE + '/api/monitor/scan', {
    method: 'POST',
    headers: { 'x-api-key': process.env.REGLINT_API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ agent_output: agentOutput, agent_name: 'my-agent', mode: 'full' }),
  });
  return r.json();
}

// 2) Poll disposition-status with backoff + a hard timeout. Returns the terminal status.
async function waitForDecision(scanId, { intervalMs = 15000, timeoutMs = 15 * 60 * 1000 } = {}) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const r = await fetch(
      BASE + '/api/agent-monitor/disposition-status?scan_id=' + encodeURIComponent(scanId),
      { headers: { 'x-api-key': process.env.REGLINT_API_KEY } },
    );
    if (r.status === 429) { await sleep(intervalMs * 2); continue; }   // backoff on rate limit
    if (r.status === 404) { await sleep(intervalMs); continue; }        // row not landed yet
    if (!r.ok) throw new Error('status ' + r.status);                   // 400/401 = fix your call
    const data = await r.json();  // { scan_id, hitl_status, final_decision, edited_content? }
    if (data.hitl_status !== 'pending' && data.hitl_status !== 'none') return data;
    await sleep(intervalMs);
  }
  return 'timeout';
}

const sleep = (ms) => new Promise((res) => setTimeout(res, ms));

// 3) Act — Reglint signals, YOUR code executes.
const result = await scan(agentOutput);
if (result.final_decision !== 'ALERT_HITL') {
  deliver(result);                       // PASS / ALERT / REDACT — your normal path
} else {
  const outcome = await waitForDecision(result.scan_id);
  if (outcome.hitl_status === 'approved')      deliver({ ...result, original_output: agentOutput });
  else if (outcome.hitl_status === 'rejected') discard(result.scan_id);
  else if (outcome.hitl_status === 'edited')   deliver({ ...result, original_output: outcome.edited_content }); // reviewer's edit is final
  else /* timeout */                           escalateToOps(result.scan_id, outcome);
}

Status endpoint response codes

200OK — returns { scan_id, hitl_status, final_decision }.
400Missing scan_id query parameter.
401Missing or invalid x-api-key (must start with rgl_).
404Scan not found — or not owned by this key (no cross-tenant leak).
429Rate limited (~60/min per key). Back off and retry.
16

SIEM Integrations

Stream compliance events — scans, HITL decisions, and dispositions — to Datadog or a generic signed webhook.

Ship your audit trail to your SIEM

Configure an export under Settings → Integrations. Reglint then streams each compliance event to Datadog (Logs API) or a generic signed webhook (Splunk HEC and others). Events are metadata only — statutes, severities, decisions, and IDs. Message content and violating_text are never exported.

  • The API key is write-only. It is stored AES-256-GCM encrypted and never shown again after saving.
  • Delivery is durable. Events queue in an outbox and are retried on failure — they survive a transient SIEM outage or a Reglint restart.
  • Event filter. Choose Violations + HITL (default), All scans (incl. clean passes), or HITL only.

Datadog

Compliance events land as structured logs, queryable in Log Explorer within seconds.

1

Create a Datadog API key

In Datadog, go to Organization Settings → API Keys → New Key. Copy the API key (not an Application key).
2

Set your Datadog site

In Settings → Integrations, pick Datadog and enter your site — the host in your Datadog URL. Examples: datadoghq.com (US1, default), us5.datadoghq.com (US5), datadoghq.eu (EU). Reglint posts to https://http-intake.logs.<site>/api/v2/logs.
3

Choose events + enable

Set the event filter, paste the API key, toggle Enabled, and Save.
4

Send a test event

Click Send test event. Reglint delivers a synthetic scan_completed through the real delivery path and shows the HTTP result inline (Datadog returns 202 on success).
5

Verify in Log Explorer

Filter on service:reglint-monitor (or ddsource:reglint). Each log carries tags — customer, event, decision, channel — plus the full event as structured attributes.

Example log in Datadog:

json
{
  "ddsource": "reglint",
  "service": "reglint-monitor",
  "ddtags": "env:prod,customer:usr_123,event:scan_completed,decision:alert,channel:gmail",
  "message": "reglint scan_completed ALERT",
  "event_type": "scan_completed",
  "event_id": "3f8c1a4e-…",
  "occurred_at": "2026-07-03T14:22:05.001Z",
  "customer_id": "usr_123",
  "scan_id": "scan_abc",
  "agent_name": "support-bot",
  "final_decision": "ALERT",
  "violations_count": 1,
  "violations": [
    { "violation_id": "SSN_EXPOSURE", "law": "GLBA", "type": "pii", "severity": "high" }
  ]
}

Generic webhook

Point Reglint at any HTTPS collector (Splunk HEC, a Lambda, your own service). Each event is POSTed as JSON, signed so you can verify it came from Reglint.

  • Endpoint must be https:// — plaintext http:// is rejected when you save.
  • Body is the raw event JSON (see the schema below).
  • Signature. Every request carries X-Reglint-Signature: sha256=<hex>, an HMAC-SHA256 of the raw body keyed by the signing secret you set in the config. Verify it before trusting the payload.

Verify the signature (Node, Express):

js
import crypto from 'crypto';
import express from 'express';

const app = express();
// Use the RAW body — the signature is over the exact bytes we sent.
app.post('/reglint', express.raw({ type: 'application/json' }), (req, res) => {
  const secret = process.env.REGLINT_SIGNING_SECRET;
  const expected = 'sha256=' + crypto.createHmac('sha256', secret)
    .update(req.body)          // Buffer of the raw request body
    .digest('hex');
  const got = req.get('X-Reglint-Signature') || '';

  const a = Buffer.from(got);
  const b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return res.status(401).end();   // reject forgeries
  }

  const event = JSON.parse(req.body.toString('utf8'));
  // …forward to your SIEM…
  res.status(200).end();            // 2xx = acknowledged
});
Retry & backoff. Return a 2xx quickly to acknowledge. On any non-2xx response or network error, Reglint retries the event with exponential backoff — 1m → 5m → 30m → 2h → 6h — up to 8 attempts, then marks it failed. Deliveries are at-least-once; dedupe on event_id if you need exactly-once.

Event schema

Every event shares a common envelope, plus fields specific to its event_type. All events are metadata only.

Common envelope (on every event):

  • event_typescan_completed | hitl_decision | disposition_reported
  • event_idUUID, stable dedupe key
  • occurred_atISO-8601 timestamp
  • customer_idyour Reglint account id

scan_completed — a scan finished.

json
{
  "event_type": "scan_completed",
  "scan_id": "scan_abc",
  "agent_name": "support-bot",
  "industry": "legal",
  "channel": "gmail",                 // null for agent (API) traffic
  "actor_type": "human",              // "human" | "agent"
  "actor_id": "employee@corp.com",
  "final_decision": "ALERT",          // PASS | ALERT | REDACT | BLOCK | ALERT_HITL
  "violations_count": 1,
  "violations": [
    { "violation_id": "SSN_EXPOSURE", "law": "GLBA", "type": "pii",
      "severity": "high", "description": "…" }
  ],
  "processing_time_ms": 812
}

hitl_decision — a reviewer resolved a held item.

json
{
  "event_type": "hitl_decision",
  "scan_id": "scan_abc",
  "agent_name": "support-bot",
  "decision": "edited",               // approved | rejected | edited
  "reviewer_id": "usr_123",
  "edited": true,
  "delivery_mode": "auto",            // "auto" | "consent" | null (only on edited)
  "has_note": true
}

disposition_reported — the final send outcome of a flagged/held item.

json
{
  "event_type": "disposition_reported",
  "scan_id": "scan_abc",
  "agent_name": "support-bot",
  "final_decision": "ALERT",
  "disposition": "sent_edited"
  // blocked_by_user | sent_redacted | sent_original_override
  // | sent_on_approval | sent_edited | edit_applied
}

Reglint Layer 2 Agent Monitor — Developer Docs

Back to top