Custom Channels
Connect any messaging platform or communication tool to the platform using custom channels. This lets you bring messages from platforms like website live chat widgets, email systems, CRMs, or any other service into your inbox — and respond to them with your AI Agent.
What Are Custom Channels?
Custom channels extend the platform beyond its built-in messaging platforms (WhatsApp, SMS, Instagram, Messenger). With custom channels, you can:
- Receive messages from any external platform into the platform’s unified inbox.
- Send replies from the app back to your external platform automatically.
- Use an AI Agent to respond to messages from any source.
- Track all conversations alongside your other channels in a single inbox.
This is ideal for businesses that use specialized communication tools, have a custom-built platform, or want all customer messages in one place.
Note: Custom channels require some technical setup. If you or your team are not comfortable with technical integrations, you may want to ask your web developer or IT team to help with this section.
How It Works
Custom channels work by passing messages back and forth between your external platform and the platform using webhooks (automated messages sent between systems over the internet). Here is the flow:
Your Platform ──(sends message to)──> The App
|
AI Agent responds
Contact saved
Message stored
|
The App ──(sends reply to)──> Your Platform
- Incoming messages: Your external platform sends messages to a web address (URL). Think of it as your platform “posting” a message to the platform’s mailbox.
- Processing: The platform creates or updates the contact, stores the message, and has an AI Agent generate a response (if active).
- Outgoing messages: When the platform sends a reply (whether from the AI or typed by you), it sends the message to a URL on your platform, where your system can deliver it to the end user.
Setting Up Incoming Messages (Your Platform to the App)
To send messages from your external platform into the app, your platform needs to send data to the following URL. Your developer will recognize this as a standard POST request (a common way for one system to send data to another over the internet).
Where to Send Messages
POST https://api.youraiconnector.com/v1/incoming_custom_channel_message?apiKey=YOUR_API_KEY
Replace YOUR_API_KEY with your API key (a private code that proves to the platform your platform is allowed to send it messages). Find or generate it under Settings → Integrations → API Key.
Message Format
Send the message data in the following format (JSON):
{
"customData": {
"messageSid": "unique-message-id-123",
"fromId": "user-456",
"toId": "your-business-id",
"body": "Hello, I have a question about your service.",
"status": "received",
"channel": "my-live-chat",
"campaignId": "optional-campaign-id",
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"mediaUrl": null,
"mediaContentType": null
},
"messageType": "text"
}
What each part means:
messageSid- A unique ID for this specific message (your system creates this). Used to prevent the same message from being processed twice.fromId- Who sent the message (could be a user ID, email, or phone number from your system).toId- Your business identifier (can be any label you choose).body- The actual message text.channel- A label you choose to identify where the message came from (e.g., “website-chat”, “email”).
Full Field Reference
| Field | Required? | What It Does |
|---|---|---|
customData.messageSid or customData.id |
Yes | A unique ID for this message (prevents duplicates) |
customData.fromId |
Yes | Identifies who sent the message (e.g., a user ID, email, or phone number from your system) |
customData.toId |
Yes | Identifies the receiving side (your business). Can be any text you choose. |
customData.body |
Yes | The actual message text. Cannot be empty. |
customData.status |
No | Message status. Leave this out to use the default ("received"). |
customData.channel |
No | A label for the source (e.g., "live-chat", "email", "my-crm"). Helps you identify where messages came from in your inbox. |
customData.campaignId |
No | A campaign/Agent ID. Use this to route the message to a specific AI configuration. |
customData.firstName |
No | Contact’s first name. Included when creating a new contact record. |
customData.lastName |
No | Contact’s last name. Included when creating a new contact record. |
customData.email |
No | Contact’s email address. Included when creating a new contact record. |
customData.mediaUrl |
No | A link to an attached file (image, video, audio, or document). Can also be a base64-encoded file (see below). |
customData.mediaContentType |
No | The file type (e.g., "image/jpeg", "video/mp4", "audio/ogg", "application/pdf"). Required if you include mediaUrl. |
messageType |
No | Type of message. Leave out for regular text. Set to "reaction" for emoji reactions. |
Emoji Reactions
If your platform supports emoji reactions (a thumbs up on a message, for example), send them as a reaction rather than as a text message: set messageType to "reaction" and put only the emoji in customData.body.
{
"messageType": "reaction",
"customData": {
"messageSid": "reaction-123",
"fromId": "user-42",
"toId": "my-business",
"body": "👍"
}
}
The assistant then treats it the way you would expect:
- A reaction to a question the assistant asked (for example “Does Thursday work?”) is treated as the answer, and the assistant replies.
- A reaction to a closing message (for example “Speak soon!”) ends the conversation quietly. No reply is sent.
If your platform turns reactions into text such as “Reacted with: 👍”, the assistant sees a normal text message and decides on its own whether to reply. Sending the reaction type avoids that.
What You Get Back
A successful request returns:
{
"success": true,
"messageId": "1234567890"
}
If something goes wrong, you will get an error message explaining the issue:
{
"error": "Message body cannot be empty"
}
Status Codes
| Code | What It Means |
|---|---|
200 |
Success - message received and being processed |
400 |
Something is wrong with your request - check for missing required fields or an empty message body |
401 |
Invalid API key - double check the key against Settings → Integrations → API Key |
405 |
Wrong request method - make sure you are using POST, not GET |
500 |
Something went wrong on the platform’s side - try again in a few moments |
If you set
customData.status, the only accepted value is"received"— leave it out entirely to use the default rather than sending anything else, or you’ll get a400.
Sending Media Attachments (Images, Videos, Files)
You can include file attachments (images, videos, audio, documents) with your messages. There are two ways to do this:
Option 1: Link to a File
If the file is already hosted online, provide the URL (web address) where the platform can download it:
{
"customData": {
"messageSid": "msg-789",
"fromId": "user-456",
"toId": "business-1",
"body": "Here is a photo of the issue.",
"channel": "support-portal",
"mediaUrl": "https://example.com/uploads/photo.jpg",
"mediaContentType": "image/jpeg"
},
"messageType": "text"
}
Option 2: Embed the File Directly (Base64)
If the file is not hosted online, you can embed it directly in the message as encoded text (base64 format). This is common in technical integrations where your system generates files on the fly. The platform will automatically decode and store the file:
{
"customData": {
"messageSid": "msg-790",
"fromId": "user-456",
"toId": "business-1",
"body": "Screenshot attached.",
"channel": "support-portal",
"mediaUrl": "data:image/png;base64,iVBORw0KGgo...",
"mediaContentType": "image/png"
},
"messageType": "text"
}
Note: Embedding files directly makes the message data much larger. For big files, it is better to host the file online and send a link (Option 1) instead.
Setting Up Outgoing Messages (the platform to Your Platform)
When the platform sends a reply on a custom channel (whether from the AI or typed by you), it automatically sends that reply to a URL on your platform so your system can deliver it to the end user.
Set the webhook URL first. You must save the custom channel webhook URL before any replies can be delivered. If no URL is saved, replies are still generated and stored, but they are never sent out — and they will not show a “Failed” status, so nothing in your inbox flags the problem. Always configure the webhook URL before going live.
Tell the App Where to Send Replies
- In the left sidebar, click Settings near the bottom.
- In the Settings left rail, under Channels, click Channels.
- Find the Custom channel card at the very bottom of the page (past Android SMS Gateway, iMessage, the website chat widget, Twilio Account, and Regulatory compliance).
- Enter the Webhook URL — the URL on your platform where the AI should send outgoing messages (your developer sets this up to receive and process replies). It must be a public HTTPS URL —
http://addresses and non-public hosts are rejected. - Click Save.
What the Platform Sends to Your Platform
When the platform sends a reply, your platform will receive the following data:
{
"contactId": "abc123",
"messageId": "msg-456",
"userId": "your-user-id",
"body": "Thank you for your message! Here is the information you requested...",
"toId": "user-456",
"channel": "my-live-chat"
}
What Each Field Means
| Field | What It Contains |
|---|---|
contactId |
the platform’s internal ID for this contact |
messageId |
The unique ID of this message in the app |
userId |
Your user ID |
body |
The reply text |
toId |
The contact’s ID on your platform (this matches the fromId you sent in the incoming message) |
channel |
The custom channel label you assigned |
Your platform receives this data and uses it to deliver the reply to the end user through your own system.
How the Platform Tracks Delivery
After sending the reply to your platform, the platform updates the message status:
- Sent - Your platform received the message successfully.
- Failed - Your platform returned an error or could not be reached. The platform stores the error details with the message so you can troubleshoot.
Sending Messages from Your System to the App
In addition to receiving messages, you can also send outbound messages through a custom channel directly from your own system. This is useful when you want to start a conversation or send a proactive message.
Plan requirement. Sending and syncing messages through the API requires a plan that includes API access and at least one messaging channel. If you receive a
403“permission denied / feature not enabled” error, your current plan does not include this — upgrade your plan or contact support.
Where to Send
POST https://api.youraiconnector.com/v1/send_custom_channel_message?apiKey=YOUR_API_KEY
Message Format
{
"customData": {
"fromId": "user-456",
"customChannel": "my-live-chat",
"body": "Hello! How can I help you today?",
"campaignId": "optional-campaign-id",
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com"
}
}
Required Fields
| Field | What It Does |
|---|---|
customData.fromId |
The contact’s ID on your platform |
customData.customChannel |
The name of your custom channel (e.g., “my-live-chat”) |
customData.body |
The message text to send |
The optional fields (campaignId, firstName, lastName, email) work the same as in incoming messages — they help the platform create or update the contact record.
What You Get Back
{
"success": true,
"messageId": "generated-message-id",
"contactId": "contact-id",
"message": "Message sent successfully"
}
Recording Messages Sent from Another System
Sometimes you have already sent a message to a contact from a different tool (for example, a workflow in another platform), and you simply want the platform to know about it so the AI has the full context. This is different from sending: the platform records the message but does not re-deliver it to the contact.
Where to Send
POST https://api.youraiconnector.com/v1/sync_custom_channel_message?apiKey=YOUR_API_KEY
Include customData.fromId (the contact’s ID on your platform) and customData.body (the message text that was already sent).
How It Behaves
- The message is recorded, not re-sent. The platform stores it on the conversation for context only.
- The AI is paused on that contact by default. This avoids the bot replying on top of a message a human already handled. To keep the bot active, pass
customData.pauseAi: false. - New contacts can be created automatically. Include
customData.customChanneland the contact will be created if it does not exist yet. - Duplicates are ignored. If you reuse the same
messageSid, the platform recognizes the message has already been recorded and makes no changes.
Plan requirement. Like sending, recording messages through the API requires a plan that includes API access and at least one messaging channel. A
403“permission denied / feature not enabled” error means your current plan does not include this.
Real-World Examples
Website Live Chat
Connect a live chat widget on your website to the platform so your AI Agent can answer visitor questions:
- A visitor types a message in your website’s chat widget.
- Your chat widget sends the message to the platform.
- The AI Agent generates a response.
- The response is sent back to your chat widget, which displays it to the visitor.
Why this is useful: Your website visitors get instant, AI-powered answers to their questions without you needing to be online.
Route email conversations through the platform so your AI Agent can respond to emails:
- Set up a system that forwards incoming emails to the platform (using the email sender’s address as the
fromId, the email subject and body as thebody, and"email"as thechannel). - The AI Agent reads the email and generates a reply.
- The reply is sent back to your email system, which sends it as a normal email response.
Why this is useful: Common email questions (pricing, hours, availability) get answered instantly by your AI Agent.
If your email system speaks IMAP/SMTP or OAuth, the built-in Email channel may be simpler than a custom integration.
CRM Integration
Connect your existing CRM (customer relationship management) system to the platform:
- When a lead sends a message through your CRM, forward it to the platform.
- The AI Agent responds and tracks the conversation.
- The AI response is sent back to your CRM for delivery.
- The full conversation history is available in both the platform and your CRM.
Why this is useful: Your sales team gets AI-assisted responses to leads without leaving their CRM.
Support Ticket System
Use the platform as an AI-powered first responder for customer support:
- Your ticketing system forwards new support tickets to the platform.
- The AI Agent sends an initial response (e.g., acknowledging the ticket and asking clarifying questions).
- The response is attached to the ticket in your support system.
- Your support team can review what the AI said and take over when needed.
Why this is useful: Customers get an immediate acknowledgment and initial help, even outside business hours.
Troubleshooting
Messages Not Being Received by the platform
- Verify your API key is correct and active (check Settings → Integrations → API Key).
- Make sure you are sending a POST request (not GET). Your developer will know the difference.
- Check that the
customData.bodyfield is not empty or whitespace-only. - Verify the
customData.fromIdfield is included. - Read the response message for specific error details.
Replies Not Reaching Your Platform
- Make sure you have entered your platform’s URL in the Custom channel card on the Channels page. If no URL is saved, replies are generated and stored but never sent out — and they will not be marked “Failed,” so check this first.
- Verify that the URL is publicly accessible (not behind a login or firewall) and returns a success response.
- Only replies (outgoing messages) are sent to your URL — incoming messages do not trigger this.
- Check for error details on the message in your inbox.
Contact Not Being Created
- Make sure the
fromIdvalue is consistent for the same user across all their messages. The platform uses this value to identify contacts — if it changes between messages, the platform will create a new contact each time. - Include
firstName,lastName, andemailin the first message from a new contact to create a complete contact record.
Media Attachments Not Working
- For file links (URLs), make sure the file is publicly accessible (no login required to access it).
- Always include
mediaContentTypewhen you includemediaUrl. - For embedded files (base64), verify the format is
data:MIME_TYPE;base64,ENCODED_DATA. - Make sure the file type you specify matches the actual file content.
Best Practices
- Use consistent
fromIdvalues. Each user on your platform should always have the samefromId. This ensures the platform groups all their messages into a single conversation instead of creating duplicate contacts. - Choose a clear
channelname. Pick something descriptive like"website-chat","email", or"zendesk"so you can easily tell where messages came from when viewing your inbox. - Include contact details (
firstName,lastName,email) in the first message from a new contact. This creates a complete, useful contact record right away. - Build in retry logic. Have your platform retry sending messages if the platform does not respond on the first attempt (network hiccups happen).
- Use unique
messageSidvalues for every message. This prevents the same message from being processed twice if your system sends it more than once. - Use
campaignIdto route messages to different AI Agents when you have multiple use cases (e.g., sales inquiries vs. support questions). - Test before going live. Send test messages in both directions and verify that contacts, conversations, and AI responses all work correctly before launching to real users.