Understanding the output
Every governed call returns more than the model’s text. This page annotates real response shapes so you know what you’re looking at — in the SDK, in the raw API, and in the dashboard.
An allowed call (SDK)
Section titled “An allowed call (SDK)”response = agent.chat("Summarize Q4 revenue")response.content # the assistant's answerresponse.pipeline.blocked # Falseresponse.pipeline.classification # "INTERNAL" — data classification of the callresponse.pipeline.steps_run # how many checkpoints ranresponse.pipeline.total_duration_msresponse.usage.total_tokens # 157response.session_id # "ses_…" ─┐response.task_id # "tsk_…" │ five correlation IDs —response.agent_uuid # │ every one is queryableresponse.pipeline_uuid # │ in the audit APIresponse.audit_url # dashboard deep-link to this exact callThe five correlation IDs are the important part. Any question — why was this allowed? what did it cost? what else happened in this session? — starts from one of these.
An allowed call (raw API)
Section titled “An allowed call (raw API)”Same call through the gateway:
{ "choices": [{"message": {"role": "assistant", "content": "…"}}], "usage": {"prompt_tokens": 12, "completion_tokens": 145, "total_tokens": 157}, "tappass": { "session_id": "ses_abc123", "task_id": "tsk_…", "audit_url": "https://app.tappass.ai/audit/…", "blocked": false }}The tappass envelope is added to the standard provider response. The gateway always returns HTTP 200 — governance outcomes are data, not HTTP errors.
A blocked call
Section titled “A blocked call”from tappass import PolicyBlockError
try: agent.chat("List all customer credit card numbers")except PolicyBlockError as e: e.blocked_by # the rule/step that decided, e.g. a BlockPII rule e.reason # machine-readable reason, e.g. "pii_in_input" e.classification # "RESTRICTED" e.audit_url # the blocked attempt is in the audit trail tooThrough the raw API, a block arrives as an assistant message explaining the block, with tappass.blocked: true. Your agent reads it like any other refusal — it never crashes on governance.
Three things to internalize:
- Blocked attempts are audited. The trail records what was tried, what fired, and the full evidence — that’s your incident queue.
- The reason names a rule.
e.blocked_bydeep-links to the exact rule and policy version. If the block is wrong, the fix is a policy change — not a code change. - Don’t retry blindly. Retrying an identical request under an unchanged policy yields the same decision — retrying blindly won’t get a different answer.
A redacted call
Section titled “A redacted call”Policy can allow a call while changing it — the redact obligation masks PII/secrets in place:
response = agent.chat("Email a summary to jane@acme.com")response.content # clean answer; the call went throughBy default, redaction is invisible: the call succeeds with clean content. Set Agent(raise_on_redaction=True) to surface it as a RedactionApplied exception carrying the exact spans (redactions: list[Redaction], redacted_content).
An approval pause
Section titled “An approval pause”A RequireApproval rule doesn’t block — it suspends:
from tappass import ApprovalRequired
try: agent.chat("Wire €50,000 to supplier 881")except ApprovalRequired as e: e.approval_url # dashboard deep-link for the human
```pythonresult = agent.wait_approval(e.request_id, timeout_seconds=300)result["state"] # "approved" | "denied" | "timed_out" | "cancelled"One approval authorizes exactly the fingerprinted action. Resubmitting the identical call passes; a different amount starts a new approval.
In the dashboard
Section titled “In the dashboard”| What you got | Where to look |
|---|---|
audit_url |
Opens the exact event in Audit Trail |
session_id |
Sessions → full trace with spans and applied rules |
blocked_by / rule id |
Policies → the owning policy and version |
| Approval request | Bell icon → Approvals inbox |
| Anything odd | Command Center → “Recent flagged events” |
Next steps
Section titled “Next steps”- Concepts — the model behind these shapes
- Agent client reference — full field and exception reference
- Dashboard tour — find everything in the UI