Channels

Configure routed email and WhatsApp addresses, send messages, and explicitly route inbound threads to people or an automatic-reply agent.

Key Concepts

Channels is organized around a layered model that separates infrastructure setup from messaging logic. Each layer builds on the one below it, so understanding the hierarchy will help you configure channels that are reliable, auditable, and easy to extend.

Channel Types

A channel type represents a communication medium — for example, email and whatsapp. The platform is designed so additional transports can reuse the same address, routing, activity, automation, and conversation contracts.

Channel Configs

Email configs use one of three integration types. platform-domain is Ergon-owned and immediately ready; addresses become {namespace}-{local}@{PLATFORM_EMAIL_DOMAIN}. custom-domain verifies customer-owned DNS. connected-mailbox is coming soon and cannot be created. WhatsApp configs use the business-account integration to bind a Meta Business Account and business phone number. Provider secrets remain in Vault, while Channels exposes safe setup and operational details.

Channel Addresses

Addresses are the send and receive identities that live under a config. Each address has a direction — send, receive, or both — an address string (e.g. support@mail.example.com), and a status. You can create multiple addresses under a single config to separate concerns: one for transactional notifications, another for support, and so on.

Receive-capable addresses also carry an access list (ACL). The ACL — managed under /configs/{config_id}/addresses/{address_id}/acl — controls who is eligible to be selected as a route target. It does not deliver or route inbound traffic. Reading inbound activity is authorized by channels:activity:view on the channel.

Activity Log

Every message — inbound and outbound — is recorded in the activity log. Each entry captures the sender, recipients, subject, thread association, and delivery status. The activity log serves as a complete audit trail for all communication flowing through your channels, and supports filtering by direction, status, date range, and free-text search.

WhatsApp

Connect a WhatsApp Business Account by supplying its WABA ID, phone-number ID, E.164 business number, pinned Graph API version, and Vault references for the System User token, app secret, and webhook verify token. The setup page provides the callback URL; the channel becomes verified after Meta completes the webhook challenge.

The setup page discovers phone numbers from the WABA and shows each number's provider status, quality rating, and restrictions. An administrator with address-create access can choose Add phone number, select another Meta-verified number, and connect it under the same WABA config without entering credentials again. Numbers that are unverified or already connected cannot be selected. The page also lets authorized administrators synchronize approved utility templates and enable each template for specific numbers. Controls are hidden or disabled when your grants do not include the corresponding management capability; secrets themselves are never displayed.

Free-form text and media are available for 24 hours after the customer's latest message. Outside that window, the conversation composer requires an approved utility template that a channel administrator synchronized from Meta and enabled for the sender address. Delivery, read, and failure callbacks appear on the conversation and in the channel activity log.

WhatsApp send rules

The composer fails closed while send options cannot be loaded. WhatsApp sends at most one uploaded media attachment per message; send additional files as separate messages. A failed message offers retry only when the provider error is classified as retryable. A new WhatsApp conversation starts with an approved template, never free-form text.

Agents and human takeover

An inbound route may make an agent the first responder or the conversation owner and first responder. A human participant can take over from the conversation header and resume the configured agent later without deleting the route. Takeover applies to the active conversation episode, not globally to the customer, phone number, or route.

Sending Messages

Sending a message through Channels is an asynchronous process. You submit a send request via the API, and the platform queues the message, dispatches it to the underlying provider, and tracks delivery status — all without blocking your application.

API Flow

When you POST a message to the send endpoint, the platform validates that the sending address is active and belongs to a verified config, then accepts the message with a 202 Accepted response and a log_id for tracking. The message moves through queued → dispatched → delivered states, each of which is reflected in the activity log.

Required Fields

Every send request requires an address_id identifying the sending address, and a channel-specific config object. For email, the config must include to (recipient list), subject, and html (the message body). Optional fields like reply_to, cc, and bcc are also supported.

Threading

Messages can be grouped into threads using a thread_id. When you reply to an inbound message or continue an ongoing conversation, include the thread identifier so the platform can maintain a chronological transcript. Thread messages can be retrieved via the thread endpoint for use in agent context, automation decisions, or compliance review.

Here is a minimal example of sending a message:

curl -X POST https://platform.ergondata.ai/api/v1/channels/send \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "email",
    "address_id": "a1d2e3f4-5566-7788-99aa-bbccddeeff00",
    "config": {
      "to": ["customer@example.com"],
      "subject": "Your order has shipped",
      "html": "<p>Tracking number: <b>1Z999AA10123456784</b></p>"
    }
  }'

The send endpoint returns a log_id you can use to look up the message's delivery status in the activity log at any time.

Inbound Routes

Every accepted inbound email is recorded and publishes channels.email.received with a snapshot of its routes. A route names a target principal, a mode, route and address status, an optional reply address, and policy.

Notify Routes

Address managers create user or team notify routes with channels:addresses:manage. Active notify routes determine the human participants added to a new conversation. Targets must already hold channels:addresses:receive on that address.

Agent Auto-Reply and Dual Control

Agent managers create and configure auto-reply routes from the agent's Channels settings with agents:agents:channels:manage. Only one active auto-reply may exist per address. The agent controls status (active or paused); the address manager independently controls address_status (allowed or blocked).

Both controls must allow a reply

The route invokes only when status is active and address_status is allowed. Address managers may block or allow the route, but cannot create, reconfigure, pause, or delete it. The reply cap is 1–100 per thread and defaults to 10.

One Conversation per Thread

Conversations stores a durable conversation_channel_threads binding. The same company, channel, address, and external thread always resolves to exactly one conversation, even when events are retried. Notify routes supply the human participants; the effective auto-reply route supplies the agent and reply address.

Cross-Service Grants

By default, only the owning organization can send from a channel address. Access grants extend this capability to other principals — for example, allowing a Workflow to send order confirmation emails, or giving an Agent the ability to reply through a shared support address.

Granting Access

Sharing uses the platform's unified access model. The config owner creates an access grant naming the principal and the permission it should hold — at the config level via /configs/{config_id}/access/grants, or scoped to a single address via its .../addresses/{address_id}/grants and ACL. A principal that wants access can also raise a connection request under /configs/{config_id}/access/connection-requests, which the owner approves or rejects. Send grants authorize outbound use; receive grants authorize route-target eligibility. Activity reads (including inbound payloads) require channels:activity:view.

Common Use Cases

  • Workflows — Grant a workflow the ability to send automated notifications (e.g. order confirmations, status updates) from a designated address whenever a phase transition occurs.
  • Agent Hub — Grant an agent access to a channel address so it can send messages as a tool action during conversations, enabling use cases like automated follow-ups or outbound outreach.

Discovering Granted Addresses

Consuming services can call the granted addresses endpoint to discover which addresses are available to them for a given service and resource scope. This is especially useful when building UI pickers — for example, letting a user select a “from” address when configuring a workflow email step.

curl "https://platform.ergondata.ai/api/v1/channels/addresses/granted?service=workflows&resource_id={workflow_id}&sendable=true" \
  -H "Authorization: Bearer {token}"

For a deeper look at the permissions model behind cross-service grants, see the Permissions guide.

API Reference

For a complete list of endpoints, request and response schemas, and parameter details, see the Channels API Reference.