> 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/channels/outbound.md).

# Outbound

Amigo has several outbound paths with different channel support and lifecycle semantics. They share workspace authorization and use-case configuration, but they are not one automatic channel-selection system.

| Path                              | Supported channel | Primary contract                                  |
| --------------------------------- | ----------------- | ------------------------------------------------- |
| **Conversation start and switch** | SMS and iMessage  | Durable Conversations API                         |
| **Direct outbound call**          | Voice             | Outbound Calls API                                |
| **Scheduled outbound task**       | Voice             | `outbound_task` world-model events and dispatcher |
| **Ringless voicemail**            | Voicemail drop    | Managed channel infrastructure                    |

Email sending uses the email channel API. The conversation-start endpoint does not currently start outbound email, WhatsApp, or voice conversations.

## Outbound SMS and iMessage

The Conversations API starts a durable outbound SMS or iMessage thread. The request identifies:

* the bound service
* `channel` as SMS or iMessage
* the recipient in E.164 format
* a workspace-owned use case that resolves the sender
* an optional instruction for the opening agent turn

The caller does not supply a sender address. The platform validates the use case, dispatches the first turn, and returns the durable conversation record. A recipient reply resolves through the same provider thread key and resumes that conversation while it remains non-terminal.

Set `force_new: true` when a new outbound SMS or iMessage opener must not reuse the active thread for the same recipient and use case. The platform closes the prior active conversation before dispatching the new opener.

{% hint style="info" %}
Request models, permissions, and failure responses are in the [Conversations API guide](https://docs.amigo.ai/developer-guide/platform-api/conversations).
{% endhint %}

### Switching Between SMS and iMessage

An active durable conversation can switch from SMS to iMessage or from iMessage to SMS. A switch request supplies the target channel, recipient, target use case, and a reason. It can also request an immediate opener on the new channel.

The conversation ID and existing history remain the same. Each new turn records its own channel attribution, so consumers should render the per-turn channel rather than applying the conversation's current channel to all history.

The channel change is persisted before the optional opener is dispatched. If opener delivery fails, the conversation remains switched and the caller can retry delivery without switching again. Voice, email, and WhatsApp are not supported switch targets.

## Direct Outbound Voice Calls

Use the Outbound Calls API for an immediate voice call. This path is separate from conversation creation and does not require an `outbound_task`.

A valid request requires:

* `phone_to` in E.164 format
* an outbound-voice `use_case_id`, which resolves caller ID
* either `patient_entity_id` or `patient_canonical_id`, but not both
* a reason for the call

Optional fields include the service, goal, system-prompt override, tags, metadata, callback lineage, an idempotency key, and an outbound-task entity ID. The workspace must already have valid outbound voice configuration; an API key alone is not sufficient.

The response returns the call identifier and initial telephony status. It can also return the resolved sender information and an `event_id`. The `outbound.initiated` world-model event is emitted best-effort, so `event_id` is nullable and must not be treated as proof that the call itself was or was not queued.

### Context and Lineage

The optional goal and system prompt steer the call. If a patient identifier is supplied, the runtime can load the authorized context available for that entity. Do not assume every clinical field is present or current; projection lag, source permissions, and missing upstream data still apply.

Use `derived_from_call_sid` to associate a callback with an earlier call. Tags and metadata support external correlation and analysis, subject to their request limits.

### Idempotent Retries

Provide a stable idempotency key when a client may retry after a timeout or transient failure. This reduces duplicate call creation, but downstream telephony and world-model event delivery remain separate lifecycles. Reconcile against the returned call ID and call status.

The Developer Console does not currently provide a general-purpose **Call now** action for this API. External applications and operator workflows invoke it programmatically.

{% hint style="info" %}
See the [Outbound Calls guide](https://docs.amigo.ai/developer-guide/platform-api/conversations/calls) for the endpoint contract and examples.
{% endhint %}

## Scheduled Outbound Voice Tasks

Scheduled outreach uses an `outbound_task` entity. A deterministic trigger action can write an `outbound.scheduled` event, and the dispatcher later selects due tasks from the projected serving state.

Supported task data includes:

* destination phone number
* reason and goal
* scheduled and next-attempt timestamps
* numeric priority from 1 through 10
* maximum attempts and retry backoff
* a business-hours window and timezone
* optional patient, service, source, and context references

Higher numeric priority is dispatched first. Tasks at the same priority are ordered by their scheduled time. A task still needs a service that resolves to an outbound-voice use case before a call can be placed.

```mermaid
flowchart LR
    A["outbound.scheduled event"] --> B["Asynchronous projection"]
    B --> C{"Due and in window?"}
    C -->|Yes| D["Resolve outbound voice use case"]
    D --> E["Place call"]
    E -->|Accepted| F["outbound.dispatched"]
    E -->|Retriable failure| G["outbound.failed with next attempt"]
    G --> C
    E -->|Attempts exhausted| H["outbound.failed"]
```

The projection is asynchronous. Writing `outbound.scheduled` does not mean the task is immediately visible to the dispatcher. Dispatch claims and deterministic event identifiers reduce duplicate attempts and duplicate lifecycle events, but integrations should not describe this path as exactly once.

### Task Lifecycle

| State          | Meaning                                                                                                                                 |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **Scheduled**  | Waiting for its due time and business-hours window                                                                                      |
| **Dispatched** | A call request was accepted for the current attempt                                                                                     |
| **Completed**  | Call completion feedback recorded a successful outcome                                                                                  |
| **Failed**     | Attempts are exhausted; a retriable failure records its outcome and projects the task back to scheduled with a future next-attempt time |

The world-model projection can also represent cancelled and snoozed events when a supported workflow emits them. Approval, dispatch, call completion, and external delivery remain distinct states.

## Triggering Scheduled Work

Cron, supported event, and authenticated external-trigger flows can invoke an action that creates an outbound voice task. Use a deterministic outbound-task action when the phone, timing, and routing inputs are already known. Use stable external identifiers and retry logic at the integration boundary when webhook delivery can repeat.

The platform does not automatically convert every promise spoken during a call into a task. Nor does it automatically choose voice versus text or fall back from an unanswered call to another channel. Those behaviors require an explicitly configured Context Graph, trigger, or external workflow.

General population campaigns also require an explicit source of eligibility, pacing, consent, and retry policy. Customer-specific automation should not be presented as a universal campaign engine.

## Ringless Voicemail

Ringless voicemail is managed channel infrastructure with its own use-case provisioning, send contract, and asynchronous status values. It is not a channel on the workspace Conversations API and is not a fallback automatically selected by the voice dispatcher.

{% content-ref url="/pages/IBtMk6VVdepPtV2GWSAq" %}
[Broken mention](broken://pages/IBtMk6VVdepPtV2GWSAq)
{% endcontent-ref %}

## Operational Guidance

* Configure and validate the channel use case before dispatch.
* Treat agent completion, provider acceptance, and recipient delivery as separate milestones.
* Use stable idempotency keys for retried direct calls and deterministic identifiers for scheduled work.
* Respect consent, opt-out, business-hours, and contact-preference policy in the workflow that selects recipients.
* Reconcile world-model projections asynchronously rather than assuming immediate timeline visibility.
* Monitor terminal failures and exhausted retries instead of relying on automatic cross-channel fallback.


---

# 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/channels/outbound.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.
