> For the complete documentation index, see [llms.txt](https://docs.amigo.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amigo.ai/developer-guide/platform-api/integrations/approval-gated-integration-writes.md).

# Approval-Gated Integration Writes

Approval gating puts a human in the loop before an agent calls a write endpoint on one of your [integrations](/developer-guide/platform-api/integrations.md). 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](https://docs.amigo.ai/api-reference/readme/platform/integrations). Approval decisions require review-queue permission, but the decision endpoints are conversation-scoped integration endpoints.

{% hint style="info" %}
**This is not the external write proposal queue.** An integration's `approval_policy` parks one Platform Integration call inside a supported conversation and resolves it through `/integrations/approvals/...`. It does not create an `ExternalWriteProposal`. External write proposals belong to a separate, private-preview connector write-back flow described in [Review Queue](/developer-guide/platform-api/integrations/review-queue.md).
{% endhint %}

{% hint style="info" %}
**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.
{% endhint %}

## 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.
* **Single-consumption resume**: the agent consumes one decision atomically so duplicate turn or event processing does not intentionally execute the parked write twice.
* **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.

{% hint style="info" %}
Approval gating applies to text and SMS conversations. Voice approval behavior is intentionally not implied by the public REST integrations surface.
{% endhint %}

## Lifecycle

```mermaid
%%{init: {"theme": "base", "themeVariables": {"actorBkg": "#083241", "actorTextColor": "#FFFFFF", "actorBorder": "#083241", "signalColor": "#575452", "signalTextColor": "#100F0F", "labelBoxBkgColor": "#F1EAE7", "labelBoxBorderColor": "#D7D2D0", "labelTextColor": "#100F0F", "loopTextColor": "#100F0F", "noteBkgColor": "#F1EAE7", "noteBorderColor": "#D7D2D0", "noteTextColor": "#100F0F", "activationBkgColor": "#E8E2EB", "activationBorderColor": "#083241", "altSectionBkgColor": "#F1EAE7", "altSectionColor": "#100F0F"}}}%%
sequenceDiagram
    participant U as User
    participant A as Agent
    participant O as Operator
    participant I as Integration
    U->>A: Message triggers a gated write
    A-->>U: Parks write, returns awaiting_approval
    O->>O: Reviews item (identity, payload, evidence)
    alt Approve
        O->>A: Records granted decision
        U->>A: Next turn (chat / REST / SMS)
        A->>I: Performs parked write synchronously
        I-->>A: Result
        A-->>U: Narrates actual result
    else Reject
        O->>A: Records rejected decision (+ reason)
        U->>A: Next turn (chat / REST / SMS)
        A-->>U: Declines, relays reason. No write.
    end
```

The decision is stored independently of a streaming connection and consumed once from the next supported turn, so REST and SMS do not depend on a live event stream. Server-sent events can provide an immediate-resume nudge for streaming clients, but they are a UI signal rather than the decision record.

After a grant is consumed, the integration write is attempted synchronously and is not automatically reconciled. A returned integration error is reported to the agent. If execution is interrupted after decision consumption, verify the destination before deciding whether a manual retry is safe.

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](/developer-guide/platform-api/integrations.md#approval-policies).

{% hint style="warning" %}
Approval-gated integration writes must be called as top-level integration tools today. They are not available inside companion skills; gated integration tools are excluded from skill tool sets until skill-internal approval is supported.
{% endhint %}

## 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:

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/integrations/approvals/{conversation\_id}/approve" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

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

{% openapi src="<https://api.platform.amigo.ai/v1/openapi.json>" path="/v1/{workspace\_id}/integrations/approvals/{conversation\_id}/reject" method="post" %}
<https://api.platform.amigo.ai/v1/openapi.json>
{% endopenapi %}

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.                |

{% hint style="warning" %}
Keep agent confirmations precise about what approval did. Report the **operational** result - "your refill request was submitted," "the alert was sent to the care team" - never a clinical conclusion the integration call did not make.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.amigo.ai/developer-guide/platform-api/integrations/approval-gated-integration-writes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
