Get started
Response codes
Guard uses conventional HTTP status codes. The Gateway adds two intentional guardrail status codes (246 and 446) you can branch on.
Guard — HTTP status codes
| Code | Meaning | When |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Malformed parameters (e.g. mixing last with from/to). |
| 401 | Unauthorized | Missing or invalid API key. |
| 404 | Not Found | Unknown resource or user. |
| 422 | Unprocessable Entity | Request body failed schema validation. |
| 429 | Too Many Requests | Rate limit exceeded. |
| 500 | Internal Server Error | Unexpected error evaluating detectors. |
| 503 | Service Unavailable | Data store temporarily unavailable (export routes). |
Guard is fail-open by design
On the Guard API a flagged or deny result is returned with HTTP 200. Inspect the JSON body (flagged, deny) to make an enforcement decision — do not rely on HTTP status to detect a violation on /v1/guard. Error responses share a consistent shape: { "detail": "..." }.
Gateway — guardrail status codes
The Gateway signals guardrail outcomes through the HTTP status code itself, so you can enforce on the status without parsing the body. These are intentional, non-standard codes — branch on them directly.
| Code | Meaning | Behaviour |
|---|---|---|
| 200 | Passed | All guardrail checks passed (or none configured). The provider response is returned as-is. |
| 246 | Flagged, not blocked | A guardrail check failed but the config did not deny, so the request proceeded. The provider response is returned with a hook_results object attached. Treated as success — use it to observe flagged-but-allowed traffic. |
| 446 | Blocked | A guardrail check failed and the config denied the request, so it was NOT sent to / returned from the provider. The body is { error: { type: "hooks_failed", ... }, hook_results: { ... } }. |
Both before-request and after-request guardrails can produce 246/446, and both work for streaming responses. Provider/LLM errors are passed through with the provider's own status code.
Branching on Gateway codes
const res = await client.chat.completions.create(...).catch((e) => e);
// The OpenAI SDK throws on non-2xx; inspect the status to enforce.
if (res.status === 446) {
// Guardrail blocked the request — read res.error.hook_results
} else if (res.status === 246) {
// Flagged but allowed — response is usable; res.hook_results has detail
}