What Should an AI Security API Return?
AI security API response design — request IDs, verdicts, findings, risk, reasons, confidence, usage units, and consistent error models.
A production AI security API is only as useful as its response contract. Integrators need stable fields they can route on, log for audits, meter for billing, and correlate during incidents — without parsing natural-language messages or vendor-specific prose.
This guide documents what a well-designed security API should return, using real IdenticAPI response fields: request_id, verdict, findings, risk, and usage_units — plus supporting metadata your middleware should persist.
For endpoint specifics, see API Reference, Unified Guard, and Combine AI Security Guardrails.
Design goals
| Goal | Why it matters |
|---|---|
| Machine-routable | Policy engines branch on enums, not prose |
| Auditable | Security teams trace decisions months later |
| Correlatable | Support links user reports to scanner results |
| Meterable | Finance predicts cost; SRE detects abuse |
| Versioned | Detector upgrades do not silently change semantics |
| Fail-distinct | HTTP errors ≠ block verdicts |
IdenticAPI responses follow these goals across individual detectors and Unified Guard.
Core fields (every successful scan)
request_id
Unique identifier for the API call. Store it alongside your application request ID.
"request_id": "req_abc123"
Use in middleware: log request_id + app trace_id; pass to support tooling; never substitute user content when reporting issues.
Error responses also include request_id (and X-Request-Id header). See Errors.
api
Product identifier for the endpoint that served the request.
"api": "prompt-injection-shield"
Unified Guard returns "api": "unified-guard". Helps when one log stream receives multiple detector types.
verdict (single-check endpoints)
Assessment result for standalone detectors:
| Endpoint family | Verdict values |
|---|---|
| Prompt Injection, PII, Output Safety | safe, suspicious, unsafe |
| Agent Action Guard | allow, review, block |
"verdict": "unsafe",
"risk": "high",
"findings": [
{
"category": "instruction_override",
"reason": "Instruction override pattern detected",
"confidence": 0.92,
"start": 0,
"end": 42
}
],
"reasons": ["Instruction override pattern detected"]
Policy mapping: your code translates verdict + risk + categories to allow, review, or block — the API does not execute product policy for you.
findings
Structured array — the primary integration surface for tuning and audit.
Typical finding fields:
| Field | Purpose |
|---|---|
category | Machine enum (email, instruction_override, unsafe_html, …) |
reason | Human-readable explanation |
confidence | Optional score for ranking or review priority |
start / end | Optional character offsets for redaction UI |
Route policy on category, not only top-level verdict. Two suspicious responses with different findings[].category may deserve different actions.
PII example:
"findings": [
{ "category": "email", "reason": "Detected email (pii)", "confidence": 0.95, "start": 12, "end": 28 }
]
When redact: true on PII checks, use offsets or redacted_text to transform prompts before the LLM call.
risk
Severity hint: low, medium, high (and critical in some contexts per glossary).
Maps loosely to verdict — safe/allow → lower risk; unsafe/block → higher. Use risk + category together for review thresholds, not risk alone.
usage_units
Billable units consumed by this request.
"usage_units": 1
- Single-detector calls: typically
1 - Unified Guard: one unit per check (max four checks per request)
"usage_units": 2
Log usage_units for cost attribution per feature, tenant, or route. See Usage & Billing.
Supporting metadata fields
reasons
Flat list of human-readable strings — convenient for reviewer UIs and logs when you should not expose full finding objects to all systems.
confidence
Optional per-finding or aggregate signal. Do not treat as probability without vendor documentation. Useful for sorting review queues.
processing_time_ms
Server-side processing duration. Measure end-to-end latency in your region separately — network dominates many deployments.
detector_version
Engine version string (e.g. "1.0.0"). Annotate dashboards when block rates shift after upgrades.
redacted_text (PII path)
Returned when redact: true and findings exist. Substitute into LLM payload per policy.
Unified Guard: decision + checks[]
Orchestrated responses add an overall decision and per-check breakdown:
{
"request_id": "req_abc123",
"api": "unified-guard",
"decision": "review",
"checks": [
{
"check": "prompt_injection",
"verdict": "allow",
"risk": "low",
"findings": [],
"reasons": ["No injection patterns detected"]
},
{
"check": "pii_secrets",
"verdict": "review",
"risk": "medium",
"findings": [{ "category": "email", "reason": "Detected email (pii)" }],
"reasons": ["Detected email (pii)"]
}
],
"usage_units": 2,
"processing_time_ms": 45,
"detector_version": "1.0.0"
}
Decision priority: block > review > allow.
Persist the full checks[] array — not only decision — so incident response knows which detector fired.
Error response design
Security APIs must distinguish:
| Situation | HTTP | Body signal | App behavior |
|---|---|---|---|
| Content flagged | 200 | verdict: unsafe or decision: block | Policy block |
| Invalid input | 400 | error.code, error.message | Fix client |
| Auth failure | 401 | error object | Rotate key |
| Rate limit | 429 | error + retry guidance | Backoff |
| Server error | 5xx | request_id in error | Fail-open or fail-closed per policy |
Never map HTTP 500 to "allow because no verdict." Explicitly implement fail-open vs fail-closed.
Example error shape:
{
"error": {
"code": "invalid_request",
"message": "text exceeds maximum length"
},
"request_id": "req_abc123"
}
Middleware integration pattern
type GuardResult = {
requestId: string;
verdict: "safe" | "suspicious" | "unsafe";
risk: string;
findings: Array<{ category: string; reason: string }>;
usageUnits: number;
};
async function screenInput(text: string): Promise<GuardResult> {
const res = await fetch("https://www.identicapi.com/api/v1/security/prompt-injection", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.IDENTICAPI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ text, source: "chat_input" })
});
if (!res.ok) {
// Distinct from unsafe verdict — apply outage policy
throw new ScannerUnavailableError(await res.json());
}
const data = await res.json();
return {
requestId: data.request_id,
verdict: data.verdict,
risk: data.risk,
findings: data.findings,
usageUnits: data.usage_units
};
}
Log requestId, verdict, risk, finding categories, and usageUnits — not necessarily full text.
Schema stability and CI
Assert in tests:
- Required keys exist (
request_id,verdictordecision,findings,risk,usage_units) - Verdict enums are members of documented sets
findings[].categoryis a string- Error responses include
request_id
Pin detector_version in regression notes when baselines change.
What not to put in responses
| Avoid | Prefer |
|---|---|
| Only a numeric "risk score" | verdict + findings[].category |
| Natural-language-only results | Structured findings + reasons |
| Echoing full input in errors | request_id + error code |
| Implicit "guarantee" language | Document verdicts as risk signals |
Verdicts are risk signals, not legal guarantees or compliance certifications.
Field checklist for vendor evaluation
When comparing guardrail APIs, require:
-
request_idon success and error - Structured
findingswith categories - Documented verdict enum per check type
- Explicit
usage_unitsor equivalent metering -
processing_time_msor latency header - Version field for detector changes
- Distinct HTTP errors vs block verdicts
- Multi-check breakdown (or honest single-check only)
See AI Guardrails API for evaluation criteria.
Summary
Production integrations center on five fields:
request_id— correlation and supportverdict/decision— routingfindings— category-level policy and auditrisk— severity hints for review queuesusage_units— cost and abuse monitoring
IdenticAPI implements this contract across Prompt Injection Shield, PII & Secrets Detection, AI Output Safety, Agent Action Guard, and Unified Guard. Your middleware owns policy; the API owns structured risk signals.
Frequently asked questions
What fields should every AI security API response include?
At minimum: request_id for correlation, verdict or decision for routing, findings with categories for audit and tuning, risk for severity hints, and usage_units for metering. IdenticAPI also returns reasons, processing_time_ms, and detector_version.
What is the difference between verdict and decision in IdenticAPI?
Single-detector endpoints return verdict (safe/suspicious/unsafe or allow/review/block). Unified Guard returns an overall decision plus a checks array with per-check verdicts. Decision priority is block > review > allow.
How should applications use the findings array?
Route policy on findings[].category — not only top-level verdict. Two suspicious responses with different categories may deserve different actions. Log categories and request_id; avoid logging raw secrets in production.
How are usage_units calculated?
Single-detector calls typically consume one usage unit. Unified Guard charges one unit per check in the request, up to four checks maximum. The usage_units field in each response reflects units consumed for that call.
How should HTTP errors differ from block verdicts?
A 200 response with verdict unsafe or decision block is a policy signal. HTTP 4xx/5xx are transport or validation failures. Applications must implement explicit fail-open or fail-closed behavior on errors — never treat a 500 as implicit allow.
Related reading
- AI Guardrails API: What Developers Should Look For
Evaluate AI guardrails APIs — supported checks, latency, error handling, consistent verdicts, privacy, and integration c…
- Designing Allow, Review and Block Security Decisions
Design allow, review, and block security decisions — why ternary verdicts beat binary flags for high-impact operations a…
- How to Detect PII in Text with an API
Use a PII detection API to scan user input, logs, and LLM context. Request format, response fields, verdict semantics, a…