Skip to content

Core concepts

If you’re deploying for employees via MCP, you can skip this page and go straight to Claude Desktop setup. This page is for developers building integrations.

A session is one conversation. It has an opaque, caller-chosen sessionId (a UUID, a ticket number, a chat-room id, whatever is stable for the lifetime of the conversation). InPolicy uses it to key its conversation state cache. Two conversations with the same sessionId are considered the same one.

Sessions expire after 4 hours of inactivity by default, with a hard 7-day cap. Configurable per API key.

A turn is one message in a conversation. Each turn has a role and content:

RoleWhat it isDoes it trigger policy retrieval?
userInbound human messageYes — new user content can activate new policies.
toolA function / tool call result coming back to the modelYes — tool returns can contain new facts.
assistantThe agent’s own outputNo — recorded but doesn’t re-run retrieval.

You record every turn as it happens. The response tells you what the current policy state is, and what changed this turn.

At any moment, a session has a set of active policies: the policies InPolicy considers applicable given everything that’s been said so far.

Each active policy carries:

  • id, title, summary, severity (1–5), citationRef
  • enforcement, one of fix / warning / audit

enforcement tells the agent how seriously to treat the policy:

  • fix: must enforce. If you’re generating text that violates, rewrite it. If you’re about to call a tool that would violate, don’t.
  • warning: caution and surface to the user. Allowed but flagged.
  • audit: aware-only. The agent doesn’t need to block anything; we’re just noting the policy is relevant.

When the active set changes between turns, InPolicy emits binding events:

  • binding_started: a policy just became active this turn.
  • binding_released: a policy dropped out of the active set this turn.

These show up in the diff.bindingEvents field on every recordTurn response and in bindingLog on the state endpoint. They’re the audit trail a customer-service platform or compliance tool would surface in a timeline.

Binding events ride in API responses only. InPolicy does not persist them server-side. If you want a durable audit trail, capture them and write them to your own store.

On every recordTurn response, the injectionBlock field is a pre-formatted markdown snippet listing the currently active policies. Drop it verbatim into the agent’s system prompt before generating. Shape:

## Applicable Company Policies
Follow these policies when responding:
- [Policy 4.2] (WARN, severity 4.0): Mask customer emails, names, account IDs...
- [Policy 7.1] (MUST FIX, severity 5.0): Do not discuss competitor pricing.

The MUST FIX / WARN / AUDIT prefixes match the policy’s enforcement. Models trained on instruction-following reliably respect these markers when they appear in the system prompt.

Default token budget is ~600 tokens; configurable per call.

Two governance capabilities are opt-in, gated per API key by settings on the key itself (configured in the InPolicy dashboard):

  • post_inference_checking: enables checkOutput on recordTurn and the standalone /post-inference endpoint. Default off.
  • tool_call_governance: enables the /check-tool-call endpoint. Default off.

Pre-inference (recordTurn without checkOutput) is always on. It’s the primary fast path.

ThingWhereHow long
Conversation state (policy IDs, turn count, binding log)Redis (in-memory)4h sliding, 7d hard cap
Policy retrieval cacheRedis24h
Turn content / user messagesNever stored
Binding events / violationsAPI response onlyCaller’s responsibility

See Privacy & data handling for the full picture.