Skip to content

API reference

Base URL: https://api.inpolicy.ai/api/v1/agent Authentication: Authorization: Bearer inp_live_… on every request. Rate limit: 120 req/min per key by default; configurable per key.

All Agent Governance endpoints are mounted under /api/v1/agent. The tenant is resolved from the API key. You never pass a tenant id in a request body.

Status Meaning
400 Bad request (validation error). Response body has details.
401 Missing / invalid / revoked API key.
403 Key lacks required scope OR feature gate disabled on the key.
404 Resource not found (e.g. unknown sessionId on GET /conversation).
429 Rate limit exceeded. Retry after window_seconds.
5xx Upstream error. Retryable with exponential backoff.

POST /api/v1/agent/governance/conversation/turn

Section titled “POST /api/v1/agent/governance/conversation/turn”

The primary surface. Record one turn in a conversation and get the updated policy state.

Request

{
"sessionId": "sess_abc",
"turn": {
"role": "user",
"content": "I'm 16 — can I buy this?"
},
"recentContext": ["prior turn content"],
"priorHistory": null,
"endUserContext": {
"attributes": { "customer_tier": "basic", "region": "EU" }
},
"policyAreaIds": ["data-handling"],
"tokenBudget": 600,
"idempotencyKey": "turn-7a9c-...",
"checkOutput": false,
"ttlSeconds": null
}
Field Required Description
sessionId Stable caller-chosen conversation id.
turn.role user | assistant | tool. system is rejected.
turn.content The turn’s text content.
recentContext Last 2–3 prior turns for disambiguation. Not stored.
priorHistory Bootstrap history; only used on the first call per session.
endUserContext.attributes Opaque attributes for policy matching. Not stored.
policyAreaIds Scope retrieval to specific policy areas.
tokenBudget Approx tokens for injectionBlock. Default 600. Range [50, 4000].
idempotencyKey Replays within 5 min return the cached response.
checkOutput Only valid when turn.role === "assistant". Requires post_inference_checking: "allowed" on the key.
ttlSeconds Override conversation TTL. Range [300, 604800].

Response (200)

{
"sessionId": "sess_abc",
"turnIndex": 3,
"diff": {
"newlyApplicable": [ /* ApplicablePolicy[] */ ],
"newlyReleased": [],
"stillActive": [ /* ApplicablePolicy[] */ ],
"bindingEvents": [
{
"turnIndex": 3,
"policyId": "pol_123",
"event": "binding_started",
"ts": "2026-04-24T12:00:00Z"
}
]
},
"activePolicies": [ /* ApplicablePolicy[] */ ],
"injectionBlock": "## Applicable Company Policies\n- [Policy 4.2]...",
"tokenEstimate": 184,
"postInferenceCheck": null,
"traceId": null
}

ApplicablePolicy:

{
"id": "pol_123",
"title": "No customer PII in external AI tools",
"summary": "Mask customer emails, names, account IDs...",
"severity": 4,
"enforcement": "fix" | "warning" | "audit",
"citationRef": "Policy 4.2",
"tags": ["pii"]
}

Latency: p50 ~100 ms, p95 ~500 ms regardless of input size (pre-inference is bounded by top-K retrieval, not prompt length). See Latency expectations.


GET /api/v1/agent/governance/conversation/:sessionId

Section titled “GET /api/v1/agent/governance/conversation/:sessionId”

Read-only snapshot of conversation state. No mutation, no TTL reset.

Response (200)

{
"sessionId": "sess_abc",
"turnCount": 7,
"activePolicies": [ /* ApplicablePolicy[] */ ],
"injectionBlock": "...",
"bindingLog": [ /* BindingEvent[] */ ],
"updatedAt": "2026-04-24T12:00:00Z"
}

Returns 404 if the session has been evicted (past TTL) or never existed.


DELETE /api/v1/agent/governance/conversation/:sessionId

Section titled “DELETE /api/v1/agent/governance/conversation/:sessionId”

End a conversation and purge its Redis state. Idempotent. Returns 204.


POST /api/v1/agent/governance/check-tool-call

Section titled “POST /api/v1/agent/governance/check-tool-call”

Gate a proposed agent tool call against the session’s active policies. Requires tool_call_governance: "allowed" on the API key; returns 403 otherwise.

Request

{
"sessionId": "sess_abc",
"toolName": "send_email",
"arguments": { "to": "competitor@acme.com", "subject": "Q3 roadmap" },
"intent": "proposed"
}

Response (200)

{
"allow": false,
"riskScore": 0.91,
"violations": [
{
"policyId": "pol_conf_01",
"matchedText": "competitor@acme.com",
"explanation": "Recipient domain matches listed competitor.",
"severity": 4,
"confidence": 0.95,
"enforcementType": "fix"
}
],
"suggestedArguments": null,
"traceId": null
}

allow: false happens when at least one violation has enforcementType: "fix" AND confidence ≥ 0.7. Any other violation (warning, audit, or low-confidence) returns allow: true with the violations surfaced for audit.


POST /api/v1/agent/governance/pre-inference

Section titled “POST /api/v1/agent/governance/pre-inference”

Legacy single-shot surface. Returns applicable policies + injection block for one prompt.

Prefer POST /conversation/turn for multi-turn agents. Same shape plus incremental diff.

Request

{
"sessionId": "sess_abc",
"prompt": "Draft a reply to our Acme account exec",
"recentMessages": [],
"context": { "surface": "email" },
"endUserContext": null,
"policyAreaIds": null,
"tokenBudget": 600,
"isUpdate": false
}

Response — same shape as conversation/turn minus the diff field.


POST /api/v1/agent/governance/post-inference

Section titled “POST /api/v1/agent/governance/post-inference”

Check a model output for policy violations. Requires post_inference_checking: "allowed" on the API key.

Request

{
"output": "Sure, here's the refund for John Smith (john@acme.com)...",
"sessionId": "sess_abc",
"prompt": "Draft a refund email",
"surface": "email",
"policyAreaIds": null,
"traceId": "trc_from_pre_inference"
}

Response (200)

{
"safe": false,
"riskScore": 0.72,
"violations": [
{
"policyId": "pol_pii_01",
"matchedText": "john@acme.com",
"explanation": "Contains unredacted customer email address.",
"severity": 4,
"confidence": 0.88,
"enforcementType": "fix",
"enforcementText": "[REDACTED]"
}
],
"suggestedRedaction": "Sure, here's the refund for John Smith ([REDACTED])...",
"policyCitations": ["pol_pii_01"],
"traceId": "trc_..."
}

POST /api/v1/agent/governance/check-output/stream

Section titled “POST /api/v1/agent/governance/check-output/stream”

Incremental check on accumulated output as the LLM streams. Requires post_inference_checking: "allowed" on the API key. Caller posts repeatedly with the full text so far; the server detects on the new portion plus a small overlap. See Streaming output checks for the full walkthrough.

Request

{
"sessionId": "sess_abc",
"fullText": "Sure, here is the refund for John Smith (john@acme.com)",
"lastCheckedOffset": 0,
"isFinal": false
}

Response (200)

{
"sessionId": "sess_abc",
"newViolations": [
{
"policyId": "policy_pii",
"matchedText": "John Smith (john@acme.com)",
"explanation": "Customer name and email...",
"severity": 4.5,
"confidence": 0.92,
"enforcementType": "fix",
"enforcementText": "[REDACTED]",
"offset": 28
}
],
"watermark": 56,
"isComplete": false,
"riskScore": 0.92,
"traceId": "trc_…"
}

Pass watermark back as lastCheckedOffset on the next call. Set isFinal: true on the last chunk to force detection on any tail content below the chunk threshold.


POST /api/v1/agent/governance/check-output/finalize

Section titled “POST /api/v1/agent/governance/check-output/finalize”

End-of-stream verdict for the full output — same response shape as POST /post-inference. Requires post_inference_checking: "allowed" on the API key.

Request — same shape as check-output/stream, with isFinal: true.

Response (200) — same shape as POST /post-inference above (safe, riskScore, violations, suggestedRedaction, policyCitations, traceId).


Every key has a set of scopes. The defaults are enough for the full API.

Scope Grants
governance:read record_turn, pre-inference, conversation state GET/DELETE
governance:check check_output, check_tool_call, post-inference
policies:read future: listing policies
policies:ack future: recording policy acknowledgements
feedback:write future: submitting thumbs-up/down feedback

Set via the InPolicy dashboard on the API key. Default: all off.

Setting Values Effect
post_inference_checking "disabled" | "allowed" Unlocks check_output + checkOutput: true on record_turn
tool_call_governance "disabled" | "allowed" Unlocks check-tool-call
conversation_ttl_seconds number | null Override default 4h TTL. Range [300, 604800].