For the complete documentation index, see llms.txt. This page is also available as Markdown.

Approval-Gated Integration Writes

Require human approval before an agent performs an integration write. Approved writes resume on the agent's next turn across streaming chat, REST, and SMS.

Approval gating puts a human in the loop before an agent calls a write endpoint on one of your integrations. When a gated tool is invoked, the agent parks the call instead of executing it. An operator approves or rejects it, and the agent performs (or declines) that same write on its next turn - on streaming chat, REST, and SMS alike.

This guide covers the approval lifecycle and how to decide what to gate. For the approval_policy field and integration approval request/response schemas, use the Integrations API reference. Approval decisions require review-queue permission, but the decision endpoints are conversation-scoped integration endpoints.

Approval gates the integration call, not the underlying decision. Approving a refill write means "send the refill request to the pharmacy queue," not "this refill is clinically approved." Word agent and reviewer copy accordingly.

Key Concepts

  • Parked write: when the agent calls a gated endpoint, the exact tool name and parameters are stored and the agent receives an awaiting_approval result. Nothing reaches the external system yet.

  • Durable decision: the operator's approve/reject is recorded durably and scoped to the authenticated workspace, so it survives across turns and transports and stays tenant-isolated.

  • Exactly-once resume: the agent consumes the decision once, on its next turn, and either performs the parked write synchronously or declines it.

  • One pending write per conversation: a second gated write while one is already parked is refused with approval_pending_elsewhere rather than overwriting the first.

Approval gating applies to text and SMS conversations. Voice approval behavior is intentionally not implied by the public REST integrations surface.

Lifecycle

The decision is durable and consumed exactly once, so the resume is reliable on REST and SMS - transports that do not drain a streaming session's event stream. Server-sent events still fire as an immediate-resume nudge for streaming clients, but they are a UI signal, not the source of truth.

If the parked write has expired by the time the decision is consumed, the agent reports that the action did not complete rather than falsely confirming success.

Approval Policies

Approval is configured per integration with approval_policy. The default is none, so existing integrations are unaffected until you opt in.

approval_policy

Effect

Use it for

none (default)

No approval required.

Safe reads and low-risk writes.

writes

POST, PUT, PATCH, DELETE require approval; GET runs normally.

Typical EHR and scheduling integrations.

all

Every endpoint requires approval, including reads.

Sensitive systems where even reads should be reviewed.

Set it on create or update of the integration. Treat a missing value on older integrations as none. See Integrations → Approval Policies.

Operator Decisions

Parked writes should be shown to operators with the identity, payload, and evidence needed to decide. The approval decision itself is conversation-scoped: the operator approves or rejects the pending write for the conversation, and the agent consumes that decision on its next turn.

Approve the parked write:

Approve a pending integration-write approval

post

Approve a pending human-in-the-loop integration-write approval for a conversation. Publishes integration.approval_granted to the workspace event channel; the subscribed text session fires the gated write. Requires ReviewQueue.review permission.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
conversation_idstring · uuidRequired
Responses
200

Successful Response

application/json

Resolution outcome for a pending integration-write approval.

statusstring · enumRequiredPossible values:
conversation_idstring · min: 1 · max: 256Required
post/v1/{workspace_id}/integrations/approvals/{conversation_id}/approve

Reject the parked write. The reason is surfaced to the agent when provided:

Reject a pending integration-write approval

post

Reject a pending human-in-the-loop integration-write approval for a conversation. Publishes integration.approval_rejected to the workspace event channel; the subscribed text session declines the gated write. Requires ReviewQueue.review permission.

Authorizations
AuthorizationstringRequired

API key issued via POST /v1/{workspace_id}/api-keys. Pass the returned api_key value as a Bearer token.

Path parameters
workspace_idstring · uuidRequired
conversation_idstring · uuidRequired
Body

Reject body — optional free-text reason surfaced to the agent.

reasonstring · max: 2000 · nullableOptional
Responses
200

Successful Response

application/json

Resolution outcome for a pending integration-write approval.

statusstring · enumRequiredPossible values:
conversation_idstring · min: 1 · max: 256Required
post/v1/{workspace_id}/integrations/approvals/{conversation_id}/reject

These endpoints require ReviewQueue.review permission. conversation_id is the durable text conversation ID: a UUID for web conversations and the SMS routing key for SMS conversations. UUID-form conversation IDs are verified against the authenticated workspace; durable approval decisions are also scoped to the authenticated workspace.

Deciding What to Gate

Require approval when a write is hard to reverse, touches a source of truth, carries PHI, or was assembled from inferred conversation data. Allow direct writes only for low-risk operations your policy has cleared.

Whatever the write, a parked item must carry enough context for the operator to decide:

  • Identity of the subject, and how confident the match is.

  • Target system and object the write lands on.

  • Payload preview - and for updates, the diff (old → new), not just the final value.

  • Source evidence - transcript or form data the write was derived from, with inferred fields marked.

  • Risk notes - same-day slot, controlled substance, third-party recipient, duplicate-record risk, and so on.

Common write categories

Category
Require approval when
Reviewer needs

Scheduling (book / cancel / reschedule)

Scarce or same-day slots, fee implications, two-write reschedules, or uncertain identity/intent.

Patient identity, requested service, provider/time, current vs. proposed appointment, payload preview.

Forms & intake

Clinical, legal, or billing fields, or any field inferred from the conversation.

Form name, completed answers, inferred fields marked, missing fields, submission payload.

Medication / refill

Always for medication writes unless policy clears low-risk queue creation; strongly for controlled substances or dosage changes.

Patient, medication, dosage, pharmacy, urgency/symptoms, target queue. Confirm request submitted, not refill approved.

EHR write-back

Clinical notes, problem lists, identity/insurance fields, or other source-of-truth updates.

Field, old value, new value, source evidence, payload diff.

Outbound messages

PHI-bearing content, sensitive topics, third-party recipients, or non-templated copy.

Recipient, channel, message body, PHI/sensitivity label, send reason.

Safety escalation

Any outreach or task write driven by a clinical, legal, or classifier signal.

Risk signal, classifier confidence, patient identity, response SLA, proposed alert/outreach. The classification is not the write - the alert is.

Record creation (add patient / chart / ticket)

Creating a source-of-truth identity, especially with duplicate risk or voice/OCR-derived fields.

Demographics, identity confidence, duplicate-search results, proposed payload; return the new record ID before downstream writes.

API Reference

Last updated

Was this helpful?