analyze() returns. The shape is the same
whether you call the HTTP endpoint, the Python SDK, or the TypeScript
SDK; the SDKs add a small ergonomic layer on top.
High-level shape
sdk/openapi/openapi.json;
the auto-rendered API reference is the
authoritative source.
Top-level fields
| Field | Meaning |
|---|---|
request_id | Echo of the X-Request-ID response header. Always quote this in support tickets. |
policy_id / policy_slug | Which combined policy ran. |
overall_status | OK (every analyzer passed), TERMINATED_EARLY (a termination rule fired), or ERROR (one or more analyzers errored). |
terminated_early | Boolean shortcut for overall_status == "TERMINATED_EARLY". |
termination_reason | Present when terminated_early == true. Names the analyzer and the rule that fired. |
analyzer_results | Per-analyzer block. Status is OK, TERMINATED_EARLY, ERROR, or SKIPPED. |
aggregated_metrics | Sum of per-analyzer wall-clock and cost. Only present when the policy’s default_telemetry is true. |
SDK ergonomics
The SDKs unpack the body into aDecision object:
blocked_by / blockedBy is the easiest lever for branching in
application code:
adversarial_detection_analyzer) to
canonical names (prompt-injection-jailbreak) so your code stays
stable even if the server-side key flips later. See
Versioning.
Per-analyzer blocks
Every analyzer reports its result inanalyzer_results.<server_key>.
The shape is consistent across analyzers:
| Field | Meaning |
|---|---|
status | OK, TERMINATED_EARLY, ERROR, SKIPPED. |
output | Analyzer-specific structured output. See the per-analyzer page. |
metrics | Map of metric name → value. The dashboard editor exposes the same names. |
terminated_by | Present when this analyzer is the one that terminated the run. |
error | Present when status == "ERROR". |
status: "SKIPPED" — they were declared
in the policy but never reached because an earlier analyzer
terminated.
Example: an inbound block by the prompt-injection classifier
0.97 on INJECTION/JAILBREAK, which crossed
both the score threshold (>= 0.85) and the output match in
default-inbound. The execution engine terminated immediately and
flipped overall_status to TERMINATED_EARLY. The remaining
analyzers were skipped.
Example: outbound flag by safety + SDP
is_safe boolean rule terminated the run.
Errors at the analyzer level
A single analyzer error does not always mean the whole call errored. Behavior depends on the step type:- In a sequential step, the first analyzer that errors stops the
step and flips
overall_statustoERROR. - In an asynchronous step, every analyzer in the group still runs
to completion. Any error in the group flips
overall_statustoERROR, but you’ll see the other analyzers’ results too.
overall_status == "ERROR" and the cause is upstream
infrastructure (model service unreachable, DLP API down), the API
response is HTTP 503 with code: "analyzer_unavailable" instead of
a 200 with embedded errors. SDKs retry these automatically. See
analyzer_unavailable.
Termination reason
Whenterminated_early == true, the response carries a structured
termination_reason:
| Field | Meaning |
|---|---|
analyzer | The server key of the analyzer whose rule fired. |
rule | A human-readable description of which signal terminated. |
match | Present when output_match was used. The matched substring. |
metric / value / operator | Present when a threshold rule fired. |
Aggregated metrics
When the policy’sdefault_telemetry is true, the response carries
totals across the run:
| Metric | Meaning |
|---|---|
total_processing_time_ms | Sum of analyzer wall-clock. Useful for SLO tracking. |
total_cost_usd | Sum of analyzer cost (when each analyzer reports a cost). |
Headers worth inspecting
X-Request-ID— same value asrequest_idin the body.X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset— current rate-limit window state.X-Billing-Status,X-Subscription-Status— subscription health.activeis normal;past_due/canceledflag attention.X-Agnes-Test-Mode: true— sandbox response. Exclude from billing dashboards.
Common questions
Why doesblocked_by have multiple analyzers? Asynchronous steps
can have more than one analyzer terminate in the same step. The SDK
reports every analyzer that fired a terminate_immediately rule.
Where is the prompt in the response? It is not echoed back. The
SDKs keep the input you sent locally; the server does not persist it
unless you explicitly ingest into the threat-intel store.
Can I get the cost in tokens, not dollars? total_cost_usd is the
public field. The metered usage report at
agnes.lasscyber.com/agnes-info/billing
shows token-level metering for billing reconciliation.
Next
- Errors — what every error response looks like.
- Combined analyzer — author the
termination rules that decide what
terminated_earlymeans. - API reference — full auto-rendered schema with interactive playground.