The CM.com Business Messaging API enables you to send messages from your system to mobile phones all around the world. This RESTful API is the main interface between your application and the CM Platform and can be implemented to communicate via various communication channels - among others SMS, WhatsApp, RCS and Viber. We accept single messages, but also very high volumes. Core capability of this API is that it can cope with various communication channels and high throughput. The HTTP protocol is used, examples can be found in JSON and XML, though we advise to use JSON.
To make use of our API for SMS, you need to be registered at CM.com and have your billing details set in your CM Wallet. This can be recurring billing via credit card (self service), or via alternative payment methods (signed business contract required).
In order to make use of communication channels like WhatsApp, Viber, or RCS, you are required to have access to the programs. This can be requested via CM.com and we will help you with the verification and activation when your request meets the terms and conditions of these additional services. For this too a billing account is required.
During the implementation you might have questions and we kindly refer to our Help Center documents to get more background information.
We have built our API in such away that you can use it for various communication channels. Currently we support:
Please be aware when using channels other than SMS, CM needs to have configured the outgoing flows before you can use them. If you want to force the use of one channel or several specific channels, it is necessary to include which channel in the request.
Each channel comes with it's own rules and regulations from service providers and governments alike. You are responsible for following the rules and regulations for each channel that you use. Failure to do so might result in immediate termination of the service.
Several SDKs are available to get you started with your API integration.
Our global gateway is accessible via one end point which we are load balancing over 2 platform locations in The Netherlands. To reduce latency, and/or be compliant to local legislation we also have platforms in London, South Africa and Shanghai. More information can be found in our Help Center.
https://gw.cmtelecom.com/v1.0/message
https://gw.cmtelecom.co.za/v1.0/message
https://gw-cn.cmtelecom.com/v1.0/message
https://gw-hk.cmtelecom.com/v1.0/message
Our API supports sending messages via HTTP. You can send a POST request containing a JSON or XML body. We strongly advice that you use JSON. The newer communication channels like RCS, WhatsApp and Viber are only supported via JSON. Information and examples about XML, SMPP and GET can be found at the end of our API documentation.
All requests require your product token which, as a registered user, you can find on our platform in the Channels app or for older SMS accounts in the Gateway app.
NOTE: Your product token is private information and should never be incorporated into webpages and/or mobile applications where it can be exposed to 3rd parties.
Communication with the CM servers should be done using the TLS cryptographic protocol, version 1.2 or higher. Older security protocols such as TLSv1.1, TLSv1.0 and SSLv3 are not supported.
When making use of the WhatsApp Business API solution messages are encrypted on our platform. In our WhatsApp implementation guide we explain how this works. Encryption is a mandatory WhatsApp feature, implemented by CM.com. You don't have to do anything to enable this, it is part of the the WhatsApp account creation.
When implementing communication channels like WhatsApp, that allow conversations with for instance a Bot or Service employee, there will be data flows from your systems (outbound/outgoing) as well as data which needs to be sent to your systems (inbound/incoming/MO).
To receive incoming messages (MO), you need to set a webhook and map the incoming API in your system. More information can be found in the API documentation of the Inbound webhook
Below is an example of a Viber message:
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Message Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "TestSender",
"allowedChannels": ["Viber"]
}]
}
}
Field | Description | Required |
---|---|---|
from | This is the sender name. The maximum length is 16 digits for a phonenumber or 11 alphanumerical characters [a-zA-Z]. Example: 'CM Telecom' | Yes |
to | Phone number of the recipient [array] | Yes |
body | Text content of the message you want to send. SMS restrictions apply to this field allowing for maximum fallback capabilities. For more modern channels like RCS, WhatsApp and Apple Messages for Business, use rich content conversation items conversation items to make use of all capabilities of the channel. | Yes |
allowedChannels | Array of communication channels via which you want to reach the user. Can be any combination of: SMS , Viber , RCS , Apple Messages for Business , WhatsApp and MobilePush , or other channels: Twitter , Facebook Messenger , Google Business Messages , Instagram , Telegram Messenger . The default is to allow any channel configured for your account. |
No |
Please note that the
msg
,to
andallowedChannels
objects are arrays and can contain multiple values. Using multiplemsg
orto
elements will produce multiple messages.NOTE: When sending a message, all messages are delivered asynchronously. The server response of the API only indicates if it was accepted for a delivery attempt and not if the delivery was successful.
Please use the following format to specify your phone numbers. Using this format is the best way for us to guarantee the correct delivery of your messages:
Not adhering to this convention might cause incorrect delivery!
The phone number of our office in The Netherlands is +31 (0)76 - 572 70 00
What we would enter via API: 0031765727000
It is possible to send multiple messages with one request, as described in the examples below. You can either declare multiple phone numbers to send the same message to each of the given phone numbers, or declare multiple different messages in one request.
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["Viber"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
},{
"number": "00447911123457"
}],
"body": {
"type": "auto",
"content": "Test message"
}
},
{
"allowedChannels": ["SMS"],
"from": "OtherSender",
"to": [{
"number": "00447911123458"
},{
"number": "00447911123459"
}],
"body": {
"type": "auto",
"content": "Other Test message"
}
}
]
}
}
Not all people have installed the popular communication applications in your geographic region. Neither are they always online or are the operator networks always available to deliver messages. To overcome this issue we have developed a fallback solution. By specifying multiple channels in the allowedChannels
parameter, you can use another channel to deliver your messages when your first channel is not available or returning errors.
Example: specifying "allowedChannels": [ "WhatsApp", "SMS" ]
acts as a filter on your configured channel routing. If WhatsApp returns a failure or a rejection for any reason, we will use SMS and the content in the body
attribute to deliver an SMS instead. When a fallback is configured a channel will not retry delivery, but immediately fallback to the next channel.
Fallback is available for the channels:
For each batch of messages you send you can set a reference. To do so, add "reference": "your_reference"
to any "msg"
object in a request body. The given reference will apply to the messages sent to the numbers in the matching message.
The custom grouping fields are optional fields that can be used to tag messages. These tags can be used by other products, like the Transactions API.
Applying custom grouping names to messages helps filter your messages. With up to three levels of custom grouping fields that can be set, subsets of messages can be further broken down. The custom grouping name can be up to 100 characters of your choosing.
You should limit the number of unique custom groupings to 1000.
This field is used for a wide variety of cases, it helps you to group/tag your messages which helps you with analysis purposes. The following example demonstrates how to implement a reference and custom groupings in your JSON.
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["SMS"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
}],
"body": {
"type": "auto",
"content": "Test message"
},
"reference": "your_reference",
"customGrouping": "Campaign ABC",
"customGrouping2": "Department XYZ",
"customGrouping3": "Source 123"
}
]
}
}
At all times we strive to deliver messages to the end-user as fast as possible. There can be several situations in which we cannot succeed in this goal. Someone might have switched off his/her phone, or might be in a remote location and does not have access to a network. When you have sent them a message it might be received later than you anticipated.
If you wish to specify a time at which a delayed message can be considered irrelevant, you can supply an absolute date & time or a relative offset in the validity
field. Our system will consider the message as failed if it was not successfully delivered before that time. And via a Status Report we inform you this was the case.
The validity period is treated as a best-effort feature. Operators that are already processing the message, might not adhere to the validity period.
Our default validity time is 24 hours, and the maximum validity period is 72 hours.
This feature is supported in all communication channels, the behavior is the same.
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["SMS"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
}],
"body": {
"type": "auto",
"content": "Test message"
},
"validity": "2017-04-20 11:50 GMT"
}
]
}
}
You can supply the time zone for the validity period using either of the following formats:
Absolute date and time:
If no time zone was specified, CE(S)T will be used. (CM local time)
Relative offset in hour (H) or minute (M)
You can set the validity in either hours or minutes. A combination of both is not supported. Any value less than 30 minutes cannot be guaranteed to work.
Supported by: WhatsApp, RCS, Viber, Mobile Push*, Twitter, Facebook Messenger, Google Business Messages, Instagram Messaging
Note*: Only supported when making use of CMPush SDK V2.
Channels like WhatsApp, RCS and Viber support messages with Rich Content. Rich Content is content that is more complex than a simple text message.
Rich content is sent using the richContent
json attribute. This attribute in turns contains a conversation
and optionally suggestions
.
Field | Description | Required |
---|---|---|
conversation | An array of one or more conversation items | Yes |
suggestions | An array of zero or more suggestions | No |
A conversation is an array of several conversation item objects. The best way to think of a conversation item is as a single 'speech' bubble in a chat and you can send one or more in a single request. There are currently 5 conversation item types supported: text
, media
, location
, contact
and template
.
This example sends two conversation items, one with text and one with an image, via WhatsApp.
{
"messages": {
"authentication": {
"producttoken": "your product token"
},
"msg": [{
"from": "CM.com",
"to": [{
"number": "0031612345678"
}
],
"body": {
"type": "auto",
"content": "fallback content"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [{
"text": "A rich content text message"
},
{
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}]
}
}]
}
}
Field | Description | Required |
---|---|---|
text | A string with the textual content. | No |
media | A media object. | No |
location | A location object. | No |
contact | A contact object contains a description similar to a vCard. | No |
template | A communication channel specific template. | No |
At least one of these six is required in a conversation item. Not all channels support the same (combinations of) item types. For details and documentation on a conversation item type, we ask you to refer to that channel's documentation.
Conversation item type | Apple Messages for Business | Viber | RCS | SMS | Mobile Push | Facebook Messenger | Google Business Messages | Instagram Messaging | Telegram | ||
---|---|---|---|---|---|---|---|---|---|---|---|
Text | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
- Text formatting | √ | x | x | x | x | x | √ | √ | √ | √ | √ |
- URL previews | √ | √ | x | x | x | √ | √ | √ | √ | √ | √ |
Media | √ | √ | √ | √ | x | √* | √ | √ | √ | √ | √ |
- Image | √ | √ | √ | √ | x | √* | √ | √ | √ | √ | √ |
- Video | √ | √ | x | √ | x | √* | √ | √ | x | √ | √ |
- Audio | √ | √ | x | √ | x | √* | x | √ | x | x | √ |
- Rich card | x | x | √ | √ | x | √* | x | √ | √ | √ | x |
- Rich card carousel | x | x | x | √ | x | x | x | √ | √ | √ | x |
Location | √ | x | x | √ | x | x | x | x | x | x | x |
Contact | √ | x | x | x | x | x | x | x | x | x | x |
Template | √ | x | x | x | x | x | x | x | x | x | x |
List picker | x | √ | x | x | x | x | x | x | x | x | x |
Time picker | x | √ | x | x | x | x | x | x | x | x | x |
OAuth2 | x | √ | x | x | x | x | x | x | x | x | x |
Custom app | x | √ | x | x | x | x | x | x | x | x | x |
Payment | x | √ | x | x | x | x | x | x | x | x | x |
Note*: Only supported when making use of CMPush SDK V2.
Please note that not all communication channels offer the exact same features and that the UI might vary per phone. To make use of rich content you need to do some investigation work to ensure that all mobile devices can read what you are sending. Be sure to check the Channel specific sections of this document for further details. And we can help you in defining and identifying this, please contact our support teams when you need a consult.
Supported by: RCS, Viber, Apple Messages for Business, Mobile Push*, Twitter, Facebook Messenger, Instagram, Google Business Messages
Note*: Only supported when making use of CMPush SDK V2.
Suggestions is an array of suggestion items. A suggestion or feature is usually presented to an end user as a button, and allows the end user to quickly take or pick an action, instead of sending a textual reply. One message can contain up to 11 (some channels allow more or less) suggestions to a user. How they are used depends on the scenario you want to built. Usually only 2 or 3 are seen by the end-user when opening the message.
Each suggestion
item contains at least the fields action
and label
.
Field | Description |
---|---|
Label | The text the end user will see |
Action | OpenUrl / CreateCalendarEvent / Dial / ViewLocation / Reply / Login / Logout / ViewProduct |
Depending on the action, certain additional fields are expected to complete the user flow.
Supported by: RCS, Viber, Apple Messages for Business, Mobile Push*, Facebook Messenger, Google Business Messages and Instagram.
Note*: Only supported when making use of CMPush SDK V2.
This is used to give the user an option to open a link. This can be an in-app link, which will only be shown when the app is installed.
postbackdata
field is required by Google Business Messages (1000 character limit).URL | The url the end user can open |
{
"suggestions": [
{
"action": "OpenUrl",
"url": "market://details?id=cm.com",
"label": "Install app",
"postbackdata": "Data sent back in an MO"
},
{
"action": "OpenUrl",
"url": "https://docs.cmtelecom.com/en/api/business-messaging-api/1.0/index/",
"label": "SMS documentation",
"postbackdata": "Data sent back in an MO"
}
]
}
Supported by: Instagram
OpenUrl can be used as a default action when a user taps your rich card.
{
"defaultAction": {
"action": "OpenUrl",
"url": "https://cm.com"
}
}
Supported by: RCS
When the user clicks on this icon, it opens the calendar app of the user to add the new appointment.
Calendar | A calendar object |
The calendar object contains the following fields.
StartTime | The start of the appointment. For example "2018-02-05T07:00:00 |
EndTime | The end of the appointment, for example "2018-02-05T08:00:00" |
Description | The description which will appear in the calendar app |
Title | The title of the appointment which will appear in the calendar app |
{
"action": "CreateCalendarEvent",
"label": "Add to calendar",
"calendar":
{
"startTime": "2018-02-05T00:00:00",
"endTime": "2018-02-08T00:00:00",
"description": "Calendar demo",
"title": "Demo"
}
}
Supported by: RCS, Facebook Messenger, Google Business Messages
RCS also provides options to make a phone call straight from the conversation. When you want to present the user with the option to call you or another team, or listen to a spoken recorded message, this suggestion can be applied. When pressed, starts a new call to the number you have inserted.
postbackdata
field is required by Google Business Messages (1000 character limit).Dial | A dial object |
The dial object contains the following field. |
PhoneNumber | The number to call (in international format) |
{
"action": "Dial",
"label": "Call us",
"postbackdata": "Data sent back in an MO",
"dial": {
"PhoneNumber": "+310612345"
}
}
Supported by: RCS
When you want to share a location, you can send this message. When the user receives it it opens the navigation app of the user with a pin at the specified location.
ViewLocation | A view location object |
View location objects contains the following fields:
Latitude (optional) | The latitude in degrees |
Longitude (optional *1) | The longitude in degrees |
SearchQuery (optional *1) | Search for this location instead of using the latitude/longitude |
Label (optional) | The label to display at the pin |
1. Either the search query or the latitude & longitude are required! |
{
"action": "viewLocation",
"viewLocation": {
"latitude": "51.603802",
"longitude": "4.770821",
"label": "CM HQ"
},
"label": "Open in maps"
}
Supported by: RCS, Mobile Push*, Twitter, Facebook Messenger, Google Business Messages, Instagram
Note*: Only supported when making use of CMPush SDK V2.
Use this suggestion if you want to suggest responses to the user. When the user clicks on a Reply
suggestion, the label text is automatically sent back as a response.
description
field is only supported by Twitter. postbackdata
field is required by Facebook Messenger, Google Business Messages and Instagram (1000 character limit).media
object is only supported by Facebook Messenger (thumbnail image).{
"action": "Reply",
"label": "Make an appointment",
"description": "Doctor",
"postbackdata": "Data sent back in an MO",
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
Supported by: Facebook Messenger
Use this suggestion if you may want to identify the user as a customer who already has an account with your business. This will suggest a login button that let you link the recipients identity on the channel, like Facebook Messenger, with your site by directing them to you web-based login flow for authentication.
URL | Authentication callback url the end user can use for login |
{
"action": "Login",
"url": "https://www.example.com/authorize"
}
Supported by: Facebook Messenger
Use this suggestion if you want to provide an unlink account option, can only be used if Login action has been used by the user before. The recipient identity on the channel, like Facebook Messengger, will remove the link with your website provided during the Login suggestion.
{
"action": "Logout"
}
Supported by: Facebook Messenger
Use this suggestion if you want to render a marketable product that's linked to your product catalog.
Product | A marketable product object |
The product object contains the following fields:
Id | Unique catalog ID provided by channel |
{
"action": "ViewProduct",
"product": {
"id": "FB_tshirt_001"
}
}
When you have sent out a notification and want to link that to incoming information you can connect those via REFERENCES.
When sending a request with an invalid msg part to the JSON gateway, it will continue to check the other to
objects and msg
objects available and send the correctly formatted values. In the JSON response, you can find details per message. With each message you receive the PhoneNumber of the failed message (if present), the accepted or rejected status, your reference for the message (if present), the amount of message parts we created for that message, and a description why the message was rejected (if present).
Acceptance by the gateway (aka receiving errors) is not the same as actual delivery of a message. Delivery is done asynchronously and as such you can only receive information about delivery status via the status report webhooks.
Examples of responses of failed JSON requests:
Entire request incorrect:
Status: 400 Bad Request
{
"details": "No account found for the given authentication",
"errorCode": 101, //See table "JSON POST Error codes" below
"messages": []
}
Incorrect msg
and a correct message:
Status: 200 OK
{
"details": "Created 1 message(s)",
"errorCode": 201, //See table "JSON POST Error codes" below
"messages": [
{
"to": "00447911123456",
"status": "Accepted",
"reference": "your_reference_A",
"parts": 1,
"messageDetails": null,
"messageErrorCode": 0 //See table "JSON POST Error codes" below
},
{
"to": "00447911123457",
"status": "Rejected",
"reference": "your_reference_B",
"parts": 0,
"messageDetails": "A body without content was found",
"messageErrorCode": 304 //See table "JSON POST Error codes" below
}
]
}
All incorrect:
Status: 400 Bad Request
{
"details": "Created 0 message(s)",
"errorCode": 201,
"messages": [
{
"to": "0044791112345a",
"status": "Rejected",
"reference": "your_reference_A",
"parts": 0,
"messageDetails": "Gsm '0044791112345a' is not a number.",
"messageErrorCode": 303 //See table "JSON POST Error codes" below
},
{
"to": "00447911123456",
"status": "Rejected",
"reference": null,
"parts": 0,
"messageDetails": "A body without content was found",
"messageErrorCode": 304 //See table "JSON POST Error codes" below
}
]
}
NOTE: The XML gateway and JSON gateway have different output, and respond differently based on the error. For XML responses, please see the section on XML communication.
HTTP status | Error text | Remarks |
---|---|---|
405 | (none) | No HTTP GET or POST was used to send your request |
500 | "details": "Unknown Error" | An unexpected error occurred. Check the provided values. Contact CM for support. |
400 | "details": "No account found for the given authentication" | No account found for the provided product token. |
400 | "details": "Insufficient balance." | Trial accounts only: You are out of trial messages. Order new messages via your dashboard. If you are a regular prepaid customer, you will be notified that you have run out of quota in a Status Report. |
400 | "details": "Message is unroutable." | Your request could not be routed. Contact CM for support. |
400 | "details": "Invalid product token." | Invalid or missing product token |
400 | "details": "A MESSAGES object requires at least one MSG object" | A MSG object within the MESSAGE object is required and is missing. |
400 | "details": "Invalid JSON" | The given JSON is malformed. Please validate your JSON syntax and try again. |
200 | "details": "Created [x] message(s)" | An [x] amount of messages have been accepted. See the messages objects for further details. |
- | "messageDetails": "No FROM field found in a MSG object." | The ‘FROM’ element is missing within the ‘MSG’ element |
- | "messageDetails": "Empty mobilenumber field, MT ignored" | The Phone Number value for the TO element is missing |
- | "messageDetails": "Rejected: Gsm '[msisdn]' is not a number." | The value for the TO element is not a valid Phone Number |
- | "messageDetails": "[Object] object is an invalid type, must be an array" | The stated [Object] should be an array. Even if this contains one element. |
- | "messageDetails": "No body field was found" | The ‘BODY’ element is missing within the ‘MSG’ element |
- | "messageDetails": "A body without content was found" | The ‘BODY’ element is missing ‘CONTENT’ |
Error code | Description |
---|---|
0 | Ok |
999 | Unknown error, please contact CM support |
101 | Authentication of the request failed |
102 | The account using this authentication has insufficient balance |
103 | The product token is incorrect |
201 | This request has one or more errors in its messages. Some or all messages have not been sent. See MSGs for details |
202 | This request is malformed, please confirm the JSON and that the correct data types are used |
203 | The request's MSG array is incorrect |
301 | This MSG has an invalid From field (per msg) |
302 | This MSG has an invalid To field (per msg) |
303 | This MSG has an invalid Phone Number in the To field (per msg,) |
304 | This MSG has an invalid Body field (per msg) |
305 | This MSG has an invalid field. Please confirm with the documentation (per msg) |
401 | Message has been spam filtered |
402 | Message has been blacklisted |
403 | Message has been rejected |
500 | An internal error has occurred |
Please note that there are a few limitations to using unicode encoded messages:
It is possible to let our gateway detect the encoding for you by including the type: auto
setting. In case it detects characters that are not part of the GSM character set, the message will be delivered as Unicode. Any existing DCS value will be ignored. If the message contains more than 70 characters in Unicode format it will be split into a multipart message. You can limit the number of parts by setting the maximum number of message parts (see also the section on Multipart below).
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["SMS"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
}],
"minimumNumberOfMessageParts": 1,
"maximumNumberOfMessageParts": 8,
"body": {
"type": "auto",
"content": "Κείμενο διαθέσιμο σε όλες τις γλώσσες"
}
}
]
}
}
By default our gateway interprets SMS messages as if sent with the standard 7 bit GSM encoding. You can use the DCS (data coding scheme) parameter to indicate the type of message you are sending. If you set DCS to '0' or do not include the parameter, the messages uses standard GSM encoding. If you want to send messages using e.g. Arabic, Cyrillic of Greek characters you will need to use the unicode UCS2 encoding. To set your message up for unicode messaging include <DCS>8</DCS>
in your <MSG>
-element, or if you're using JSON "dcs": 8
in a msg
object. See the examples below.
View the Unicode paragraph for more information.
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["SMS"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
}],
"dcs": 8,
"body": {
"content": "Κείμενο διαθέσιμο σε όλες τις γλώσσες"
}
}
]
}
}
When your message is longer than 160 characters (or 70 when it contains unicode characters), we call such a message a multipart or concatenated message. The gateway will first check if an SMS is bigger than 160 (or 70) characters, and if so the message will be cut into multiple parts.
Please note that there are a few limitations to using multipart messages:
{
"messages": {
"authentication": {
"producttoken": "00000000-0000-0000-0000-000000000000"
},
"msg": [ {
"allowedChannels": ["SMS"],
"from": "SenderName",
"to": [{
"number": "00447911123456"
}],
"minimumNumberOfMessageParts": 1,
"maximumNumberOfMessageParts": 8,
"body": {
"content": "Using these settings we can send SMS messages that contain more than 160 characters as if it is one message. Please do note that this limits the length of one message to 153 characters."
}
}
]
}
}
This chapter of our API Documentation is designed for customers who have been granted access to WhatsApp Business API. It is important that you request access to this program via our Channels portal. Without this approval you can not make use of this part of the API.
WhatsApp also comes with a considerable set of 'business rules' that you might have to take into account when using WhatsApp. Be sure to read our Implementation guide and its Rules and Regulations
Note: since WhatsApp for Business is used for 2-way communication (chat) it is important to also implement the Inbound flow using our API documentation of the Inbound webhook.
When making use of the WhatsApp Business API solution, messages are encrypted on our platform. In our WhatsApp implementation guide we explain how this works. Encryption is a mandatory WhatsApp feature, implemented by CM.com. You don't have to do anything to enable this, it is part of the the WhatsApp account creation.
There are two types of rate limits for WhatsApp. Capacity limits and messaging limits.
Capacity limit is restriction in maximum throughput, that allows 50 messages per second. When you are sending more than this maximum throughput, messages may fail from being sent.
Messaging limit is a restriction in how many unique users your business can send messages to on a daily basis. More about this can be read here: Messaging Limits
For service requests, users usually initiate a conversation and will reach out to you. To link incoming messages to your outbound messages, the phone number field is used.
An example of sending a message via WhatsApp by specifying allowedChannels
with a WhatsApp
value. This example makes use of the Rich Content conversation
array, with 3 conversation items (or speech bubbles), 2 text bubbles and one image. These will all be deliverd at once.
The body
's content attribute is also required. It is the content value that will be used when falling back to SMS as a delivery channel. The body.content attribute needs to be backwards compatible with SMS channel requirements. This means it is affected by maximum size limitations of SMS as described in the section on SMS multipart messaging.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text for SMS"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [{
"text": "A text message with *bold* formatting in a speech bubble."
}, {
"text": "Another speech bubble"
}, {
"media": {
"mediaName": "and an image",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}]
}
}]
}
}
**Note:*** The WhatsApp protocol strives for, but does not guarantee, in-order delivery of your messages.
If you have configured multiple WhatsApp-numbers in our platform, you can use the desired phone number by providing it in the from
field.
If this does not match to one of your phone numbers, your first onboarded number will be used.
Example:
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Message Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["WhatsApp"]
}]
}
}
Text messages are and should always be encoded in UTF-8 and do support characters like emojis 😀. This is true for both the body
field and when using a text
item inside a Rich Content conversation
. Please remember that emoji rendering is device dependent and older devices therefore may not support the newest unicode emojis and depending on the font used by the device, an emoji may look slightly different on from one device to another 📱💻🖥.
The maximum length of a WhatsApp text message bubble is 4096 characters.
WhatsApp specifically allows a limited amount of formatting for text messages that you can make use of. These markup characters need to be prefixed with a space character in order for them to take effect.
Formatting | Symbol | Example |
---|---|---|
Bold | Asterisk (*) | Your total is *$10.50*. |
Italics | Underscore (_) | Welcome to _WhatsApp_! |
Tilde (~) | This is ~better~ best! | |
Code |
Three backticks (``` ) |
```print 'Hello World';``` |
A line break can be inserted by using: \n
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [{
"text": "A text message with *bold* formatting in a speech bubble."
}, {
"text": "Another speech bubble"
}]
}
}]
}
}
Any URLs present in the message text of a WhatsApp message will be automatically recognized by the clients as links. Additionally, the first URL encountered in a text message will generate a URL preview. For this it is required that the URL starts with http://
or https://
A URL preview can contain a title, a message and a small fragment of text. These elements are automatically retrieved from the destination website. To support this preview, the destination website needs to have implemented the Open Graph Protocol.
The URL preview is retrieved by the WhatsApp software running on the CM.com side, before being sent to the client. This is for privacy reasons.
To send a message to a user first a template must be used. These templates must be setup and approved before they can be used. You can request templates via the Channels portal. Once a template is approved you can use the template namespace and name to send a message (Use the details button in your template overview to find these values).
The template message must have the exact same number of variables as the template has. The same template can be set-up in multiple languages, hence you also need a language parameter.
Please remember that a user must have opted in for the type of communication as well. The opt-in must be an active opt-in. This means it must be triggered by a user action, such as entering a phone number in a WhatsApp field or checking a box to indicate consent.
See also Facebook's opt-in guide.
A template object contains a 'whatsapp' object, which corresponds to the template object in the WhatsApp for Business docs.
Field | Description | Required |
---|---|---|
namespace | The namespace that will be used, will be provided to you after the template is approved | Yes |
element_name | The element name of the template that will be used, will be provided to you after the template is approved | Yes |
language | Specifies the language, see below for object definition | Yes |
components | Array containing the content-components of the message, to personalize the templated message. See the WhatsApp documentation for advanced details. | Yes (only for media templates) |
localizable_params | An array of parameters to personalize the templated message. Use components if your template needs media or has a header/footer. See the WhatsApp documentation for advanced details. |
Yes (only for regular templates) |
Media templates is a newer generation of WhatsApp templates, which in addition to the text body, can also feature a header with an additional image, video or document, as well as a footer.
The header can have three component types: image
, document
, video
and text
. The body and footer can only have the component type text
. The parameters
are similar to the localizable_params
of the older template format, but NOT the same.
See the WhatsApp documentation for advanced details.
{
"messages": {
"authentication": {
"producttoken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "0031612345678"
}
],
"body": {
"type": "auto",
"content": "This is a WhatsApp message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation":
[{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "replace-value-1"
},
{
"type": "currency",
"currency" : {
"fallback_value": "$100.99",
"code": "USD",
"amount_1000": 100990
}
},
{
"type": "date_time",
"date_time" : {
"fallback_value": "February 25, 1977",
"day_of_week": 5,
"day_of_month": 25,
"year": 1977,
"month": 2,
"hour": 15,
"minute": 33, // OR
"timestamp": 1485470276
}
},
]
}
]
}
}
}]
}
}]
}
}
Interactive templates is a newer generation of WhatsApp templates, which in addition to the media template, can also support button
-components.
The button
-component can be either of sub_type
: quick_reply
or url
.
quick_reply
the end-user will see a suggestion to respond with. The button text itself has to be specified during creation of the template.url
you are able to send a Call-to-action button. This can be a phone number to call, or an url to visit. This has to be specified during creation of the template as well.The payload
on quick_reply
buttons will be sent back when an end-user interacts with such a button. This will be explained in the MO documentation.
See the WhatsApp documentation for advanced details.
{
"messages": {
"authentication": {
"producttoken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}
],
"body": {
"type": "auto",
"content": "fallback message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation":
[{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [{
"type": "body",
"parameters": [
{
"type": "text",
"text": "your-text-string"
}
]
},
{
"type": "button",
"sub_type" : "quick_reply",
"index": "0",
"parameters": [
{
"type": "payload",
// Business Developer-defined payload
"payload":"aGlzIHRoaXMgaXMgY29vZHNhc2phZHdpcXdlMGZoIGFTIEZISUQgV1FEV0RT"
}
]
},
{
"type": "button",
"sub_type" : "url",
"index": "1",
"parameters": [
{
"type": "text",
// Business Developer-defined dynamic URL suffix
"text": "9rwnB8RbYmPF5t2Mn09x4h"
}
]
},
{
"type": "button",
"sub_type" : "url",
"index": "2",
"parameters": [
{
"type": "text",
// Business Developer-defined dynamic URL suffix
"text": "ticket.pdf"
}
]
}]
}
}
}]
}
}]
}
}
This is the template message format without media. See also the WhatsApp documentation for advanced details.
The hsm-templates that use the localizable_params
-structure, will be deprecated in a future version.
{
"messages": {
"authentication": {
"producttoken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "0031612345678"
}
],
"body": {
"type": "auto",
"content": "This is a WhatsApp message"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation":
[{
"template": {
"whatsapp": {
"namespace": "your namespace id here",
"element_name": "TEMPLATE_NAME",
"language": {
"policy": "deterministic",
"code": "en"
},
"components": [{
"type": "body",
"parameters": [
{
"type": "text",
"text": "your-text-string"
},
{
"type": "currency",
"currency": {
"fallback_value": "$100.99",
"code": "USD",
"amount_1000": 100990
}
},
{
"type": "date_time",
"date_time" : {
"fallback_value": "February 25, 1977",
"day_of_week": 5,
"day_of_month": 25,
"year": 1977,
"month": 2,
"hour": 15,
"minute": 33
}
},
{
"type": "date_time",
"date_time" : {
"fallback_value": "February 25, 1977",
"timestamp": 1485470276
}
}
]
}]
}
}
}]
}
}]
}
}
Field | Description | Required |
---|---|---|
policy | deterministic — Deliver the message template in exactly the language and locale asked for.fallback — deprecated Deliver the message template in the language that matches user's language/locale setting on device. If one can't be found, deliver using the specified fallback language. |
Yes |
code | The code of the language or locale to use — Accepts both language and language_locale formats (e.g., en and en_US). | Yes |
WhatsApp maintains a list of valid language codes
Note: Please note that the fallback language policy will be deprecated by WhatsApp in January 2020 and the deterministic language policy will become the default policy.
In WhatsApp the following media types are supported:
Type | Supported file types | to send |
---|---|---|
image | JPG, JPEG, PNG | image/jpeg, image/png |
video | MP4 (see notes) | video/mp4 |
audio | AAC, M4A, AMR, MP3, OGG OPUS | audio/aac, audio/m4a, audio/amr |
audio/mpeg, audio/ogg; codecs=opus | ||
document | PDF, DOC(X), PPT(X), XLS(X), etc | Any valid MIME-type |
Notes:
This is the size of the media file after encryption:
Media Type | Size |
---|---|
audio | 16 MB |
document | 100 MB |
image | 5 MB |
sticker | 100 KB |
video | 16 MB |
Media object contains the following fields:
Term | Description |
---|---|
MediaName | The filename for a document, or the caption of the image or video (not supported for audio). |
MediaUri | The location of the image, audio or video. The Uri should return a correct Content-Type header |
MimeType | The mime type of the image, audio or video. |
{
"conversation": [
{
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
}
As data usage costs might apply when the end user is not on Wifi, please be considerate when sending media messages. We strongly advise not to send files larger than 1 MB, and for a conversation not to exceed 20Mb.
Interactive messages are new features supported by WhatsApp. The options are:
List Messages: You are now able to send list pickers, if you would like your end user to make an choice you can send messages including a menu of up to 10 options. This will give a much better experience for your end users.
Reply Buttons: Send messages with reply buttons, these type of messages makes the conversation flow much quicker. You can only send an maximum of 3 reply buttons. Reply buttons have the same user experience as interactive templates with buttons.
Example list message
{
"conversation": [{
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "your-header-content"
},
"body": {
"text": "your-text-message-content"
},
"footer": {
"text": "your-footer-content"
},
"action": {
"button": "cta-button-content",
"sections": [{
"title": "your-section-title1",
"rows": [{
"id": "unique-row-identifier1",
"title": "row-title-content",
"description": "row-description-content"
}]
},
{
"title": "your-section-title2",
"rows": [{
"id": "unique-row-identifier2",
"title": "row-title-content",
"description": "row-description-content"
}]
}
]
}
}
}]
}
Please note that the title of your section contains an maximum length: 24 characters. Each row must have a title (Maximum length: 24 characters) and an ID (Maximum length: 200 characters). You can add a description (Maximum length: 72 characters), but it is optional.
Example reply buttons
{
"conversation": [
{
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "your text"
},
"body": {
"text": "your-text-body-content"
},
"footer": {
"text": "your-text-footer-content"
},
"action": {
"buttons": [{
"type": "reply",
"reply": {
"id": "unique-postback-id1",
"title": "First Button"
}
},
{
"type": "reply",
"reply": {
"id": "unique-postback-id2",
"title": "Second Button"
}
}
]
}
}
}
]
}
Please note of the following guidelines: title: Button title. It cannot be an empty string and must be unique within the message. Does not allow emojis or markdown. Maximum length: 20 characters. id: Unique identifier for your button. This ID is returned in the webhook when the button is clicked by the user. Maximum length: 256 characters.
Example reply buttons with Media Notes: It is possible to send images, videos or documents when using reply buttons. Audio is not supported in combination with actions. To do so add an media object in the Interactive Header. You also need to update the header type to what kind of media, the options are image, video or document.
example:
{
"conversation": [
{
"interactive": {
"type": "button",
"header": {
"type": "image",
"Media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/blog/content/logo-cmcom.png",
"mimeType": "image/jpeg"
}
},
"body": {
"text": "your-text-body-content"
},
"footer": {
"text": "your-text-footer-content"
},
"action": {
"buttons": [{
"type": "reply",
"reply": {
"id": "unique-postback-id1",
"title": "First Button"
}
},
{
"type": "reply",
"reply": {
"id": "unique-postback-id2",
"title": "Second Button"
}
}
]
}
}
}
]
}
WhatsApp product messages is an feature to share products with your customers.
Product List Messages: Messages containing a selection of up to 30 items from a business’ inventory. Single Product Messages: Messages with a single product item from the business’ inventory. The product is displayed in a Product Detail Page (PDP) format.
Users that receive product messages can add products to an shopping cart, send the shopping cart to the business and share products with friends on WhatsApp.
Please note that to send these type of messages an WhatsApp business number needs to be linked to an Facebook business page. Where products can be added via commerce manager. In the commerce manager a catalog of products can be made to send out via product messages. For more details visit https://developers.facebook.com/docs/whatsapp/guides/commerce-guides
Example single product message
{
"conversation": [{
"interactive": {
"type": "product",
"body": {
"text": "Do you want to enjoy the fun of a new mousepad?"
},
"footer": {
"text": "Limited edition, only 1 per order."
},
"action": {
"catalog_id": "catalogid-from-commercemanager",
"product_retailer_id": "product-id-in-catalog"
}
}
}]
}
example list product message
{
"conversation": [{
"interactive": {
"type": "product_list",
"body": {
"text": "Hi customer! We have some new products in stock!"
},
"header": {
"type": "text",
"text": "New products"
},
"action": {
"catalog_id": "catalogid-from-commercemanager",
"sections": [{
"title": "Products",
"product_items": [{
"product_retailer_id": "product-id-in-catalog"
},
{
"product_retailer_id": "product-id-in-catalog"
},
{
"product_retailer_id": "product-id-in-catalog"
}
]
}]
}
}
}]
}
Currently, these types of messages can be received in the following minimum WhatsApp versions:
iOS: 2.21.100 (Multi-Product Messages) and 2.21.210 (Single Product Messages). Android: 2.21.9.15 (Multi-Product Messages) and 2.21.19 (Single Product Messages). Web: The web client that supports these features has been launched.
To send a location to a user use the location object, which contains the following fields:
Latitude | The latitude in degrees |
Longitude | The longitude in degrees |
SearchQuery | The address to display |
Label | The label to display at the pin |
Example
{
"conversation": [
{
"location": {
"latitude": "51.603802",
"longitude": "4.770821",
"label": "CM HQ",
"searchQuery": "Konijnenberg 30"
}
}
]
}
To send one or more contacts to a user use the Contacts array, which contains the fields described in WhatsApp for Business docs.
Note that the name.formatted_name
and at least one of: name.first_name, name.last_name, name.middle_name, name.suffix, name.prefix
is required.
Example
{
"conversation": [
{
"contacts": [
{
"addresses": [
{
"city": "Breda",
"country": "Netherlands",
"country_code": "NL",
"street": "Konijnenberg 30",
"type": "WORK",
"zip": "4825 BD"
}
],
"name": {
"formatted_name": "CM Developer",
"last_name": "Your last name"
}
}
]
}
]
}
This chapter of our API Documentation is designed for customers who have been granted access to Apple Messages for Business. It is important that you request access to this program via our our Channels portal. Without this approval you can not make use of this part of the API.
Apple Messages for Business has a considerable set of 'business rules' that you might have to take into account when using Apple Messages for Business.)
Note: since Apple Messages for Business is used for 2-way communication (chat) it is important to also implement the Inbound flow using our API documentation of the Inbound webhook.
For service requests, users initiate a conversation and will reach out to you. To link incoming messages to your outbound messages, the from/to field is used with an Apple Messages for Business message-identifier value.
An Apple Messages for Business message-identifier or the 'Opaque user identifier' as Apple calls it, is a string of alpha numerical characters that you have received as the from address in an incoming message. This is the only information you have about a user on the Apple platform. You do not receive the name, profile image, location or anything else the user has not shared themselves within conversation.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
},
"to": [{
"number": "Apple Messages for Business-identifier"
}],
"from": "TestSender",
"allowedChannels": ["Apple Messages for Business"]
}]
}
}
Text messages are and should always be encoded in UTF-8 and do support characters like emojis. This is true for both the body
field and when using a text
item inside a Rich Content conversation
.
There is no official maximum length of an Apple Messages for Business message bubble, but up to 4096 characters is known to work. After 1024 characters, the user has to click the message to be able to read the full contents.
Any URLs present in the message text of a Apple Messages for Business message will be automatically recognized by the clients as links. Additionally, if a message starts or ends with a URL (and begins with http://
or https://
), the URL will be split off from the rest of the message and delivered as "preview url" bubble. A URL in the middle of a message will not generate a URL preview. The URL preview is retrieved by the software running on the device of the end user. For privacy reasons the preview is only generated after the consumer clicks "Tap to load Preview".
In order to have a preview image (or even preview video) without requiring the consumer to manually load it, make use of an OpenUrl suggestion instead.
Apple Messages for Business supports all media types that the devices, such as an iPhone, itself supports.
Notes:
Media object contains the following fields:
Term | Description |
---|---|
MediaName | The filename of the file, including file extension |
MediaUri | The location of the image, audio or video. |
MimeType | The mime type of the image, audio or video. |
{
"conversation": [
{
"media": {
"mediaName": "conversational-commerce.jpg",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
}
As data usage costs might apply when the end user is not on Wifi, please be considerate when sending media messages. We strongly advise not to send files larger than 1 MB, and for a conversation not to exceed 20Mb.
Suggestions allow you to request the end user to take an action and you will receive the result of that action via the MO webhook.
Suggestions currently supported for our Apple Messages for Business Channel are: OpenUrl, Pick, Payment.
Suggestions for Apple Messages for Business are specific per conversation part and thus included inside the conversation item, instead of at the richContent
level as with RCS and Viber.
Sending a message with a Url action and a preview of the URL. With this method users do not have to click "Tap to preview". You can add text, a label, the url and media items to your conversation part.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [
{
"richContent": {
"conversation": [{
"text": "CM.com - Be part of it.",
"suggestions": [
{
"action": "OpenUrl",
"label": "CM.com - Be part of it.",
"url": "https://www.cm.com/products/talk/",
"media": {
"mediaName": "cm-com.png",
"mediaUri": "https://www.cm.com/cdn/cm/cm-com.png",
"mimeType": "image/png"
}
}
]
}]
},
"body": { "content": "CM.com - Be part of it." },
"from": "CM Test",
"allowedChannels": ["Apple Messages for Business"],
"to": [
{ "number": "Apple Messages for Business-identifier" }
]
}
]
}
}
With a list picker you can present a button in the conversation that when clicked presents a list of options to the users. These lists can have labels and a media thumbnail.
NOTE: Don't send images that are exceptionally large as the download time, may influence the time it takes to present the options to the user.
When the user makes a choice the response will be sent back to you via the MO webhooks.
{
"conversation": [
{
"text": "Magic trick",
"listpicker": {
"label": "Please, pick a card",
"media": {
"mediaUri": "https://static.thenounproject.com/png/393234-200.png"
},
"options": [
{
"label": "Ace of Hearts",
"media": {
"mediaUri": "https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.N7zZqoCvjxZZvwp2Zi1UVwHaH6%26pid%3D15.1&f=1"
}
},
{
"label": "Ace of Spades",
"media": {
"mediaUri": "https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.pixabay.com%2Fphoto%2F2013%2F07%2F12%2F12%2F01%2Fsuit-of-spades-145116_960_720.png&f=1"
}
},
{
"label": "Ace of Diamonds",
"media": {
"mediaUri": "https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fcdn.pixabay.com%2Fphoto%2F2012%2F05%2F07%2F18%2F37%2Fsuit-48941_960_720.png&f=1"
}
},
{
"label": "Ace of Clubs",
"media": {
"mediaUri": "https://proxy.duckduckgo.com/iu/?u=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2F8%2F8a%2FSuitClubs.svg%2F709px-SuitClubs.svg.png&f=1"
}
}
]
}
}
]
}
The text element of the message will be shown in the message, the label element in the list picker will be shown in the list picker.
A quick reply makes it easy for end users to select one of the options you present them.
When the user makes a choice the response will be sent back to you via the MO webhooks.
{
"conversation": [
{
"listpicker": {
"label": "a CM conversational product",
"options": [
{
"label": "Communication Platform as a Service"
},
{
"label": "Mobile Marketing Cloud (MMC)"
},
{
"label": "Mobile Service Cloud (MSC)"
},
{
"label": "Conversational AI Cloud"
}
]
}
}
]
}
With a time and date picker you can present a button in the conversation that when clicked presents a list of time and dates to the user to pick from. This is a good method to plan meetings and/or delivery times.
When the user makes a choice the response will be sent back to you via the MO webhooks.
In order to setup a time picker, you submit a timePicker object with an options array containing the suggested date and time slots for the user to pick from. Optionally you can add a label and location which will be used when an end users add the appointment to the calendar.
"conversation": [
{
"text": "Click here to pick a time.",
"timePicker": {
"label": "Appointment at CM HQ",
"location": {
"latitude": "51.603802",
"longitude": "4.770821",
"label": "CM HQ"
},
"options": [
{
"startTime": "2020-02-21T09:00",
"endTime": "2020-02-21T10:00"
},
{
"startTime": "2020-02-22T09:00",
"endTime": "2020-02-22T10:00"
},
{
"startTime": "2020-02-23T09:00",
"endTime": "2020-02-23T10:00"
}
]
}
}
]
Note that the start time must always be in the future.
It is possible to do an OAuth 2 authentication within a conversation. Using the OAuth2 authentication prompt, you can ask a user to login via a 3th party website. Authentication results are received via the MO webhooks.
The 3th party must be configured in the Apple Messages for Business account on the Apple Business Register.
"conversation": [
{
"oauth2": {
"responseType": "token",
"state": "3a77fc39-ac33-404f-896a-e0fad171a343",
"responseEncryptionKey": "SOME LONG ENCRYPTION KEY",
"clientSecret": "SOME CLIENT SECRET",
"scope": ["email","profile","openid"]
}
}
]
It is also possible to make a payment using Apple Pay. Setting this up requires some custom work and we therefor ask you to contact our support team.
If you have your own app and want to have your own Apple Messages for Business integrations than this is possible as well. Again, please contact our support team.
Our business messaging API supports sending and receiving Twitter direct messages.
Being able to send Twitter direct messages requires requesting access via the Channels portal. Without onboarding with Twitter via the portal, you can not make use of this part of the API.
Feature | Support | Remarks |
---|---|---|
encryption | yes | There is no end-to-end encryption. However, messages are transmitted over the public Internet using https |
delivery notification | yes | Occurs when your message is delivered to the Twitter platform. Delivery notifications are sent to the status report webhooks. |
text messages | yes | The maximum length of a Twitter direct message is 10.000 characters and it must be UTF-8 encoded. |
urls in text | yes | |
media | yes | Media name attribute should end in the proper file extension. Only one media file is allowed per message; when sending multiple files, each file will be sent in its own Twitter message. When the linked media doesn't exist/can't be found, the message will not be sent at all. |
media: images | yes | Maximum file size for an uploaded image is 5 MB. Supported MIME types are image/jpeg, image/png, **image/webp***. |
media: gifs | yes | Maximum file size for an uploaded GIF is 15 MB. Supported MIME types are image/gif. |
media: video | yes | Maximum file size for an uploaded video is 512 MB. Supported MIME types are video/mp4, video/quicktime. |
read receipts | yes | Read receipts are sent to the status report webhooks. |
reply suggestions | yes | Maximum label length: 36 characters. |
* Note: Only non-animated webp files are supported by Twitter
Onboarding is done via our Channels portal. Via our portal, you are redirected to the authorization page of Twitter. On this page you will need to authorize our Twitter app, called CM Business Messaging API to send and receive Direct Messages on behalf of your Twitter account.
Sending Twitter DMs using the CM Business Messaging API also requires you to adhere to the Twitter rules.
An extended set of rules and policies for Twitter messages can be found here.
It is allowed to have multiple Twitter accounts under one CM.com account.
Note that in case of Twitter, the Twitter account that is used for sending messages is also still available in the regular Twitter app, from the Twitter website and from other 3rd party Twitter apps. Our API only has permissions to send on behalf of the Twitter account, but it's not exclusively in control of that Twitter account.
This means that it will be possible to send messages using Twitter as well as using our API, and that might lead to situations where the API will relay replies to messages you sent via the Twitter app or website.
In those cases it will seem like messages are missing from a conversation when you use both ways of communicating with your end-users.
Our recommendation is to use the API exclusively for these Twitter accounts, and not switch between the Twitter app or website and the API, because the API won't "know" about the messages you sent using the app or website, but it will receive the replies to those messages.
In your Twitter account, make sure you have enabled "Receive messages from anyone", found under Settings...Privacy and safety...Receive messages from anyone
. If you don't enable this, end-users won't be able to message you and start a conversation.
There are two ways you can start a conversation with a Twitter end-user yourself;
if the end-user follows your Twitter account.
In other cases the only way to start a Twitter conversation with end-users is when the end-user starts the conversation by sending you an initial message.
When a message is received from an end-user, you may send up to 5 messages in response within a 24 hour window. Each message received resets the 24 hour window and the 5 allotted messages. Sending a 6th message within a 24 hour window or sending a message outside of a 24 hour window will count towards rate-limiting.
Unlike other channels, Twitter does not use telephone numbers as identifiers for sender (from
) and recipient (to.number
), instead it uses so called "snowflakes", which are unique identifiers of the twitter accounts (e.g. the Twitter account @cmchanneldev has the snowflake 1263071591262494721).
The snowflake is a 64-bit unsigned integer, and is visible in the CM.com platform as the userid
under channels...Twitter
.
If you send a message including both an image and some text, Twitter will display this as one entity, always placing the text below the image, and “joining” the two visually.
It is possible to have the text above the image by sending two seperate conversations in a single API call; Twitter will then display them in order, but the text is not visually joined with the image.
See the Direct message with text and image example.
Since Twitter Direct Messaging is used for 2-way communication (chat) it is important to also implement an Inbound flow. You can find more information about how to do this using our API documentation of the Inbound webhook. Note that for Twitter you need to set up your webhook API in the Channels app, not in the Gateway app.
Please note that currently we only support snowflakes when sending and receiving Twitter direct messages. An upcoming version of the API might also allow for using Twitter handles, but please note that a Twitter user may change their handle at any point in time, while the Twitter snowflake will remain the same for each individual account. Therefore, we would recommend using snowflakes as identifiers to prevent problems matching users to messages in your system.
The example below will send a simple text-only Twitter direct message.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your snowflake",
"to": [
{
"number": "Recipients Snowflake"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Twitter"],
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
}
}
]
}
}
In the example below we send a simple rich content message that contains both text and an image that Twitter will display as one entity. An explanation on how to send rich content messages in general can be found in the rich content description.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your snowflake",
"to": [
{
"number": "Recipients Snowflake"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Twitter"],
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"media": {
"mediaName": "conversational-commerce.jpg",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions. An explanation on reply suggestions can be found under Suggestions/Features under Rich Content
NOTE: Twitter only supports suggestions with
"action": "Reply"
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your snowflake",
"to": [
{
"number": "Recipients Snowflake"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Twitter"],
"richContent": {
"conversation": [
{
"text": "Hi, what can I do for you?",
"suggestions": [
{
"action": "Reply",
"label": "Create an appointment"
},
{
"action": "Reply",
"label": "Change my appointment"
},
{
"action": "Reply",
"label": "Cancel my appointment"
}
]
}
]
}
}
]
}
}
Our business messaging API supports sending and receiving Facebook Messenger messages.
Being able to send Facebook Messenger messages requires requesting access via the Channels portal. Without onboarding with Facebook Messenger via the portal, you can not make use of this part of the API.
Feature | Support | Remarks |
---|---|---|
delivery notification | yes | Occurs when your message is delivered to the Facebook Messenger platform. Delivery notifications are sent to the status report webhooks. |
text messages | yes | The maximum length of a Facebook Messenger message is 2.000 characters and it must be UTF-8 encoded. |
media | yes | Media name attribute should end in the proper file extension. Only one media file is allowed per message; when sending multiple files, each file will be sent in its own Facebook Messenger message. When the linked media doesn't exist/can't be found, the message will not be sent at all. The provided text message is sent in a separate Facebook Messenger message. |
media: images | yes | Maximum file size for an uploaded image is 25 MB. All common MIME types supported. For example: image/jpeg, image/png, image/webp. |
media: gifs | yes | Maximum file size for an uploaded GIF is 25 MB. Supported MIME types are image/gif. |
media: video | yes | Maximum file size for an uploaded video is 25 MB. All common MIME types supported. For example: video/mp4, video/quicktime. |
media: audio | yes | Maximum file size for an uploaded audio is 25 MB. All common MIME types supported. For example: audio/aac, audio/mpeg. |
media: document | yes | Maximum file size for an uploaded document is 25 MB. All common MIME types supported. For example: application/pdf. |
reply suggestions | yes | Maximum label length: 20 characters. |
rich card | yes | Support for generic, media, button and product template. |
rich carousel | yes | Support for generic and product templates. Maximum of 10 templates supported. |
message tags | yes | Allows messaging outside the standard messaging window of 24 hours. |
Onboarding is done via our Channels portal. On our portal, you will be presented with a facebook login pop up. In this pop up you will need to authorize our Facebook app, called CM.com Business Messaging to send and receive Facebook Messenger messages on behalf of your Facebook account.
This app requires the following permissions to work correctly:
If you choose the de-select these permissions in the facebook pop up, we will not be able to complete the onboarding.
Sending Facebook Messenger messages using the CM Business Messaging API also requires you to adhere to the Facebook Messenger Policy & Guidelines.
It is allowed to have multiple Facebook accounts under one CM.com account.
Note that in case of Facebook, the Facebook account that is used for sending messages is also still available in the regular Facebook app, from the Facebook website and from other 3rd party Facebook apps. Our API only has permissions to send on behalf of the Facebook account, but it's not exclusively in control of that Facebook account.
This means that it will be possible to send messages using Facebook as well as using our API, and that might lead to situations where the API will relay replies to messages you sent via the Facebook app or website.
In those cases it will seem like messages are missing from a conversation when you use both ways of communicating with your end-users.
Our recommendation is to use the API exclusively for these Facebook accounts, and not switch between the Facebook app or website and the API, because the API won't "know" about the messages you sent using the app or website, but it will receive the replies to those messages.
The only way to have a Facebook Messenger conversation with end-users is when the end-user starts the conversation by sending you an initial message.
Facebook Messenger has rate limits in place; the per day rate limit is equal to 200 * the number of people the customer can message via Facebook Messenger.
If you choose to revoke any of the permissions given during the onboarding process on facebooks side, we might no longer be able to deliver messages.
Once onboarded, the authorization of our Facebook app expires after 90 days. This impacts the ability of our Facebook app to retrieve the name of the end user. In order to remedy this, you must re-authorize our Facebook app using the same onboarding process.
Unlike other channels, Facebook Messenger does not use telephone numbers as identifiers for sender (from
) and recipient (to.number
), instead it uses a so called "Page Scoped User ID (PSID)" for the recipient and a "Page ID" for the sender. A person is assigned a unique PSID for each Facebook Page they start a conversation with. Do note that the PSID is only valid for the Facebook page that received a message from a Facebook user.
Your Page ID is visible in the CM.com platform under channels...Facebook Messenger
. The last section of the Page URL is your Page ID. E.g. https://www.facebook.com/1234567890 with 1234567890 as the Page ID.
If you send a message including both an image and some text, Facebook Messenger will display these as separate messages; typically the text will be the first message.
See the Facebook Messenger message with text and image example.
The following actions are supported by Facebook as buttons.
Action | Remarks |
---|---|
Reply* | Maximum length of label is 20 characters. |
OpenUrl | Maximum length of label is 20 characters, url required. |
Dial | Maximum length of label is 20 characters, phone number required. |
Login | Suggestion without text, url required. |
Logout | Suggestion without text. |
Note*: A reply action can be used as either a button or as a quick reply.
An explanation on suggestions can be found under Suggestions/Features
Quick Replies allows you to suggest quick answers for the recipient beneath your message. Quick replies can be combined with any type of message; text, media or rich card. A maximum of 13 quick replies are supported by Facebook Messenger.
The following restrictions apply for a quick reply:
Field | Required | Remarks |
---|---|---|
label | Yes | Maximum length is 20 characters. |
postbackdata | Yes | Maximum length is 1000 characters. |
media | No | Thumbnail image, should be at least 24 x 24 pixels. |
Quick replies can also be included as a reply button to a template but each template has its own button limit. If those limit has been passed, your reply suggestions will be included as quick replies beneath your message.
More info can be found in the rich content description.
Message tags enable sending important and personally relevant 1:1 updates to users outside the standard messaging window of 24 hours. This enables greater flexibility in how you interact with people, as well as the types of experiences you can build on the Facebook Messenger Platform. They may not be used to send promotional content (e.g. deals, offers, coupons, discounts, etc.). Use of tags outside of the approved use cases may result in restrictions on the Page's ability to send messages. See the Facebook Messenger Platform policy for details.
The following message tags are supported:
Tag | Description |
---|---|
CONFIRMED_EVENT_UPDATE | Send the user reminders or updates for an event they have registered for (e.g., RSVP'ed, purchased tickets). This tag may be used for upcoming events and events in progress. |
POST_PURCHASE_UPDATE | Notify the user of an update on a recent purchase. |
ACCOUNT_UPDATE | Notify the user of a non-recurring change to their application or account. |
HUMAN_AGENT | Allows human agents to respond to user inquiries. Messages can be sent within 7 days after a user message. |
Rich cards, called templates in Facebook Messenger, offer a way for you to offer a richer in-conversation experience than standard text messages by integrating buttons, images and more alongside text in a single message. Rich cards can be used for many purposes, such as displaying product information or asking the message recipient to choose from a pre-determined set of options.
You can send rich cards as one of the following Facebook templates.
More info about the templates specifically down below.
When sending rich cards we recommend adhering to the Best Practices defined by Facebook.
The button template sends a structured message with up to three attached buttons. This template is useful for offering the recipient options to choose from, such as pre-determined responses to a question, or actions to take.
The button template is quit similar to other templates. But unlike other templates, there is a maximum of 640 characters.
The following restrictions apply for a button template:
Field | Support | Required | Remarks |
---|---|---|---|
cards | No | No | Supported if a single card is given |
header | Yes | Yes | Displayed as the text. Maximum length is 640 characters. |
text | No | No | - |
mediaUri | No | No | - |
suggestions | Yes | Yes | Maximum of 3 buttons per card. If more are given, all will be included as quick replies, instead of buttons. |
The following Facebook buttons can be used. More info about each button can be found in the rich content description.
Button | Action | Remarks |
---|---|---|
URL | OpenUrl | Maximum length of button text is 20 characters, url required. |
Postback | Reply | Maximum length of button text is 20 characters. |
Call number | Dial | Maximum length of button text is 20 characters, phone number required. |
Log in | Login | Button without text, url required. |
Log out | Logout | Button without text. |
When sending rich cards containing buttons, we recommend adhering the Best Practises for using buttons defined by Facebook.
The media template allows you to send a image, GIF, or video as a structured message with an optional button. Videos and animated GIFs sent with the media template are playable in the conversation.
The following restrictions apply for a media template:
Field | Support | Required | Remarks |
---|---|---|---|
cards | No | No | Supported if a single card is given |
header | No | No | - |
text | No | No | - |
mediaUri | Yes | Yes | Image or video |
suggestions | Yes | No | Maximum of 1 button per card. If more are given, all will be included as quick replies, instead of buttons. |
The product template sends a structured message to render products that have been uploaded to your Facebook catalog. You need to provide the product ids that are linked to your Facebook page.
Up to 10 products can be provided via either suggestions directly or suggestions in a carousel.
The following restrictions apply for a product template:
Field | Support | Required | Remarks |
---|---|---|---|
cards | Yes | No | With a maximum of 10 per message. |
header | No | No | - |
text | No | No | - |
mediaUri | No | No | - |
suggestions | Yes | Yes | Only action 'ViewProduct' supported. With a maximum of 10 per message. |
A simple structured message that includes a title. May include a subtitle, image and up to three buttons.
This template will be used if fields are given that are not covered by other Facebook templates.
The following restrictions apply for a generic template:
Field | Support | Required | Remarks |
---|---|---|---|
cards | Yes | Yes (If header not defined) | Maximum 10 allowed per message. At least one property must be set in addition to header. |
header | Yes | Yes (If cards not defined) | Displayed as the title. Maximum length is 80 characters. |
text | Yes | No | Displayed as the subtitle. Maximum length is 80 characters. |
mediaUri | Yes | No | The URL of the image to display. |
suggestions | Yes | No | Maximum of 3 buttons per card. If more are given, all will be included as quick replies, instead of buttons. |
You can use the following matrix to check what type of message will be send with the included inputs.
Text | Media | Suggestions | Header | Output |
---|---|---|---|---|
x | x | x | x | Not supported |
x | x | x | √ | Generic template |
x | x | √ | x | Product template if 'ViewProduct' action, otherwise not supported |
x | x | √ | √ | Button template with max 3 buttons or as template with quick replies |
x | √ | x | x | Media message |
x | √ | x | √ | Generic template |
x | √ | √ | x | Media template with max 1 button or as template with quick replies |
x | √ | √ | √ | Generic template with max 3 buttons or as template with quick replies |
√ | x | x | x | Text message |
√ | x | x | √ | Generic template |
√ | x | √ | x | Text message with quick replies |
√ | x | √ | √ | Generic template with max 3 buttons or as template with quick replies |
√ | √ | x | x | Text and Media messages |
√ | √ | x | √ | Generic template |
√ | √ | √ | x | Not supported |
√ | √ | √ | √ | Generic template with max 3 buttons or as template with quick replies |
Since Facebook Messenger is used for 2-way communication (chat) it is important to also implement an Inbound flow. You can find more information about how to do this using our API documentation of the Inbound webhook. Note that for Facebook Messenger you need to set up your webhook API in the Channels app, not in the Gateway app.
The following examples are some showcases of the possible input matrix combinations
An explanation on how to send rich content messages in general can be found in the rich content description.
The example below will send a simple text-only Facebook Messenger message.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"allowedChannels": ["Facebook Messenger"],
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
}
}
]
}
}
In the example below we send a simple rich content message that contains both text and an image that Facebook Messenger will display as two separate messages.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Facebook Messenger"],
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}
]
}
}
In the example below we send a simple rich content message that contains elements that Facebook Messenger will display as a generic template.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Facebook Messenger"],
"richContent": {
"conversation": [
{
"carousel": {
"cards": [
{
"header": "CM.com - Be part of it.",
"text": "Want to know more about CM.com?",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
},
"suggestions": [
{
"action": "REPLY",
"label": "Give me more info",
"postbackdata": "INFO"
},
{
"action": "OPENURL",
"label": "Visit CM.com",
"url": "https://www.cm.com/"
}
]
}
]
}
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Facebook Messenger"],
"richContent": {
"conversation": [
{
"text": "Hi, what can I do for you?",
"suggestions": [
{
"action": "Reply",
"label": "Call me",
"postbackdata": "CALL"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "EMAIL"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "SMS"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains elements that Facebook Messenger will render as a product from your product catalog.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Facebook Messenger"],
"richContent": {
"conversation": [
{
"suggestions": [
{
"action": "VIEWPRODUCT",
"product": {
"id": "FB_tshirt_001"
}
},
{
"action": "VIEWPRODUCT",
"product": {
"id": "FB_tshirt_002"
}
},
{
"action": "VIEWPRODUCT",
"product": {
"id": "FB_tshirt_003"
}
}
]
}
]
}
}
]
}
}
In the example below we send a simple text message with a message tag "POST_PURCHASE_UPDATE"
applied. This tag is used to notify the user of an update on a recent purchase.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Page ID",
"to": [
{
"number": "Recipients PSID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Facebook Messenger"],
"richContent": {
"conversation": [
{
"text": "Dear customer, your order with id 1234xyz has been shipped.",
"tag": "POST_PURCHASE_UPDATE"
}
]
}
}
]
}
}
Our business messaging API supports sending and receiving messages on Instagram Messaging.
Being able to send Instagram messages requires requesting access via the Channels portal. Without onboarding with Instagram via the portal, you can not make use of this part of the API.
Feature | Support | Remarks |
---|---|---|
delivery notification | yes | Occurs when your message is delivered to the Instagram platform. Delivery notifications are sent to the status report webhooks. |
text messages | yes | The maximum length of a Instagram message is 1.000 characters and it must be UTF-8 encoded. |
media | yes | Media name attribute should end in the proper file extension. Only one media file is allowed per message; when sending multiple files, each file will be sent in its own Instagram message. When the linked media doesn't exist/can't be found, the message will not be sent at all. The provided text message is sent in a separate Instagram message. |
media: images | yes | Maximum file size for an uploaded image is 8 MB. All common MIME types supported. For example: image/jpeg, image/png, image/x-icon, image/bmp. |
media: gif | no | Will only display the first frame of the GIF. |
media: audio | no | |
media: video | coming soon | Only supported by sharing a Instagram post containing a video. |
reply suggestions | yes | Maximum label length: 20 characters. |
rich card | yes | Support for generic template. |
rich carousel | yes | Support for generic template. Maximum of 10 templates supported. |
message tags | Yes | Allows messaging outside the standard messaging window of 24 hours. |
handover protocol | yes | Allows handover to the Instagram Inbox for live agents. |
To be able to onboard, you need to set-up the following:
Onboarding is done via our Channels portal. On our portal, you will be presented with a Facebook login pop up where you need to login with your Facebook account that is linked to your Instagram Business account.
In this pop up you will need to authorize our Facebook app, called CM.com Business Messaging to send and receive Instagram messages on behalf of your Instagram account.
This app requires the following permissions to work correctly:
If you choose to de-select these permissions in the Facebook pop up, we will not be able to complete the onboarding. It is allowed to have multiple Instagram accounts under one CM.com account.
Sending Instagram messages using the CM.com Business Messaging API also requires you to adhere to the Instagram Policy & Guidelines.
Please note that you must comply to Instagram's Technical Requirements. Specifically for incoming messages:
Note that in case of Instagram, the Instagram account that is used for sending messages is also still available in the regular Instagram app, from the Instagram website and from other 3rd party Instagram apps. Our API only has permissions to send messages on behalf of the Instagram account, it's not exclusively in control of that Instagram account.
This means that it will be possible to send messages using Instagram as well as using our API, and that might lead to situations where the API will relay replies to messages you sent via the Instagram app or website.
In those cases it will seem like messages are missing from a conversation when you use both ways of communicating with your end-users.
Our recommendation is to use the API exclusively for these Instagram accounts, and not switch between the Instagram app or website and the API, because the API won't "know" about the messages you sent using the app or website, but it will receive the replies to those messages.
The only way to have a Instagram conversation with end-users is when the end-user starts the conversation by sending you an initial message.
Instagram has rate limits in place; the per day rate limit is equal to 200 * the number of people the customer can message via Instagram.
If you choose to revoke any of the permissions given during the onboarding process on Facebooks side, we might no longer be able to deliver messages.
Unlike other channels, Instagram Messaging does not use telephone numbers as identifiers for sender (from
) and recipient (to.number
), instead it uses a so called "Instagram Scoped User ID (IGSID)" for the recipient and a "Instagram Account ID" for the sender. A person is assigned a unique IGSID for each Instagram Business account they start a conversation with.
Your Instagram Account ID is visible in the CM.com platform under channels...Instagram
.
If you send a message including both an image and some text, Instagram will display these as separate messages; typically the text will be the first message.
See the Instagram message with text and image example.
Quick replies provide a way to present a set of buttons in-conversation for users to reply with. A maximum of 13 quick replies are supported and each quick reply allows up to 20 characters before being truncated. Quick replies only support plain text. Note: quick replies are only visible in the Instagram app, not via web browser.
The following restrictions apply for a quick reply:
Field | Required | Remarks |
---|---|---|
label | Yes | Maximum length is 20 characters. |
postbackdata | Yes | Maximum length is 1000 characters. |
More info can be found in the rich content description.
For Instagram Messaging, experiences must have an escalation path that allows end-users to speak to a human agent instead of a bot. If you have a custom inbox solution, you can handle the human agent escalation by yourself by switching between a bot and live agents in your inbox solution.
If you don't have a custom inbox solution, we provide support to escalate to the Instagram inbox of your Instagram account instead by following the steps below.
In order to allow CM.com to perform a handover to your Instagram inbox, you need to update the settings of your Facebook page that is linked with your Instagram account after you have successfully onboarded in the CM.com platform.
In your Facebook page settings, go to Advanced messaging
and browse to Handover protocol
.
Click on the Configure
button and select CM.com Business Messaging
as the primary receiver for the handover protocol.
To provide the end-user to speak with a human agent via the Instagram inbox, you must send a quick reply with HUMAN_AGENT
as postback data.
If the end-user then selects this quick reply, the handover event will be triggered by CM.com, changing the conversation from the app to the message inbox in Instagram.
After the handover event has been triggered, CM.com has no control of the conversation for 24 hours. During this timeframe, a human agent has to escalate the conversation with the end-user via your Instagram account. These messages will not be tracked by CM.com during the 24 hour timeframe until it has expired.
If your human agent is done with the conversation or want CM.com to take control again, sending a message via the Business Messaging API will cancel the handover protocol. This will make CM.com take control again of the conversation with the end-user.
Rich cards, called Generic Templates in Instagram Messenger, offer a way for you to offer a richer in-conversation experience than standard text messages by integrating buttons, images and more alongside text in a single message. Rich cards can be used for many purposes, such as displaying product information or asking the message recipient to choose from a pre-determined set of options.
Note: this is supported only for the Instagram App.
Note: when using a carousel (2 to 10 generic templates), put the cards containing a media image and at least a button first and/or second, as the behavior and sizing of the rest of the cards is affected by them.
A simple structured message that must include a title and must include at least one of the following: a subtitle, an image and/or up to three buttons.
This template will be used if fields are given that are not covered by other Instagram templates.
The following restrictions apply for a generic template:
Field | Support | Required | Remarks |
---|---|---|---|
cards | Yes | Yes (If header not defined) | Maximum 10 allowed per message. At least one property must be set in addition to header. |
header | Yes | Yes (If cards not defined) | Displayed as the title. Maximum length is 80 characters. |
defaultAction | Yes | No | Make the template behave as if it is an open url button when a user taps it. |
text | Yes | No | Displayed as the subtitle. Maximum length is 80 characters. |
mediaUri | Yes | No | The URL of the image to display. |
suggestions | Yes | No | Maximum of 3 buttons per card. |
You can use the following matrix to check what type of message will be send with the included inputs.
Text | Default Action | Media | Suggestions | Header | Output |
---|---|---|---|---|---|
x | x | x | x | x | Not supported |
x | x | x | x | √ | Generic template with just a title |
√ | x | x | x | √ | Generic template with a title and a subtitle |
√ | x | √ | x | √ | Generic template with a title, a subtitle and a media image. |
√ | x | x | √ | √ | Generic template with a title, a subtitle and up to 3 buttons. |
x | x | √ | x | √ | Generic template with a title and a media image. |
x | x | √ | √ | √ | Generic template with a title, a media image and up to 3 buttons. |
x | x | x | √ | √ | Generic template with a title and up to 3 buttons. |
√ | x | √ | √ | √ | Generic template with a title, a subtitle, a media image and up to 3 buttons. |
√ | √ | x | x | √ | Generic template with a title, a subtitle and a default action. |
x | √ | x | x | √ | Generic template with a title and a default action. |
x | √ | √ | x | √ | Generic template with a title, a media image and a default action. |
x | √ | x | √ | √ | Generic template with a title, a default action and up to 3 buttons. |
√ | √ | √ | √ | √ | Generic template with a title, a subtitle, a default action, a media image and up to 3 buttons. |
Since Instagram Messaging is used for 2-way communication (chat) it is important to also implement an Inbound flow. You can find more information about how to do this using our API documentation of the Inbound webhook. Note that for Instagram you need to set up your webhook API in the Channels app, not in the Gateway app.
An explanation on how to send rich content messages in general can be found in the rich content description.
The example below will send a simple text-only Instagram message.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"allowedChannels": ["Instagram"],
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
}
}
]
}
}
In the example below we send a simple rich content message that contains both text and an image that Instagram will display as two separate messages.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"allowedChannels": ["Instagram"],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Instagram"],
"richContent": {
"conversation": [
{
"text": "Hi, what can I do for you?",
"suggestions": [
{
"action": "Reply",
"label": "Call me",
"postbackdata": "CALL"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "EMAIL"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "SMS"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions. One of the suggestions with postback data HUMAN_AGENT
will trigger the handover protocol.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Instagram"],
"richContent": {
"conversation": [
{
"text": "Hi, what can I do for you?",
"suggestions": [
{
"action": "Reply",
"label": "Ask a question",
"postbackdata": "QUESTION"
},
{
"action": "Reply",
"label": "Talk to live agent",
"postbackdata": "HUMAN_AGENT"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a rich card. The rich card is composed of a title, a subtitle, a default action, a media image and two suggestions. One of the suggestions will open an external url, while the other suggestion will start a handover protocol based upon it's postback data HUMAN_AGENT
.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Instagram"],
"richContent": {
"conversation": [
{
"header": "We are CM.com!",
"text": "Visit our website or start a chat with one of our employee's!",
"defaultAction": {
"action": "OpenUrl",
"url": "https://cm.com"
},
"media": {
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg"
},
"suggestions": [
{
"action": "OpenUrl",
"label": "Visit our website!",
"url": "https://cm.com"
},
{
"action": "Reply",
"label": "I want to chat!",
"postbackdata": "HUMAN_AGENT"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a carousel of rich cards. The rich cards have multiple different compositions in which they are shown to the end user.
Three possible different compositions are:
It's possible to mix different elements with each other.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your Instagram account ID",
"to": [
{
"number": "Recipients IGSID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Instagram"],
"richContent": {
"conversation": [
{
"carousel": {
"cards": [
{
"header": "We are CM.com!",
"text": "Visit our website or start a chat with one of our employee's!",
"media": {
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg"
},
"suggestions": [
{
"action": "OpenUrl",
"label": "Visit our website!",
"url": "https://cm.com"
},
{
"action": "Reply",
"label": "I want to chat!",
"postbackdata": "HUMAN_AGENT"
}
]
},
{
"header": "Our logo!",
"defaultAction": {
"action": "OpenUrl",
"url": "https://cm.com"
},
"media": {
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg"
}
},
{
"header": "Conversational Channels",
"text": "Here's a selection of some of the channels we support!",
"suggestions": [
{
"action": "OpenUrl",
"label": "WhatsApp!",
"url": "https://www.cm.com/whatsapp/"
},
{
"action": "OpenUrl",
"label": "Instagram Messaging!",
"url": "https://www.cm.com/instagram-messaging"
},
{
"action": "OpenUrl",
"label": "RCS!",
"url": "https://www.cm.com/rcs/"
}
]
}
]
}
}
]
}
}
]
}
}
Our business messaging API supports sending and receiving Google Business Messages.
Being able to send Google Business Messages requires requesting access via the Channels portal. Without onboarding with Google Business Messages via the portal, you can not make use of this part of the API.
Feature | Support | Remarks |
---|---|---|
delivery notification | yes | Occurs when your message is delivered to the Google Business Messages platform. Delivery notifications are sent to the status report webhooks. |
text messages | yes | The maximum length of a Google Business Messages message is 1.500 characters. Rich text is for messages only, it isn't supported in welcome messages, suggested replies, suggested actions, or rich cards. |
media | yes | Media name attribute should end in the proper file extension. Only one media file is allowed per message; when sending multiple files, each file will be sent in its own Google Business Messages message. When the linked media doesn't exist/can't be found, the message will not be sent at all. The provided text message is sent in a separate Google Business Messages message. |
media: images | yes | Maximum file size for an uploaded image is 5 MB. Supported MIME types are image/jpeg, image/png. |
media: gifs | no | |
media: video | no | |
media: audio | no | |
media: document | no | |
reply suggestions | yes | Maximum label length: 25 characters. |
rich card | yes | Support for text, media or suggestions. |
rich card carousel | yes | Minimum of 2 and maximum of 10 rich cards. |
message tags | yes | Allows messaging from a specific source |
live agent request | yes | Allows a BOT to send a Live Agent Request suggestion to the end-user. |
Onboarding is done via our Channels portal. On our portal, you will be presented with an onboarding page in which you have to provide CM.com information about your agent. With this information CM.com will create, verify, and launch the agent itself and the agent’s locations for you.
Sending Google Business Messages using the CM Business Messaging API also requires you to adhere to the Google Business Messages Terms of Service, Acceptable Use Policy and Guidelines for sending messages.
To be able to send Google Business Messages the creation of an agent is required. An agent is a conversational entity that users interact with. You create one agent for each brand you manage.
An agent encompasses a brand's business functions, such as online support, and physical locations (if any). Each message contains the context from which the user initiated the conversation.
It is allowed to have multiple agent accounts under one CM.com account.
The only way to have a Google Business Messages conversation with end-users is when the end-user starts the conversation by sending you an initial message.
Unlike other channels, Google Business Messages does not use telephone numbers as identifiers for sender (from
) and recipient (to.number
), instead it uses a so called "Conversation ID" for the recipient and an "Agent ID" for the sender. A person is assigned a unique Conversation ID for each agent they start a conversation with.
These IDs are visible in the CM.com platform as the userid
under channels...Google Business Messages
.
If you send a message including both an image and some text, Google Business Messages will display these as separate messages; typically the text will be the first message.
See the Google Business Messages message with text and image example.
Quick Replies allows you to suggest quick answers for the recipient beneath your message.
The following restrictions apply for a quick reply:
Field | Required | Remarks |
---|---|---|
label | Yes | Maximum length is 25 characters. |
postbackdata | Yes | |
media | No |
With the Open URL action, your agent suggests a URL for a user to open. If an app is registered as a default handler for the URL, the app opens instead, and the icon for the action is the app's icon.
The Dial action suggests a phone number for the user to dial. When a user taps a Dial action suggestion chip, the user's default dialer app opens with the specified phone number pre-populated.
The Live agent request suggestion allows you to guide users to interact with human representatives during complex interactions or when your automation can't handle a user request. Users can request a live agent at any point in a conversation from the overflow menu. This suggestion gives agents a way to programmatically suggest interactions with human representatives based on the context of the conversation.
When users tap a Live agent request suggestion, it triggers a Live agent requested event.
When a BOT is unable to process a user message correctly it can also suggest a Live Agent Request to the user as an option.
More info can be found under Suggestions/Features.
By default, all messages send towards an enduser are considered to be coming from a bot.
By including a tag, you can specify the message comes from a different source like a human agent. The enduser will receive a notification when a human agent joins the conversation.
The following message tags are supported:
Tag | Description |
---|---|
HUMAN_AGENT | Message will be considered to be send by a human agent |
Rich cards offer a way for you to offer a richer in-conversation experience than standard text messages by integrating buttons, images and more alongside text in a single message. Rich cards can be used for many purposes, such as displaying product information or asking the message recipient to choose from a pre-determined set of options.
Rich cards can contain the following items:
Feature | Remarks |
---|---|
Media | Jpg, jpeg or png, maximum 5 MB |
Media thumbnail | Maximum 25 KB |
Title | Maximum 200 characters |
Description | Maximum 2000 characters |
A list of suggested replies and suggested actions | Maximum 4 |
A rich card can contain any or all of the listed items, but a card must contain at least media or a title to be valid. A rich card can contain a maximum of four suggested actions and suggested replies.
Cards expand vertically to fit their contents. Rich cards have a minimum height of 112 DP and a maximum height of 344 DP. If the contents of a card are not large enough to fill the minimum card height, the card expands and fills the extra height with white space.
Media in rich cards must fit one of three heights:
If the media doesn't fit the dimensions within the card given the selected height, the media preview is chosen by zooming and cropping the media.
When you need to present a user with multiple options to choose between, use a rich card carousel. Carousels string together multiple rich cards, allowing users to compare items and react to each individually.
Carousels may contain a minimum of two and a maximum of ten rich cards. Rich cards within carousels must conform to general rich card requirements for content and height.
Since Google Business Messages is used for 2-way communication (chat) it is important to also implement an Inbound flow. You can find more information about how to do this using our API documentation of the Inbound webhook. Note that for Google Business Messages you need to set up your webhook API in the Channels app, not in the Gateway app.
The example below will send a simple text-only Google Business Messages message.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"allowedChannels": ["Google Business Messages"],
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
}
}
]
}
}
In the example below we send a simple rich content message that contains both text and an image that Google Business Messages will display as two separate messages. An explanation on how to send rich content messages in general can be found in the rich content description.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}
]
}
}
In the example below we send a simple rich content message that contains elements that Google Business Messages will display as an open url action. An explanation on how to send rich content messages in general can be found in the rich content description.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"suggestions": [
{
"action": "OPENURL",
"label": "Visit CM.com",
"url": "https://www.cm.com/",
"postbackdata": "visit-cm"
}
]
}
]
}
}
]
}
}
In the example below we send a Live Agent Request suggestion to the user. This must/can only be send as BOT to the user.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"type": "auto",
"content": "Fallback text"
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"text": "Do you want to speak with a live agent?",
"suggestions": [
{
"action": "Reply",
"postbackdata": "HUMAN_AGENT"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions. An explanation on reply suggestions can be found under Suggestions/Features under Rich Content
NOTE: Google Business Messages only supports suggestions with
"action": "Reply"
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"text": "Hi, what can I do for you?",
"suggestions": [
{
"action": "Reply",
"label": "Call me",
"postbackdata": "call-me"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "email-me"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "send-me-sms"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains elements that Google Business Messages will display as a rich card.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"header": "Contact options",
"text": "Hi, what can I do for you?",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
},
"suggestions": [
{
"action": "Reply",
"label": "Call me",
"postbackdata": "call-me"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "email-me"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "send-me-sms"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains elements that Google Business Messages will display as a rich card carousel.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"carousel": {
"cards": [
{
"header": "CM.com - Be part of it.",
"text": "Want to know more about CM.com?",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg"
},
"suggestions": [
{
"action": "REPLY",
"label": "Give me more info",
"postbackdata": "INFO"
},
{
"action": "OPENURL",
"label": "Visit CM.com",
"url": "https://www.cm.com/",
"postbackdata": "visit-cm"
}
]
},
{
"header": "CM.com - Customer Satisfaction",
"text": "17 Ways To Enhance Your Customer Satisfaction",
"media": {
"mediaName": "customer-contact-channels.png",
"mediaUri": "https://www.cm.com/cdn/web/blog/content/customer-contact-channels.png",
"mimeType": "image/png"
},
"suggestions": [
{
"action": "REPLY",
"label": "Give me more info",
"postbackdata": "INFO CCC"
},
{
"action": "OPENURL",
"label": "Visit CM.com - CCC",
"url": "https://www.cm.com/blog/17-ways-business-messaging-enhances-your-customer-satisfaction/",
"postbackdata": "visit-cm"
}
]
}
]
}
}
]
}
}
]
}
}
In the example below we send a simple text message with a message tag "HUMAN_AGENT"
applied. This tag is used to indicate this messages comes from a human agent.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Agent ID",
"to": [
{
"number": "Conversation ID"
}
],
"body": {
"type": "auto",
"content": "Fallback Text"
},
"allowedChannels": ["Google Business Messages"],
"richContent": {
"conversation": [
{
"text": "Hi, how can I help you?",
"tag": "HUMAN_AGENT"
}
]
}
}
]
}
}
Our business messaging API supports sending and receiving Telegram messages.
Feature | Support | Remarks |
---|---|---|
encryption | yes | All Telegram messages are always encrypted. Messages in Secret Chats use client-client encryption, while Cloud Chats use client-server/server-client encryption and are stored encrypted in the Telegram Cloud. |
delivery notification | no | Telegram does not support status reports. They state it in their FAQ "We don‘t have a ’delivered to device' status for messages because Telegram can run on as many devices as you want." |
text messages | yes | The maximum length of a Telegram message is 4096 characters and it must be UTF-8 encoded. |
urls in text | yes | |
media | yes | Media name attribute should end in the proper file extension. You can send more media files in one message. When sending multiple files, each file will be sent in its own Telegram message. |
media: images | yes | Maximum file size for an uploaded image with an publicly available url is 5 MB. Supported MIME types are image/jpeg, image/png, image/webp. |
media: gifs | yes | Maximum file size for an uploaded animation with an publicly available url is 20 MB. Supported MIME types are image/gif, video/mpeg without sound. |
media: video | yes | Maximum file size for an uploaded video with an publicly available url is 20 MB. Supported MIME types are video/mp4, other mime types will be send as a document. |
media: audio | yes | Maximum file size for an uploaded audio file with an publicly available url is 20 MB. Supported MIME types are audio/mpeg. |
media: document | yes | Maximum file size for an uploaded document with an publicly available url is 20 MB. |
media: sticker | yes | Maximum file size for an uploaded sticker with an publicly available url is 20 MB. Supported MIME types are image/webp, and Telegram's own stickers .TGS files. |
reply suggestions | coming soon |
Onboarding pages for telegram are in development, in the meantime you are welcome to onboard your app via your customer success manager.
Sending Telegram messages using the CM Business Messaging API also requires you to adhere to the Telegram policy.
It is allowed to have multiple bots under one CM.com account.
The only way to have a Telegram conversation with end-users is when the end-user starts the conversation by sending your bot an initial message.
If you stop using Telegram and don't come online for at least six months, your account will be deleted along with all messages, media, contacts and every other piece of data you store in the Telegram cloud. You can change the exact period after which your inactive account will self-destruct in Settings.
To be able to onboard, you need to set-up the following:
Unlike other channels, Telegram does not use telephone numbers as identifiers for sender (from) and recipient (to.number), instead it uses a so called "Chat ID" for the recipient and an "Bot ID" for the sender. A person is assigned a unique Chat ID for each bot they start a conversation with.
If you send a message including both Media and some text, Telegram will display this as one entity, always placing the text below the Media, and “joining” the two visually.
Since Telegram is used for 2-way communication (chat) it is important to also implement an Inbound flow. You can find more information about how to do this using our API documentation of the Inbound webhook. Note that for Telegram you need to set up your webhook API in the Channels app, not in the Gateway app.
The example below will send a simple text-only Telegram message.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your bot ID",
"to": [
{
"number": "Recipients Identifier"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Telegram Messenger"],
"body": {
"type": "auto",
"content": "CM.com - Be part of it."
}
}
]
}
}
In the example below we send a simple rich content message that contains both text and Media that Telegram will display as one entity. An explanation on how to send rich content messages in general can be found in the rich content description.
{
"messages": {
"authentication": {
"producttoken": "Your product token"
},
"msg": [
{
"from": "Your bot ID",
"to": [
{
"number": "Recipients Identifier"
}
],
"body": {
"content": ""
},
"allowedChannels": ["Telegram Messenger"],
"richContent": {
"conversation": [
{
"text": "CM.com - Be part of it.",
"media": {
"mediaName": "conversational-commerce.jpg",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}
]
}
}
]
}
}
An alternative for SMS, is RCS. To deliver the message also telecom operators are being used, though now you can send rich content instead of pure text messages. Unfortunately RCS is not yet available in each country. When you would be interested to learn more, and get access to resources to assist with the set-up please contact us via our RCS Business Messaging product page.
You can send text messages over RCS using the Conversation bubble just by simply adding an text object containing your message. You can also add an fallback in case your recipient is not RCS capable they will then receive an SMS message with "Fallback test"
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["RCS", "SMS"],
"richContent": {
"conversation": [{
"text": "A RCS text message"
}]
}
}]
}
}
One of the Rich features that RCS provides is the Media message, you can send an Message with an image of choice.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg"
}
}]
}
}]
}
}
Add buttons to your RCS message to suggest actions for your recipient, you can add buttons that will directly open links to your website or give suggested replies
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}],
"body": {
"type": "auto",
"content": "Fallback."
},
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"text": "We hope you like it!"
}],
"suggestions": [{
"action": "Openurl",
"label": "Go to website",
"url": "https://www.cm.com",
"postbackdata": "visit-cm"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "EMAIL"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "SMS"
}
]
}
}]
}
}
Share any location with a location action, when clicked this will open the navigation app of your user with a pin at the specified location.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}],
"body": {
"type": "auto",
"content": "Fallback."
},
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"text": "We hope you like it!"
}],
"suggestions": [{
"action": "viewLocation",
"viewLocation": {
"latitude": "51.603802",
"longitude": "4.770821",
"label": "CM HQ"
},
"label": "Open in maps"
}]
}
}]
}
}
If you want to share a quick dial button to the recipient, you can send a dial action.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}],
"body": {
"type": "auto",
"content": "Fallback."
},
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"text": "We hope you like it!"
}],
"suggestions": [{
"action": "Dial",
"label": "Call us",
"dial": {
"PhoneNumber": "+310612345"
}
}]
}
}]
}
}
Send your recipient a calender event, when clicked this will open the calendar app of the user to add a new apppointment*
*only available with some operators.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}],
"body": {
"type": "auto",
"content": "Fallback."
},
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"text": "We hope you like it!"
}],
"suggestions": [{
"action": "CreateCalendarEvent",
"label": "Add to calendar",
"calendar": {
"startTime": "2018-02-05T00:00:00",
"endTime": "2018-02-08T00:00:00",
"description": "Calendar demo",
"title": "Demo"
}
}]
}
}]
}
}
Combine media messages with action buttons to create an RichCard. You can specify the height of the media image by using 'mediaHeight'. Please note that the default media height is set to short.
Media height options are: small, medium, tall.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"from": "00316098765432",
"to": [{
"number": "00316012345678"
}],
"body": {
"type": "auto",
"content": "Fallback."
},
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"header": "CM.com wants to reach out to you.",
"text": "How do you want to be contacted?",
"media": {
"mediaName": "conversational-commerce",
"mediaUri": "https://www.cm.com/cdn/web/nl-nl/blog/conversational-commerce.jpg",
"mimeType": "image/jpeg",
"mediaHeight": "Tall"
},
"suggestions": [{
"action": "Openurl",
"label": "Go to website",
"url": "https://www.cm.com",
"postbackdata": "visit-cm"
},
{
"action": "Reply",
"label": "Email me",
"postbackdata": "EMAIL"
},
{
"action": "Reply",
"label": "Send me an sms",
"postbackdata": "SMS"
}
]
}]
}
}]
}
}
One of the biggest and unique features that RCS has to offer is the RCS Carousel message. In an RCS carousel message you can line up to ten Rich cards side by side. Each card can contain an header, text, image and button.
You can specify the height of the media image by using 'mediaHeight'. Please note that the default media height is set to short.
media height options are: small, medium, tall
Please note that when the media height is set to Tall, buttons will not be visible anymore.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback Text"
},
"to": [{
"number": "00316012345678"
}],
"from": "00316098765432",
"allowedChannels": ["RCS"],
"richContent": {
"conversation": [{
"carousel": {
"cards": [{
"header": "CM.com - Be part of it.",
"text": "Want to know more about CM.com?",
"media": {
"mediaName": "cm-tablet.jpg",
"mediaUri": "https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType": "image/jpeg",
"mediaHeight": "Medium"
},
"suggestions": [{
"action": "OPENURL",
"label": "Visit CM.com",
"url": "https://www.cm.com/",
"postbackdata": "visit-cm"
}]
},
{
"header": "CM.com - Customer Satisfaction",
"text": "17 Ways To Enhance Your Customer Satisfaction",
"media": {
"mediaName": "customer-contact-channels.png",
"mediaUri": "https://www.cm.com/cdn/web/blog/content/customer-contact-channels.png",
"mimeType": "image/png",
"mediaHeight": "Medium"
},
"suggestions": [{
"action": "OPENURL",
"label": "Visit CM.com - CCC",
"url": "https://www.cm.com/blog/17-ways-business-messaging-enhances-your-customer-satisfaction/",
"postbackdata": "visit-cm"
}]
}
]
}
}]
}
}]
}
}
Viber is growing in popularity and besides transactional messaging also offers the possibility to send marketing messages. Our platform offers you several other tools and products that you can freely use, also with Viber as communication channel. Examples here are our Analytics, Customer Contact application and Campaign tooling. Viber is secure communication via end-to-end encryption. Please be aware that Viber needs verify the legitimacy of your business and your rational for use. You can request access via our website.
Viber supports the conversation items: text and media (images only) as well as the openUrl suggestion. If you would like to send locations or date indicators you can include these in the text message and the phone will interpret those.
When you use suggestions, the last conversation item in your conversations array should be a text
conversation item. Without adhering to this restriction, your message will not be delivered.
Sending an image and text within a single conversation item is not supported, using multiple conversation items for each type is required.
{
"messages": {
"authentication": {
"productToken": "your product token"
},
"msg": [{
"body": {
"type": "auto",
"content": "Fallback text"
},
"richContent": {
"conversation": [
{
"media": {
"mediaName": "viber-example.png",
"mediaUri": "https://www.cm.com/cdn/web/viber-message-festival.png",
"mimeType": "image/png"
}
},
{
"text": "Viber message text"
}
],
"suggestions": [
{
"action": "Openurl",
"label": "Visit cm.com",
"url": "https://www.cm.com"
}
]
},
"to": [{
"number": "00316012345678"
}],
"from": "TestSender",
"allowedChannels": ["Viber"]
}]
}
}
NOTE: For now, always use API endpoint gw.cmtelecom.com
when using Viber.
The mobile push channel in the Business Messaging API is a solution for Android or iOS developers that want to send push notifications to their apps using phone numbers instead of the standard Firebase or APNS tokens or credentials. Devices without a SIM card (e.g. tablet, iPad) are also supported by using installation identifiers instead of phone numbers.
The push client consists of a library that needs to be included in your iOS and/or Android project. The library allows for receiving incoming push messages and optionally for registering an end-users phone number via an OTP.
There is a version 1 and version 2 of the push client SDK. Version 2 of the SDK supports rich features, the fact sheet below is based on V2.
When sending messages via mobile push using the Business Messaging API, the CM platform will look up the corresponding push token for the given phone number or installation identifier. If a push token is present, the push message will be send out. Our client libraries will allow you to receive them. Sending push messages by phone number also allows for a fallback to SMS.
The fact sheet below assumes you are using the SDK V2. V1 only supports simple text and data delivery.
Feature | Support | Remarks |
---|---|---|
encryption | partly | there is no end-to-end encryption; messages are sent over https to CM and pushed to FCM or APNs using SSL |
text messages | yes | messages have a maximum size of ~4Kb |
emojis in text |
yes | sending an emoji in unicode is possible |
urls in text | yes/no | In iOS the URLs are clickable after opening a push message. Android will display URLs, but they are not clickable. |
rich text | no | |
media | yes* | Media name attribute should end in the proper file extension. Only one media file is allowed per message; when sending multiple files, each file will be sent in its own Mobile Push message. When the linked media doesn't exist/can't be found, the message will not be sent at all. |
media: images | yes* | Maximum file size for an uploaded image is 10 MB. Sending very large images is not recommended, because it might take the app a while to download them. Supported MIME types are: image/jpeg, image/png. |
media: gifs | yes* | Maximum file size for an uploaded GIF is 10 MB. Sending very large GIFs is not recommended, because it might take the app a while to download them. Supported MIME type: image/gif. |
media: video | possible* | Maximum file size for an uploaded video is 50 MB. Sending very large videos is not recommended. Supported MIME types: video/mp4. Video is not supported by default in Android but you can intercept the message via the SDK to display it on your own accords within your app. |
media: audio | possible* | Maximum file size for an uploaded audio is 5 MB. Supported MIME types: audio/mpeg, audio/m4a. Audio is not supported by default in Android but you can intercept the message via the SDK to display it on your own accords within your app. |
media: document | possible* | Maximum file size for an uploaded document is 10 MB. Display is up to the client app. All common MIME types supported. For example: application/pdf. Document is not supported by default but you can intercept the message via the SDK to display it on your own accords within your app. |
reply suggestions | possible* | Maximum label length: 25 characters. OpenUrl supported by default, other suggestions you be intercepted via the SDK to display it on your own accords within your app. |
Note*: Only supported by making use of CMPush V2 SDK, not supported via SMS fallback.
Notifire is a publicly available mobile app of CM that you can use for sending push notifications if you don't have the capabilities to build your own mobile app.
If you want to make use of Notifire, you can skip the onboarding steps and go immediately to sending a message.
Onboarding is available as early access via our Channels portal. In the portal, you will be presented with an onboarding page in which you have to provide CM.com information about your mobile app such as credentials from the Google's FCM and/or Apple's APNs development environments.
To enable pushing messages to an Android app you need to add Firebase to your app and you have to add the CMPush Android library to your project.
The library itself and a detailed explanation of how to add it to your Android Project is available on the official GitHub repo for the Android library
To enable pushing messages to your iOS app you need to enable push in your app settings and you have to add the CMPush framework to your project. The framework and a detailed explanation of how to add it to your iOS Project is available on the official GitHub repo for the iOS library.
In other channels, like Twitter or WhatApp, the client applications are produced by 3rd parties. In the case of mobile push, you write your own client. Therefore, there are no 3rd party guidelines or regulations regarding messages. However, we do adhere to the general rules for sending messages using the CM platform found here: https://www.cm.com/en-gb/app/legal/cm-com/terms-and-conditions/
The costs of the OTP calls will be debited on your account at CM.
To prevent abuse, OTP calls are throttled at:
When making use of the CMPush V1 SDK, the following limitations are applicable:
Mobile Push works in a single direction, from the Business Messaging API to the end-user's phone (MT, or mobile-terminated). As the end-user has no way to respond to push messages, there is no MO (mobile-originated) traffic.
An exception are status reports (SRs). These are sent when a message is received by the app on the end user's phone and they will arrive in the status report webhook.
Before you can implement the mobile push channel in your iOS or Android apps, you should have a developer account and a project set up at Apple and/or Google.
Sending a message works in much the same way as sending an SMS message.
In the onboarding process of your mobile app, we will provide you with a unique sender id called a channel account id to use in the dedicated appkey
field.
NOTE: The channel account id is the identifier of your app within CM and should never be incorporated into webpages or open-source software where it can be exposed to 3rd parties.
The to
field can either be
The from
field is optional where you can specify the sender for a fallback SMS.
If you want to make use of Notifire, you must provide an empty UUID as your channel account id: 00000000-0000-0000-0000-000000000000
.
Mobile push is a one-way communications channel, but we do send status reports that indicate whether a message arrived in your client app.
To receive these status reports, you will need to configure an inbound flow. You can find more information about how to do this using our status report webhooks in the messaging gateway app.
The example below will send a simple text-only push message which will be send via SMS as fallback if user doesn't have your app installed.
{
"messages":{
"authentication":{
"producttoken":"Your product token"
},
"msg":[
{
"allowedChannels":[
"MobilePush",
"SMS"
],
"from":"Your sender",
"to":[
{
"number":"Recipients phone number/installation identifier"
}
],
"body":{
"type":"auto",
"content":"This is the content of my push message."
},
"appkey":"Your channel account"
}
]
}
}
{
"messages":{
"authentication":{
"producttoken":"Your product token"
},
"msg":[
{
"allowedChannels":[
"MobilePush",
"SMS"
],
"from":"Your sender",
"to":[
{
"number":"Recipients phone number/installation identifier"
}
],
"body":{
"type":"auto",
"content":"This is a message towards Notifire."
},
"appkey":"00000000-0000-0000-0000-000000000000"
}
]
}
}
In the example below we send a simple rich content message that contains both text and an image.
Only supported if your app makes use of CMPush V2 SDK.
{
"messages":{
"authentication":{
"producttoken":"Your product token"
},
"msg":[
{
"allowedChannels":[
"MobilePush"
],
"from":"Your sender",
"to":[
{
"number":"Recipients phone number/installation identifier"
}
],
"body":{
"type":"auto",
"content":"Fallback Text"
},
"richContent":{
"conversation":[
{
"text":"CM.com - Be part of it.",
"media":{
"mediaName":"cm-tablet.jpg",
"mediaUri":"https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType":"image/jpeg"
}
}
]
}
}
]
}
}
In the example below we send a rich content message that contains a text and some reply suggestions.
Only supported if your app makes use of CMPush V2 SDK.
{
"messages":{
"authentication":{
"producttoken":"Your product token"
},
"msg":[
{
"allowedChannels":[
"MobilePush"
],
"from":"Your sender",
"to":[
{
"number":"Recipients phone number/installation identifier"
}
],
"body":{
"type":"auto",
"content":"Fallback Text"
},
"richContent":{
"conversation":[
{
"text":"CM.com - Be part of it.",
"suggestions":[
{
"action":"Reply",
"label":"Call me",
"postbackdata":"CALL"
},
{
"action":"Reply",
"label":"Email me",
"postbackdata":"EMAIL"
},
{
"action":"Reply",
"label":"Send me an sms",
"postbackdata":"SMS"
}
]
}
]
}
}
]
}
}
In the example below we send a rich content message that contains elements that can be displayed as a rich card.
Only supported if your app makes use of CMPush V2 SDK.
{
"messages":{
"authentication":{
"producttoken":"Your product token"
},
"msg":[
{
"allowedChannels":[
"MobilePush"
],
"from":"Your sender",
"to":[
{
"number":"Recipients phone number/installation identifier"
}
],
"body":{
"type":"auto",
"content":"Fallback Text"
},
"richContent":{
"conversation":[
{
"header":"Contact options",
"text":"Hi, what can I do for you?",
"media":{
"mediaName":"cm-tablet.jpg",
"mediaUri":"https://www.cm.com/cdn/web/blog/featured/cm-tablet.jpg",
"mimeType":"image/jpeg"
},
"suggestions":[
{
"action":"Reply",
"label":"Call me",
"postbackdata":"call-me"
},
{
"action":"Reply",
"label":"Email me",
"postbackdata":"email-me"
},
{
"action":"Reply",
"label":"Send me an sms",
"postbackdata":"send-me-sms"
}
]
}
]
}
}
]
}
}
NOTE: Status report webhooks are available in XML format and JSON format.
Once you have sent out messages via our Business Messaging API, you might want to receive status updates in return. These status updates can inform you about: how successful a campaign has been, who has received your message, or in case of failure, when a fallback has been applied. You can view the status updates on the CM-platform's messaging log or receive those statuses in your own system via a webhook.
There are no additional cost to use either one. The Messaging platform has the option to communicate with a web server whenever a message updates its status. The status reports will be communicated using an HTTP POST request.
Note: Status reports sent towards an API/Webhook will be considered as not delivered when a non-successful response code is returned. Our services will temporarily hold the information and retry the delivery periodically for a maximum of 7 days. Status information will remain available through the Messaging Log.
You can configure your status report webhook for SMS in the 'Channels'-app. Please refer to the gateway section to configure your status reports.
You can choose to receive the status report in JSON format:
{
"messages": {
"msg": {
"received": "[CREATED_S]",
"to": "[GSM]",
"reference": "[REFERENCE]",
"status": {
"code": "[STATUS]",
"errorCode": "[STATUSDESCRIPTION]",
"errorDescription": "[STANDARDERRORTEXT]"
},
"operator": "[OPERATOR]"
}
}
}
Or in XML format:
<MESSAGES>
<MSG RECEIVED="[CREATED_S]">
<TO>[GSM]</TO>
<REFERENCE>[REFERENCE]</REFERENCE>
<STATUS>
<CODE>[STATUS]</CODE>
<ERRORCODE>[STATUSDESCRIPTION]</ERRORCODE>
<ERRORDESCRIPTION>[STANDARDERRORTEXT]</ERRORDESCRIPTION>
</STATUS>
</MSG>
</MESSAGES>
Name | Format | Description |
---|---|---|
Created | Datetime | The moment when the status report was registered on CM.com's platform |
Send | Datetime | The moment when the status report was sent to customer's/your endpoint |
To | String | The recipient of the message, such as the telephone number of the message recipient or another identifier |
Status | Integer | The code describing the current state of the message. 0 = accepted by the operator 1 = rejected by CM or operator 2 = delivered 3 = failed (message was not and will not be delivered) 4 = Read (Not for SMS, only other channels) |
Standard Error | String | The description of the error if the message is in an error-state |
Status Description | String | The description of the current state of the message |
Channel | String | The used communication method via which the status report was received – ie. sms, whatsapp, viber. |
Operator | String | The Mobile Operator of the recipient - if relevant |
Reference | String | The message reference which can be provided by the customer in the outbound message (see business messaging API) |
CustomGrouping CustomGrouping2 CustomGrouping3 |
String | The custom groupings set for this Outbound Message (MT) (see business messaging API) |
Note:
read
implies it was delivered, even if you never received a report with status delivered
. Similarly in some rare cases a status can become failed even after having received a previous status delivered. The reason for this is optimization by the various channel providers.When sending a request with an invalid part to the XML gateway, NO MESSAGES are created and the entire request is rejected. You will receive a plain text response with details why the request was rejected.
Example response of a failed XML request:
Status: 200 OK
Error: ERROR No account found for the given authentication
HTTP status | Error text | Remarks |
---|---|---|
400 | (none) | No HTTP GET or POST was used to send your request |
200 | Error: ERROR | Unknown error An unexpected error occurred. Check the provided values. Contact CM for support. |
200 | (empty) | The request was accepted |
200 | Error: ERROR No account found for the given authentication | No account found for the provided product token. |
200 | Error: ERROR Insufficient balance. | Trial accounts only: You are out of trial messages. Order new messages via your dashboard. If you are a regular prepaid customer, you will be notified that you have run out of quota in a Status Report. |
200 | Error: ERROR Message is unrouteable. | Your request could not be routed. Contact CM for support. |
200 | Error: ERROR Invalid product token. | Invalid or missing product token |
200 | Error: ERROR No FROM field found in a MSG node. | The ‘FROM’ element is missing within the ‘MSG’ element |
200 | Error: ERROR A MESSAGES node requires at least one MSG node | A MSG node within the MESSAGE node is required and is missing. |
200 | Error: ERROR No phone numbers found. Message will not be sent. | The Phone Number value for the TO element is missing |
200 | Error: ERROR Rejected: Gsm '<msisdn>' is not a number. | The value for the TO element is not a valid Phone Number |
Error code | Short description | Full description |
---|---|---|
5 | Message not delivered at third party | The message has been confirmed as undelivered but no detailed information related to the failure is known. |
7 | Message not delivered at operator because recipient has insufficient credit | Temporary - Used to indicate to the client that the message has not yet been delivered due to insufficient subscriber credit but is being retried within the network. |
8 | Message expired at third party | Temporary - Used when a message expired (could not be delivered within the life time of the message) within the operator SMSC but is not associated with a reason for failure. |
20 | Message not delivered because of a malformed request | Used when a message in its current form is undeliverable. |
21 | Message expired at operator | Temporary - Only occurs where the operator accepts the message before performing the subscriber credit check. If there is insufficient credit then the operator will retry the message until the subscriber tops up or the message expires. If the message expires and the last failure reason is related to credit then this error code will be used. |
22 | Message not delivered at operator because recipient has insufficient credit | Temporary - Only occurs where the operator performs the subscriber credit check before accepting the message and rejects messages if there are insufficient funds available. |
23 | Message not delivered because of an incorrect recipient number (invalid/blacklisted/barred) | Used when the message is undeliverable due to an incorrect / invalid / blacklisted / permanently barred Phone Number for this operator. This Phone Number should not be used again for message submissions to this operator. |
24 | Message not delivered because the recipient was unreachable | Temporary - Used when a message is undeliverable because the subscriber is temporarily absent, e.g. his/her phone is switch off, he/she cannot be located on the network. |
25 | Message not delivered at third party | Temporary - Used when the message has failed due to a temporary condition in the operator network. This could be related to the SS7 layer, SMSC or gateway. |
26 | Message not delivered because of a temporary handset issue (sim card full/memory exceeded/SME busy) | Temporary - Used when a message has failed due to a temporary phone related error, e.g. SIM card full, SME busy, memory exceeded etc. This does not mean the phone is unable to receive this type of message/content (refer to error code 27). |
27 | Message not delivered because of a permanent handset issue (unable to receive SMS) | Permanent - Used when a handset is permanently incompatible or unable to receive this type of message. |
28 | Message not delivered because submission speed is too high (throttling errors) | Used if a message fails or is rejected due to suspicion of SPAM on the operator network. This could indicate in some geographies that the operator has no record of the mandatory MO required for an MT. |
29 | Message not delivered because content is not permitted | Permanent - Used when this specific content is not permitted on the network / shortcode. |
30 | Message not delivered because the set spend limit is reached | Temporary - Used when message fails or is rejected because the subscriber has reached the predetermined spend limit for the current billing period. |
31 | Message not delivered because the recipient was suspended from premium services | Used when the Phone Number is for a valid subscriber on the operator but the message fails or is rejected because the subscriber is unable to be billed, e.g. the subscriber account is suspended (either voluntarily or involuntarily), the subscriber is not enabled for bill-tophone services, the subscriber is not eligible for bill-to-phone services, etc. |
33 | Message not delivered because of parental lock | Used when the subscriber cannot receive adult content because of a parental lock. |
34 | Message not delivered because age check failure | Permanent - Used when the subscriber cannot receive adult content because they have previously failed the age verification process. |
35 | Message not delivered because age check missing | Temporary - Used when the subscriber cannot receive adult content because they have not previously completed age verification. |
36 | Message not delivered because age check unavailable | Temporary - Used when the subscriber cannot receive adult content because a temporary communication error prevents their status being verified on the age verification platform. |
37 | Message not delivered because recipient is in national Do-Not-Call Register (for example, the Dutch SMS DienstenFilter and Chinese DnD list) | The Phone Number is on the national blacklist |
38 | Message not delivered because maximum concatenation tariff exceeded | Used when the total tariff of a concatenated message exceeds the maximum tariff per message set by the operator |
39 | Message not delivered because quota is empty | Used when a customer is out of qouta. |
40 | Message not delivered because the conversation window is closed | Message failed to send, conversation window closed. The channel specific conversation window is no longer open to send messages towards this customer. |
41 | Message not delivered because too many messages were sent from this number | Too many messages send from this number, blocked notifications or marked as spam. |
42 | Message not delivered because recipient is not capable to receive a message from this channel | Used when a recipient is not capable to receive a message from this channel. (For example, the user did not install WhatsApp). |
43 | Message not delivered because a template related error occured | Template name does not exist for this language and namespace. |
Clients can use SMPP to deliver and receive mobile terminated (MT) messages, mobile originated (MO) messages and delivery reports (DLR messages) to and from the CM SMS gateway. CM supports SMPP protocol version 3.4. If you would like to get the South African SMPP settings, please reach out to your Account Manager.
Delivery receipts are sent in the short_message field of a deliver_sm or the message_payload TLV of a data_sm PDU, as per account configuration. In both cases, the message state is available as a message_state TLV attached to the PDU as well as in the actual receipt. Use whichever is more convenient.
The following format is used:
id:IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII submit date:yyyyMMddHHmmss done date:yyyyMMddHHmmss stat:SSSSSSS err:EEE
The number and order of fields is fixed, and they are separated by a single ASCII space. It is unwise to depend on this, however; for extendibility, you should not assume any number or ordering of fields and accept arbitrary whitespace as separator.
Similarly, though sizes are specified, strings not of fixed length may vary in size -- the specified size only reflects the maximum returned size as currently implemented. In no case will the total message length exceed 255 characters, however.
Field | Size | Type | Description |
---|---|---|---|
id | 32 | string | The message ID allocated to the message by the SMSC when originally submitted. |
stat | 7 | Fixed length string | The final status of the message as specified in Table Message state values or ENROUTE for receipts of pending messages. |
submit date | 14 | Fixed length string | The time and date at which the short message was sent. Formatted: yyyyMMddHHmmss |
done date | 14 | Fixed length string | The time and date at which the short message reached its final state. Formatted: yyyyMMddHHmmss |
Message state | Final message states | Description (from SMPP standard) | CM specific description |
---|---|---|---|
DELIVERED | DELIVERD | Message is delivered to destination. | Message was delivered at the handset. |
EXPIRED | EXPIRED | Message validity period has expired. | |
DELETED | DELETED | Message has been deleted. | Not used. |
UNDELIVERABLE | UNDELIV | Message is undeliverable. | Message was not delivered at the handset. |
ACCEPTED | ACCEPTD | Message is in accepted state (i.e. has been manually read on behalf of the subscriber by customer service). | Message has been buffered at the operator network. |
UNKNOWN | UNKNOWN | Message is in an invalid state. | Not used. |
REJECTED | REJECTD | Message is in a rejected state. | Message was not accepted by the server. |
Notable differences with the example format given in the standard:
In order to use a single connection to send messages for all operators and tariffs the following proprietary TLVs are supported for both the DELIVER_SM PDUs and the SUBMIT_SM PDUs (please note that the tariff TLV is not yet used for DELIVER_SM PDUs). The "basic unit" of the tariff field is presently cents for all accounts.
Field | Size octets | Type | Description |
---|---|---|---|
Parameter tag | 2 | Integer | 0x1401 |
Length | 2 | Integer | Length of Value part |
Value | 1-7 | C-Octet string(Decimal) | MCC/MNC of operator |
Field | Size octets | Type | Description |
---|---|---|---|
Parameter tag | 2 | Integer | 0x140A |
Length | 2 | Integer | Length of Value part |
Value | 1-6 | C-Octet string(Decimal) | Tariff in basic unit |
Error Codes:
XML is only available for our SMS services.
More information can be found in our Help Center.
https://gw.cmtelecom.com/gateway.ashx
https://gw.cmtelecom.co.za/gateway.ashx
Values should be XML encoded and XML element names are in capitals. The following characters must be escaped in the XML body:
Character | Escape value |
---|---|
" | " |
' | ' |
< | < |
> | > |
& | & |
POST requires a valid XML document, UTF-8 encoded. Values should be XML encoded and XML element names are in capitals. The following characters must be escaped in the XML body:
Character | Escape value |
---|---|
" | " |
' | ' |
< | < |
> | > |
& | & |
A POST containing JSON should be sent to a different URL. JSON keys are case insensitive.
<?xml version="1.0" encoding="utf-8"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<BODY>Test message</BODY>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<TO>00447911123457</TO>
<BODY>Test message</BODY>
</MSG>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>OtherSender</FROM>
<TO>00447911123458</TO>
<TO>00447911123459</TO>
<BODY>Other Test message</BODY>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<BODY>Test message</BODY>
<REFERENCE>your_reference</REFERENCE>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<DCS>8</DCS>
<BODY>Κείμενο διαθέσιμο σε όλες τις γλώσσες</BODY>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<MINIMUMNUMBEROFMESSAGEPARTS>1</MINIMUMNUMBEROFMESSAGEPARTS>
<MAXIMUMNUMBEROFMESSAGEPARTS>8</MAXIMUMNUMBEROFMESSAGEPARTS>
<BODY TYPE="AUTO">Κείμενο διαθέσιμο σε όλες τις γλώσσες</BODY>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<MINIMUMNUMBEROFMESSAGEPARTS>1</MINIMUMNUMBEROFMESSAGEPARTS>
<MAXIMUMNUMBEROFMESSAGEPARTS>8</MAXIMUMNUMBEROFMESSAGEPARTS>
<BODY>Using these settings we can send SMS messages that contain more than 160 characters as if it is one message. Please do note that this limits the length of one message to 153 characters.</BODY>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<BODY>This message uses custom groupings</BODY>
<CUSTOMGROUPING>Campaign ABC</CUSTOMGROUPING>
<CUSTOMGROUPING2>Department XYZ</CUSTOMGROUPING2>
<CUSTOMGROUPING3>Source 123</CUSTOMGROUPING3>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>SMS</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<BODY>This message defines allowed channels</BODY>
<ALLOWEDCHANNELS>Push</ALLOWEDCHANNELS>
<APPKEY>00000000-0000-0000-0000-000000000000</APPKEY>
</MSG>
</MSG>
</MESSAGES>
<?xml version="1.0"?>
<MESSAGES>
<AUTHENTICATION>
<PRODUCTTOKEN>00000000-0000-0000-0000-000000000000</PRODUCTTOKEN>
</AUTHENTICATION>
<MSG>
<CHANNEL>Push</CHANNEL>
<FROM>SenderName</FROM>
<TO>00447911123456</TO>
<APPKEY>00000000-0000-0000-0000-000000000000</APPKEY>
<BODY>This message will be delivered as a push message.</BODY>
</MSG>
</MESSAGES>
We also maintain a gateway interface that can be addressed using a HTTP GET method. This call is limited in its features and only supports the basic parameters (FROM, TO, BODY and REFERENCE), options such as concatenation (multipart), unicode, and hybrid messaging are not supported. We advise to use our HTTP POST call if possible.
https://gw.cmtelecom.com/gateway.ashx?producttoken=00000000-0000-0000-0000-000000000000&body=Example+message+text&to=00447911123456&from=SenderName&reference=your_reference
Parameter | Description |
---|---|
PRODUCTTOKEN | Required. This is the product token that was sent to you by email. Example: 00000000-0000-0000-0000-000000000000' |
MSG | Required. The msg-tag signals the start of a message and should comprise of at least a from, to and body-tag. One HTTP-call can support up to 1000 msg elements. |
FROM | Required. This is the sender name. The maximum length is 11 alphanumerical characters or 16 digits. Example: 'CM Telecom' |
TO | Required. This is the destination mobile number. Restrictions: this value should be in international format. A single mobile number per request. Example: '00447911123456' |
BODY | Required. This is the message text. Restrictions: the maximum length is 160 characters. |
REFERENCE | Here you can include your message reference. This information will be returned in a status report so you can match the message and it's status. It should be included in the XML when posting. Restrictions: 1 - 32 alphanumeric characters and reference will not work for demo accounts. |
APPKEY | Use an APPKEY for Hybrid Messaging purposes. If an APPKEY is added to the request, the gateway will deliver according to the settings defined in the App Manager. |
HTTP status | Error text | Remarks |
---|---|---|
400 | (none) | No HTTP GET or POST was used to send your request |
200 | Error: ERROR | Unknown error An unexpected error occurred. Check the provided values. Contact CM for support. |
200 | (empty) | The request was accepted |
200 | Error: ERROR No account found for the given authentication | No account found for the provided product token. |
200 | Error: ERROR Insufficient balance. | Trial accounts only: You are out of trial messages. Order new messages via your dashboard. If you are a regular prepaid customer, you will be notified that you have run out of quota in a Status Report. |
200 | Error: ERROR Message is unrouteable. | Your request could not be routed. Contact CM for support. |
200 | Error: ERROR Parameter 'producttoken' contains an invalid value: '<producttoken>' | Invalid or missing product token |
200 | Error: ERROR No sender name provided | ‘from’ parameter is missing or its value was empty |
200 | Error: ERROR Parameter 'to' contains an invalid value: '<msisdn>' | The value for the ‘to’ parameter is not a valid Phone Number |
200 | Error: ERROR Parameter 'body' is required | The value for the ‘body’ parameter is missing |
Term | Description |
---|---|
MT | Mobile Terminated – term for a text message that is sent from your application to a handset. |
MO | Mobile Originated – term for a text message that is sent from a handset to your application. |
SMPP | Short Message Peer-to-Peer - standard telecom industry protocol for transferring short message data. |
MSISDN | Mobile Station International Subscriber Directory Number - |
RCS | Rich Communication Services - A telco level alternative to SMS featuring rich content chat options |
WABA | WhatsApp Business Account - A WhatsApp verified account for businesses |
Adding conversion details for each message helps you to keep insight into conversions using Analytics and it helps CM to improve the quality of our service. We recommended looking into using the Conversion web API.
A conversion is a confirmation that an end-user has used the contents of the sms/voice/push message that was processed by CM.
If you wish to get started with the Conversion API, click here.