What a guardrail's checks came to in a project
const url = 'https://example.com/v1/guardrails/example/outcomes?projectId=example&from=2026-04-15T12%3A00%3A00Z&to=2026-04-15T12%3A00%3A00Z';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://example.com/v1/guardrails/example/outcomes?projectId=example&from=2026-04-15T12%3A00%3A00Z&to=2026-04-15T12%3A00%3A00Z' \ --header 'Authorization: Bearer <token>'Counts from the server, over a window: how many of the guardrail’s checks on agent turns in the project passed, were violated (the answer went through: log-only, noop, or an action handed back; or a retry sent it back for a new one), blocked (a halt failed the turn, or a retry whose attempts had run out) or errored (the check couldn’t run; a halt guardrail’s error fails the turn too, and is counted here). The same counts per agent version, and the window’s latest blocked turns, by run id and time only: a blocked answer stays behind its run’s page. A guardrail whose scope didn’t match a turn wasn’t checked on it. A check is counted per answer it judged: a guardrail judges a turn’s final answer, and, in a turn with a retry guardrail, its halt and retry guardrails judge each answer. Replays and dry runs aren’t counted. Outcomes go with their run’s retention, so a window can hold fewer than asked; recordedSince says how far back they go. A guardrail no longer registered still has its outcomes. Needs read on the guardrail and on the project.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”GuardrailId — unique identifier for the guardrail.
Query Parameters
Section titled “Query Parameters”The project whose agent turns are counted.
Checks at or after this time (ISO 8601).
Checks before this time (ISO 8601). At most 90 days after from.
How many of the latest blocked turns to name: 0 to 50, 10 by default.
Responses
Section titled “Responses”The outcomes.
object
How many of a guardrail’s checks came to each outcome: one check per answer it judged. A guardrail judges a turn’s final answer. In a turn with a retry guardrail, its halt and retry guardrails judge each answer, so a turn that sent answers back counts a check of those for each.
object
The check ran and found nothing.
The check found something and the answer went through (log-only, noop, or an action handed back), or a retry sent it back for a new one.
The check found something and its action failed the turn: a halt, or a retry whose attempts had run out.
The check couldn’t run (no such check, a bad configuration, a judge that couldn’t be routed).
The same counts per agent version, the most checked first, at most 100.
The counts on one agent version’s turns.
object
The check ran and found nothing.
The check found something and the answer went through (log-only, noop, or an action handed back), or a retry sent it back for a new one.
The check found something and its action failed the turn: a halt, or a retry whose attempts had run out.
The check couldn’t run (no such check, a bad configuration, a judge that couldn’t be routed).
The window’s latest blocked turns, newest first, at most recent.
A turn the guardrail blocked: its run, never its answer.
object
When the guardrail checked.
The earliest outcome kept for this guardrail in this project, in any window: nothing before it is counted. Outcomes were first recorded in 0.1.6, and they go with their run’s retention. Absent when none is kept.
Examplegenerated
{ "guardrailId": "example", "from": "2026-04-15T12:00:00Z", "to": "2026-04-15T12:00:00Z", "counts": { "passed": 1, "violated": 1, "blocked": 1, "errored": 1 }, "byAgentVersion": [ { "agentId": "example", "agentVersion": "example", "passed": 1, "violated": 1, "blocked": 1, "errored": 1 } ], "recentBlocked": [ { "runId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "at": "2026-04-15T12:00:00Z", "agentId": "example", "agentVersion": "example" } ], "recordedSince": "2026-04-15T12:00:00Z"}A missing or malformed projectId, from, to or recent; a window over 90 days.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}Missing / malformed / expired / revoked bearer token.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}guardrail-outcomes-not-supported: this deployment doesn’t record guardrail outcomes.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}The database was too busy to answer in time (database-busy); Retry-After (whole seconds) says when to try again.
object
object
Stable machine-readable discriminant. Values match domain error codes (see docs/API-ROUTE-CONVENTIONS.md §4.3).
Optional, kind-specific.
object
Server-assigned request id; also echoed via X-Request-Id header.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": {}, "requestId": "example" }}