API

Sessions

Mint a session, read the verdicts recorded against it, close it when the run finishes, and keep it out of learning.

A session is one agent run: the sequence of calls made while working on a single task. Verdicts, the timeline, and forensic evidence are all organised by session, so it is the id you search on when something needs explaining after the fact.

Most integrations never call these endpoints. Sending chat traffic is enough β€” Sentisec opens and stitches sessions on its own (how). Mint one explicitly when you want to attach a task description up front, or hand a short-lived key to a subprocess.

Mint a session

POST/ws/{workspace_id}/v1/sessionsWorkspace key
Open a session β€” returns its id, base URL, and a session key
curl -X POST https://api.sentisec.ch/ws/$SENTISEC_WORKSPACE_ID/v1/sessions \
  -H "Authorization: Bearer $SENTISEC_API_KEY" -H "content-type: application/json" \
  -d '{"customer_id":"acme","model":"claude-sonnet-4","task":"Triage the inbound support queue","policy":"default","response_policy":"default"}'
{"session_id":"ses_…","proxy_base_url":"https://api.sentisec.ch","api_key":"sk_sentisec_…"}

The task string is worth writing well. It is what the operator sees first in the session list, and it is the stated intent that everything the agent subsequently does is judged against.

Optional fields let you tag the run for later filtering: agent_kind, integration, and upstream_provider. Omit them and Sentisec infers what it can from the request.

Read the verdicts

GET/ws/{workspace_id}/v1/sessions/{session_id}/verdictsWorkspace key
Every verdict recorded for this session, in order
{"session_id":"ses_…","verdicts":[{"session_id":"ses_…","step_idx":7,"verdict":"HIJACK","intervention":"HALT","explanation":"…one line, plain language…","forensic_id":"","timestamp":"2026-08-03T14:25:13+00:00"}]}

verdict is one of NOMINAL, ELEVATED, SUSPICIOUS, HIJACK β€” how far the run has moved from its stated task. intervention is what was done about it: PROCEED, SANITIZE, HALT, or ABORT. In shadow mode the verdict is recorded truthfully but the intervention is not applied, so this endpoint is how you see what enforcing would have done.

forensic_id can be empty: the signed evidence record covers the whole session and is sealed when it closes (see evidence after close). Each entry carries further diagnostic fields used by the dashboard; they are described in the full API reference. What the dashboard shows for each step is in Verdicts.

Always call the workspace-scoped form. It checks that the session belongs to the workspace in the path and returns 404 if it does not, so a foreign session id is never confirmed as real.

Treat session ids as sensitive: they are the key to a run's recorded detail, so keep them out of URLs you share, client-side logs, and support tickets.

Close a session

POST/v1/sessions/{session_id}/closeWorkspace key
Mark the run finished β€” idempotent

Closing marks the run complete so the dashboard stops showing it as live. It is idempotent: closing an already-closed session returns 200, and an unknown session returns 404. Idle sessions can be closed automatically. For a workflow you manage, close the session explicitly when it finishes and use a new id for the next run.

The response includes a forensic_bundle_url field. Retrieve evidence through the dashboard's forensics view rather than from that value.

Evidence after close

From 0.8: With evidence recording healthy and the session close received, every closed session yields a sealed record or a visible failure, never a silent drop.

Closing is not a synchronous evidence-download operation. Check the dashboard for the sealed record or its recording status. A pending or unavailable read is not proof of an empty record. Activity added after a session has been sealed does not extend that sealed record; start a new session for a new run. See evidence durability.

Exclude sessions from learning

When you propose a contract, Sentisec learns from the sessions your workspace recorded. To keep a run out of that, such as a test you ran by hand, an incident, or traffic that does not represent normal work, exclude it. The session stays recorded and visible; only learning skips it. In the dashboard, an admin uses Exclude from learning on the session's row or page; these endpoints do the same from a script.

POST/v1/workspaces/{workspace_id}/contract/cohorts/exclusions
Exclude sessions from learning β€” admin only
POST/v1/workspaces/{workspace_id}/contract/cohorts/exclusions/undo
Include them in learning again β€” admin only
GET/v1/workspaces/{workspace_id}/contract/cohorts/exclusions
The current exclusions, newest first

These endpoints take the session token from Sentisec sign-in, like the administration endpoints, not a workspace API key. Excluding and including again need a workspace admin; any member can read the list.

curl -X POST https://api.sentisec.ch/v1/workspaces/$SENTISEC_WORKSPACE_ID/contract/cohorts/exclusions \
  -H "Authorization: Bearer $SENTISEC_ADMIN_TOKEN" -H "content-type: application/json" \
  -d '{"session_ids":["3f6c1a52-8d0e-4b1f-9a47-2c5e7d9b0a13"],"reason":"Manual load test, not normal work"}'
{"changed":["3f6c1a52-8d0e-4b1f-9a47-2c5e7d9b0a13"],"exclusions":[{"session_id":"3f6c1a52-8d0e-4b1f-9a47-2c5e7d9b0a13","reason":"Manual load test, not normal work","excluded_by":"user_…","excluded_at":"2026-10-15T09:12:44+00:00"}],"count":1}
  • session_ids are Sentisec's session ids, the UUID shown on a session's page, not the x-session-id value your client sent. One call names up to 500.
  • reason is required to exclude, up to 2,000 characters. The undo takes the same body, and its reason is optional.
  • Both calls answer with the sessions whose state changed and the current list. A call that changes nothing records nothing.
  • Each change is one entry in the workspace's audit log: who, when, which sessions and why.

Every later proposal skips the current exclusions and lists each skipped session with its reason under excluded_by_administrator. After an undo, the next proposal reads the session again. An excluded session is not held back to test a proposed contract either, from the next proposal on; a test set made before you excluded it keeps it until you propose again. After an undo it can be held back again.

ResponseMeaning
403 workspace_admin_requiredOnly a workspace admin can exclude or include again.
404 session_not_foundAn id is not a session of this workspace; detail.session_ids lists them and nothing changed.
422 invalid_session_idAn id is not a session UUID.
422 exclusion_reason_requiredExcluding needs a reason.

Finding sessions and requests

From 0.8, the dashboard's filters use the same labels as their tables:

  • Sessions β†’ quick filters: All, Flagged, Would ask, Would block and Blocked; Held for approval, Approved and Blocked, agent recovered join them when the window holds such a session. These describe the session finding, not only its last step's verdict; what each means is in session findings. Fine and Not checked sessions are listed under All; a recovered session is not listed under Blocked. Two more chips select sessions that Moved money or Contacted someone. More filters narrows by agent, status, source and session id; Status and Source each accept one selection.
  • Requests β†’ Band: Nominal, Elevated, Suspicious, or Hijack. Model and Provider list recorded ids for selection rather than requiring an exact id typed from memory. No verdict rows remain visible but cannot be selected by the Band filter.

Counts are shown only where the available data supports that count. Use the time window with these filters; an empty window does not mean the workspace has no earlier sessions.

Protected docs