The key idea
Unify the business workflow, message lifecycle and tool interface. Keep channel-specific identities, permissions and delivery constraints visible at the adapter boundary.
Your app might need to answer the same question on WhatsApp, iMessage and Telegram: “Where is my order?” Building three separate implementations of that workflow creates three places to maintain the lookup, authentication and error handling.
A unified messaging layer gives your application a common way to handle conversations. Channel adapters translate the transport; shared tools perform the business operation. Your customer can use a familiar chat interface while your team keeps one source of truth for what the app does.
What is a unified messaging API?
A unified messaging API provides a shared contract for messages across multiple channels. Depending on the product, that contract can include sending, receiving, conversation identities, delivery status and agent execution.
The useful abstraction is larger than a send function. A customer asks a question, the application identifies them, a tool reads the order and the result becomes a reply. That entire workflow needs a coherent record even when the transport differs.
For an AI agent, the shared layer also decides which tools are available and how their results reach the conversation. The transport should not determine whether a customer is allowed to cancel an order; your application should.
Share the workflow, keep the channel rules
A common API should preserve important differences instead of hiding them. Recipient identity, customer initiation and available message formats belong to the channel boundary.
| Layer | Share across channels | Keep channel-specific |
|---|---|---|
| Customer task | Order lookup, booking update, support request | Conversation entry point |
| Identity | Verified application account and permissions | Telegram chat ID, phone number or provider conversation ID |
| Agent tools | API or MCP operations and confirmation rules | Incoming event and attachment translation |
| Messages | Internal message ID and lifecycle | Provider status and formatting capabilities |
| Delivery | Queue, retries and duplicate protection | Messaging window, provider limits and transport errors |
WhatsApp’s Business Platform has a customer-service window and template rules, described in WhatsApp’s policy. Telegram’s Bots FAQ explains customer initiation for private bot conversations. For iMessage, clarify the specific integration route; Apple’s Messages framework is distinct from a third-party server API.
The WhatsApp agent, Telegram agent and iMessage API guides explain those boundaries in more detail.
Connect your app once
Expose business operations through an API or MCP server. Name them by their outcome: find an order, check availability, create a booking or update a delivery address. Return structured results so the agent can distinguish success, a missing record and a business constraint.
For an appointment workflow, a useful tool contract might be:
find_bookingreturns the customer’s eligible booking.list_available_slotsreads the current schedule.move_bookingaccepts the selected slot and returns the saved booking.
These names illustrate operations your backend could expose; they are not a prescribed Flow SDK. Your existing API may use different names or routes. What matters is that the operation has a narrow purpose and an explicit result.
Keep customer confirmation separate from a successful write. “I can move it to Friday” is a proposal. “It is now booked for Friday” requires a saved update. Reusing that distinction across channels gives customers the same dependable behavior wherever they message.
Flow starts with the app you want to bring into chat. Describe the workflow and supply the API or MCP connection, then configure the messaging channels around it. Start with your app.
Use Flow’s owner API for customer updates
Flow’s owner API uses the same message endpoint for existing customers on connected WhatsApp and Telegram channels. The recipient’s prefix identifies the channel. Use a scoped API key stored on your backend.
For a WhatsApp customer inside the allowed service window:
curl -X POST 'https://flow.engineer/api/v1/bots/42/messages' \
-H "Authorization: Bearer $FLOW_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1042-ready-whatsapp' \
-d '{
"to": "whatsapp:+14155550123",
"text": "Your order 1042 is ready for pickup."
}'
For a customer who has started your connected Telegram bot, the request shape stays the same:
{
"to": "telegram:123456789",
"text": "Your order 1042 is ready for pickup."
}
Replace the sample bot and recipient IDs with your own. These examples describe the current owner API’s WhatsApp and Telegram recipient formats. For an iMessage integration, use the contract provided for that connection; do not infer a recipient format from another channel’s example.
You can send exact text, or supply a prompt for the agent to compose the message using its instructions and tools. An accepted request returns 202 with a queued message. Follow the returned ID through GET /api/v1/bots/42/messages/{id} to distinguish queued, sending, sent and failed states.
Make retries and ordering part of the design
Networks fail after requests are accepted. Providers retry webhook events. A customer can send a correction while an earlier request is still running. Your messaging architecture should expect those situations.
Use stable event IDs for inbound deduplication and idempotency keys for outbound operations. Process messages in order within a conversation, while allowing different conversations to proceed independently. Keep a business transaction ID alongside the message ID so you can trace an update from the customer’s request to its stored result.
Flow’s owner API supports an Idempotency-Key header on writes. Reuse it for the same request body when retrying; changing the body under the same key produces an idempotency mismatch. Give each intended customer update its own key.
Treat permanent and temporary failures differently. A transient transport problem may justify a retry. An unknown customer, a disconnected channel or an expired WhatsApp window needs an application decision. Repeatedly sending the same request cannot repair a missing permission or an ineligible recipient.
Do not silently merge customer identities across channels. Link them through a verified account flow. Likewise, do not silently send a message through another channel because the first one failed: fallback changes the customer experience and should be an explicit product choice.
Choose your first channel and workflow
Start where your customers already contact you. Choose a task with a clear backend result, such as checking an order or moving a booking. Make that conversation work from request to completed operation before adding a second interface.
Then reuse the tool contract and adapt the channel boundary. Review recipient identity, formatting, attachments and delivery errors for the new channel. Compare completed tasks and support transfers by channel so you can see where the interface needs a different explanation.
A unified API is valuable when it reduces repeated work while preserving the details your product depends on. It should make adding another interface a smaller change, rather than making every channel behave as though it had the same rules.
Frequently asked questions
Does one API mean every channel has identical features?
No. A shared contract can normalize common operations while exposing channel-specific capabilities and constraints. Keep those differences explicit when they affect the customer’s task.
Can I reuse the same agent tools?
Yes. Keep the tools focused on application operations and make the messaging adapter responsible for translating channel events and replies.
Does 202 Accepted mean the customer received the message?
For Flow’s owner API, it means the message was queued. Read the message’s status using its returned ID. The meaning of a provider’s delivery state should remain explicit in your integration.
How do I get started with Flow?
Describe your app, choose one useful customer workflow and connect its backend operations. You can also talk to us about your channels and API requirements.
