API Explorer
The partner-facing subset of the Shield API, rendered from
openapi-partner.json. Import that file
directly into Postman, Insomnia, or a client generator.
For prose and integration patterns see the API Reference; this page is the contract.
The two flows
Everything else on this page configures or observes these two sequences.
Content path - wrap your model call. Screen what goes in, screen what comes back out.
sequenceDiagram
autonumber
participant App as Your app
participant Shield
participant Model
App->>Shield: POST /guardrails/input
Shield-->>App: passed, or blocked with a reason
Note over App: stop here if blocked -<br/>the model never sees it
App->>Model: prompt
Model-->>App: response
App->>Shield: POST /guardrails/output
Shield-->>App: passed, blocked, or redacted
Note over App: return to the user
Tool path - wrap each tool call. Ask before it runs, screen what it returns. An MCP gateway sits exactly here.
sequenceDiagram
autonumber
participant Agent
participant Shield
participant Tool
Agent->>Shield: POST /v1/shield/tool/check
Shield-->>Agent: allowed, or denied with a reason
Note over Agent: a denied call must not run -<br/>the decision is worthless<br/>if the caller proceeds anyway
Agent->>Tool: execute
Tool-->>Agent: result
Agent->>Shield: POST /v1/shield/tool/output
Shield-->>Agent: result, sanitised
The two are independent. Guarding the content path stops prompt injection and data leaving in text; guarding the tool path stops the action. Most integrations want both, and starting with one is fine.
Which integration is this?
Shield supports two shapes, and this page documents the first. Committing to one matters, because the setup and the calls differ.
Embed (this page). Your gateway calls Shield over HTTP around each
tools/call. You keep the enforcement point, the traffic path and the data
inside your own infrastructure. This is the shape to build against.
Hosted gateway. Your clients point at a Shield gateway route and we sit in the traffic path. Different setup entirely - upstream registration, identity headers - and not described here.
If you find a third surface in older guides (/v1/shield/mcp/check), it
predates this spec. Build against what is on this page.
Your first integration
- Create a runtime key -
POST /v1/tenant/me/api-keys. Runtime scope is enough for the guard calls and cannot change configuration, so it is the key to put on the hot path. - Register the agent -
POST /v1/agents/registry, then set the role-to-tool policy withPUT /v1/agents/tools/policies. Do this before the firsttool/check: an unregistered agent is denied by RBAC, which looks like a broken API and is actually unfinished setup. - Call
/guardrails/inputwith a prompt you expect to fail. Confirm you get a block before you trust a pass. - Wrap the model - add
/guardrails/outputon the way back. - Wrap the tools -
tool/checkbefore execution,tool/outputafter. - Tune -
GET /v1/tenant/me/policiesto see what ran,PUTto change it,GET /v1/tenant/me/telemetryto see the decisions.
Step 3 is the one people skip. A guardrail that has never refused anything in your integration is indistinguishable from one that is not wired up.
Reading the verdict
HTTP 200 does not mean allowed. A blocked request also returns 200 - the status code tells you the call succeeded, not what it decided. Branch on the body:
| Endpoint | Verdict field | Also returns |
|---|---|---|
/guardrails/input, /guardrails/output |
safe (boolean) |
action, guardrail_results |
/v1/shield/tool/check, /tool/output |
allowed (boolean) |
action, guardrail_results |
action is one of pass, warn, redact, block. The two families use
different field names today; a client should read the one belonging to the
endpoint it called rather than assume both are present.
A missing or unrecognised API key returns 401, not a verdict.
What is in it
| Guard the content path | POST /guardrails/input before the model, POST /guardrails/output after it |
| Guard the tool path | POST /v1/shield/tool/check before a tool runs, POST /v1/shield/tool/output on the way back. An MCP gateway calls these. |
| Configure | PUT /v1/tenant/me/policies, plus the custom-policy routes |
| Credentials | /v1/tenant/me/api-keys - create, label, expire, rotate |
| Observe | usage, telemetry, audit, guardrail metrics |
Authentication is a tenant API key in X-API-Key. The tenant is derived from
the key, never from the request, so a key can only read and write its own
configuration. Keys carry a scope: runtime may call the guard endpoints,
admin may additionally change configuration. Issue runtime keys to anything on
the hot path.
Administrative routes, tenant provisioning, and anything taking a tenant id in the path are deliberately absent. They exist, and they are not part of the partner contract.
Regenerating
The spec is generated, not hand-written, so it cannot drift from the running service:
python scripts/build_partner_openapi.py --url https://api.guardrails.votal.ai/openapi.json
The script filters by an allow list. A deny list would fail open - a route added next month would be public until somebody remembered to exclude it. This fails closed, and exits non-zero if an allow-listed path has disappeared, so a rename breaks the build rather than silently shrinking what a partner can see.