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

# Email

Email channel with domain verification, inbound reply handling, thread continuity, and transactional and marketing use cases.

The platform supports email as a communication channel alongside voice and text. Concurrence provisions email use cases on a verified sending domain. Messages are sent through the Channel Manager email API, and inbound replies thread back into the original conversation.

## Sending Domain Setup

Before an email use case can send or receive messages, the workspace must have a verified sending domain. Each setup binds a logical tenant name to a domain identity, creating an isolation boundary for reputation and suppression management. Each email domain setup is its own boundary for reputation and suppression, and a deployment can have more than one.

Sending-domain setup is provisioned by the Concurrence team - it is not self-serve. The team registers the domain identity, provides the DNS records to publish at your DNS provider, and confirms verification against live DNS. A single domain identity serves both outbound sending and inbound receiving. Sending and receiving are verified separately: the sending records must be verified before the domain can send or back any email use case, while the inbound MX record is needed only for use cases that receive email. To enable email for a workspace, contact the Concurrence team.

Each email setup includes:

* **Domain identity** - The domain used for sending (e.g., `notifications.example.com`)
* **DNS records** - Records that must be added to the domain's DNS configuration for verification: DKIM signing keys, SPF records, DMARC policies, and inbound MX routing
* **Verification status** - Two separate results: sending verification (DKIM, MAIL FROM, and DMARC) and inbound MX verification

## Use Cases and Sender Identities

Email on the platform is organized around use cases. A use case names one email sender identity - a sender address backed by a verified sending domain - owned by a workspace. Each use case specifies:

* **Sender email address** - The `From` address for messages sent through this use case
* **Email type** - Either `transactional` (triggered by user actions, like appointment confirmations) or `marketing` (bulk or promotional messages). The type determines sending rules and compliance handling.
* **Entity name and use case name** - Labels that identify the purpose of the use case for reporting and management

Each use case also records an explicit decision on two inbox posture settings:

* **Unsubscribable** - whether sends carry one-click unsubscribe headers and honor per-use-case opt-out lists. Marketing email must be unsubscribable. Transactional use cases may opt out for must-send flows such as password resets.
* **Inbound mode** (`inbound_mode`) - what inbound email the sender address accepts:

  * `send_only` - no inbound email is accepted, including replies to messages the use case sent. This mode does not need the inbound MX record, so it can be used before or without inbound DNS.
  * `replies_only` - only authenticated replies to the use case's own outbound messages are accepted; first-contact email is dropped.
  * `all_inbound` - replies and first-contact email to the sender address are accepted, after authentication and spam checks.

  Any mode other than `send_only` requires the setup's inbound MX record to be verified, both when the use case is created and when an existing `send_only` use case is changed to receive. Otherwise the request returns `409`.

Binding a use case to a service is the act that enables the email channel for the workspace. Once bound, inbound traffic for the use case resolves to the bound service, and outbound dispatch from the service routes through the use case. Rebinding replaces the current binding immediately. Unbinding turns the channel off.

Concurrence provisions email use cases. The Platform API binds, inspects, and unbinds a use case's service binding; see [Use Cases & Bindings](https://docs.concurrence.com/developer-guide/platform-api/workspaces/use-cases).

{% hint style="info" %}
Email sending, reads, and delivery events are available through the [Channel Manager API](https://docs.concurrence.com/developer-guide/platform-api/conversations/channel-manager#send-and-reconcile-email).
{% endhint %}

## Inbound Email

When a domain's MX records are verified and the use case's `inbound_mode` accepts it, the platform receives and processes inbound email. A `send_only` use case drops all inbound email. Inbound messages are resolved back to the original outbound email that prompted the reply, linking the patient's response to the correct conversation context.

Reply resolution matches the inbound `In-Reply-To` header to the parent outbound, and the reply's authenticated `From` address must match the address that outbound was sent to. When a match is found, the inbound email is associated with the same use case and workspace, giving downstream systems full thread context.

### Long-Running Tools and Reply Delivery

Some agent replies depend on a tool that takes longer than the synchronous turn window. Voice can provide a live acknowledgement. A web API client instead follows the REST contract: bounded `wait_for_final`, `background_pending`, and explicit polling when work remains.

Email is asynchronous, so its channel policy suppresses an intermediate acknowledgement and waits for supported background work before attempting the final reply. The recipient does not maintain a live text connection. Tool completion, message creation, provider acceptance, and recipient delivery are separate milestones.

The intended result is one useful reply rather than a filler followed by a correction. Tool failure, exhausted processing retries, suppression, bounce, or provider rejection can still prevent that outcome. Use channel status and delivery events to distinguish those cases.

SMS, iMessage, and WhatsApp use related non-live policies. Web conversations use request-scoped REST or SSE rather than a persistent text WebSocket.

### Attachment Handling

The inbound parser handles standard MIME attachments and the deeply nested layouts produced by some mail clients. Supported behavior includes:

* **Attachment parts are preserved.** Recognized attachment parts are extracted with their content and metadata rather than flattened into the message body.
* **Forwarded emails stay intact.** An email forwarded as an attachment is kept as a single `.eml` file, preventing attachments inside it from being attributed to the outer message.
* **Inline images retain CID identity.** Content-ID parts are stored under their CID identifiers so renderers can resolve references from the message body. Consumers should not assume every client hides those parts from attachment views.

## Reply Threading

Outbound emails can be sent as replies to inbound messages, maintaining thread continuity in the patient's email client. When sending a reply, the platform sets the `In-Reply-To` and `References` headers according to RFC 5322, so the patient sees a single threaded conversation rather than disconnected messages.

The platform maintains the full reference chain across multiple reply rounds. If a patient replies to an outbound, and the platform replies back, and the patient replies again, each message carries the complete thread history. Even when a patient's email client strips the `References` header (some lightweight mailers do this), the platform reconstructs the chain from its stored records so the next outbound reply still threads correctly.

Reply threading is scoped to the same use case and email setup. Cross-use-case replies are rejected to prevent confused-deputy scenarios where a reply intended for one context could be misattributed to another.

## Delivery Tracking

The platform records available provider lifecycle events for outbound email:

* **Delivery confirmation** - When the receiving mail server accepts the message
* **Bounce handling** - Hard bounces (invalid address) and soft bounces (temporary failure) are recorded and influence future sending decisions
* **Complaint tracking** - When a recipient marks a message as spam, the platform records the complaint and can suppress future sends to that address

## Unsubscribe Handling

Outbound emails include RFC 8058 one-click unsubscribe headers. When a patient clicks the unsubscribe button in their email client, the platform processes the opt-out automatically. Unsubscribe scope can be per-use-case (the patient stops receiving emails from one campaign but continues receiving others) or per-setup (the patient opts out of all email from that domain).

## Reliability and Operational Recovery

Inbound email turns are retried automatically. A turn that still fails is held in a durable record with its routing context rather than discarded, and Concurrence can re-submit it once the cause is resolved. Processing is best-effort; do not assume that every inbound message is processed.


---

# 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/email.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.
