> For the complete documentation index, see [llms.txt](https://docs.concurrence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.concurrence.com/channels/outbound.md).

# Outbound

Outbound paths for SMS and iMessage conversations and for direct voice calls, with the channel support, lifecycle, and retry rules of each.

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

Email sending uses the email channel API. The conversation-start endpoint does not 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.concurrence.com/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 a voice call. This path is separate from conversation creation.

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 goal, system-prompt override, start-time `context`, tags, metadata, callback lineage, an idempotency key, and an outbound-task entity ID. The service is resolved from the use case's service binding. 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

On the platform-managed runtime (`amigo`), the optional goal and system prompt steer the call, and an outbound-task entity ID can give the greeting its task context. When the service runs on `gpt_realtime`, a request that carries a goal, a system prompt, or an outbound-task entity ID returns `422` and nothing is dialed, so place the call without them or run the service on `amigo`. See [Startup Instructions and Patient Identity](https://docs.concurrence.com/developer-guide/platform-api/conversations/calls#startup-instructions-and-patient-identity).

The required patient identifier is validated and anchors best-effort lineage, but it is not passed to the call as patient context; any caller lookup depends on the service's own identity-resolution path.

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. The key is claimed before anything is dialed: a retry after the call was placed returns the original response, a retry while it is still being placed returns `409`, and an attempt that placed nothing releases the key so a retry can place the call. Deduplication is best-effort. Telephony status and world-model event delivery remain separate lifecycles. Reconcile against the returned call ID in Runs.

The Developer Console does not 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.concurrence.com/developer-guide/platform-api/conversations/calls) for the endpoint contract and examples.
{% endhint %}

## Triggering Scheduled Work

Cron, supported event, and authenticated external-trigger flows can invoke a trigger action. To place calls on a schedule, have the scheduling workflow call the Outbound Calls API and apply its own timing, attempt, and business-hours rules. Use stable external identifiers and retry logic at the integration boundary when webhook delivery can repeat.

The platform does not automatically turn a promise spoken during a call into a follow-up call. 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 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.

## Voicemail <a href="#ringless-voicemail" id="ringless-voicemail"></a>

A voicemail that picks up an outbound call counts as an answer, so the call-opening notice and the greeting play to it. Keep the greeting fit to leave on a voicemail, and check it with the configured outbound call workflow before outreach.

## 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.
* 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.concurrence.com/channels/outbound.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
