Apple Messages for Business
Using Conversation API, clients are able to integrate with Apple Messages for Business and send messages using an Apple device running iOS 11.3 and later or macOS 10.13.4 and later. Apple Messages for Business requires that the end-user (the contact) initiate the conversation first, and then the Apple Messages for Business client can reply. For configuring and connecting Apple Messages for Business with the Conversation API, follow the instructions below.
Before you start, you will need access to the following:
- An Apple device running iOS 11.3 and later or macOS 10.13.4 and later.
- A Messages for Business Account ID (MBA-ID) which can be configured and found here in the Setup Guide.
For detailed instructions on setting up the required configurations, please follow the Apple Messages for Business Getting Started guide.
Setting up Conversation API to forward callbacks to your service
You can add a webhook to your Conversation API app using the Sinch Portal or the management API.
Example snippet for creating your webhook programmatically:
{
"app_id": "{{APP}}",
"target": "{{WEBHOOK_URL}}",
"target_type": "HTTP",
"triggers": [
"EVENT_DELIVERY",
"MESSAGE_INBOUND",
"EVENT_INBOUND",
"CONVERSATION_START",
"CONVERSATION_STOP",
"UNSUPPORTED"
]
}
Finally, send a message to your Messages for Business Account (Only the customers can start the conversation with Apple Messages for Business). If everything works fine, you should receive the message you've just sent:
{
"app_id": "01F6T8M717SPW0186EC5A90Z0E",
"accepted_time": "2021-09-21T16:57:15.043890Z",
"event_time": "2021-09-21T16:57:15.198Z",
"project_id": "5b7c830f-4183-4275-14ad-13e40c98e29f",
"message": {
"id": "01F6ZMFKRHKW7E414518M9VM041G",
"direction": "TO_APP",
"contact_message": {
"text_message": {
"text": "Hello World Apple Messages for Business"
}
},
"channel_identity": {
"channel": "APPLEBC",
"identity": "3964920326927846",
"app_id": "01F6T8M717SPW0186EC5A90Z0E"
},
"conversation_id": "01F6T8NG7D6M3Y0DT0RMDP1KFE",
"contact_id": "01F6T8NG3ZWF460K28RHAM1DHW",
"metadata": "",
"accept_time": "2021-09-21T21:57:15.981939Z"
}
}
Now, with a conversation created automatically, you can use the received contact_id to send responses to this user:
{
"app_id": "01F6T8M717SPW0186EC5A90Z0E",
"recipient": {
"contact_id": "01F6T8NG3ZWF460K28RHAM1DHW"
},
"message": {
"text_message": {
"text": "Text message from Sinch Conversation API."
}
},
"channel_priority_order": [
"APPLEBC"
]
}
Now you should receive callbacks with information about the message and events.
Sending messages
Not every rich message is natively supported by the Apple Messages for Business API, so in this case they must be converted. The following sections shows the mapping between Conversation API generic message format and Apple Messages for Business messages types on mobile devices.
Text messages
Apple Messages for Business supports text messages natively.
The code to send a text message for this channel doesn't differ from the generic message and can be viewed here.
Media Messages
Apple Messages for Business supports image-based media messages as an attachment and Rich Link. Attachment fits better in media messages.
The code to send a media message for this channel doesn't differ from the generic message and can be viewed here.
Choice Messages
Choice messages are sent as a list picker if all choices are text. Otherwise, the choices are converted to plain text.
Supported:
Unsupported:
The code to send a choice message for this channel doesn't differ from the generic message and can be viewed here.
Card Messages
Card messages are converted into a list picker if all choices are text, and are converted into a rich link message if it contains a single URL choice. Otherwise, the message can be sent with an attachment containing the media, and the card content is converted to plain text.
When converted to a rich link message, it's also possible to use a video in the url
field, along with an image in the thumbnail_url
field inside the card's media_message
. This will allow the display of a video media with an image thumbnail.
Supported (as list picker):
Supported (as rich link message):
Unsupported:
The code to send a card message for this channel doesn't differ from the generic message and can be viewed here.
Carousel Messages
Carousel messages are sent as a single text message with multiple attachments. Each card's information is converted to plain text and displayed below each attachment.
Supported:
Unsupported:
The code to send a carousel message for this channel doesn't differ from the generic message and can be viewed here.
Location Messages
Location messages will be sent with an Apple Maps URL and Apple supports the preview automatically.
The code to send a location message for this channel doesn't differ from the generic message and can be viewed here.
Receiving Messages
Apple Messages for Business supports multiple types of messages: text, media share, list picker, time picker, Apple Pay payment requests, authentication messages and custom interactive messages. All of these are delivered by Conversation API with POST to MESSAGE_INBOUND
webhook.
Example Text:
{
"app_id": "01FFNDNEJN94GW1H42RAFZAXC754T1N0WB6",
"accepted_time": "2021-09-15T20:18:03.380753Z",
"event_time": "2021-09-15T20:18:01.509299Z",
"project_id": "abe06282-1141FA-f4b-4079-a5b2-dafdd5ebbbe3",
"message": {
"id": "01FFNHQVQDEHV90F7YXJ2144141FASXCZCH0EMN",
"direction": "TO_APP",
"contact_message": {
"text_message": {
"text": "Test"
}
},
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:UYAHGDSIUAGHD+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FFNDNEJN94GW1H754T1N0WB6"
},
"conversation_id": "DSADADASDAR14141",
"contact_id": "01FFNHQW9V4H7013G2FS3D1H3N",
"metadata": "",
"accept_time": "2021-09-15T20:18:03.210097Z"
},
"message_metadata": ""
}
Example Media:
{
"app_id": "01FFNDNEJN94124231VZVEAF0WB6",
"accepted_time": "2021-09-15T20:19:21.818757Z",
"event_time": "2021-09-15T20:19:17.033218Z",
"project_id": "avc414a-1f4b-4079-a5b2-dafdd5ebbbe3",
"message": {
"id": "01FFNHT9Z4512ASDCZD0ZD1",
"direction": "TO_APP",
"contact_message": {
"media_message": {
"url": "http://localhost:9098/convapi/01FFNDNEJN94GW1H754T1N0WB6/01FFNHT9GB1Z7607BVNMT71MKB.jpg",
"thumbnail_url": ""
}
},
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:AQAAY/zyinAJUdads42145+aWG4qriV5edMvc5/eLX0lRl/8EUjPaz141245ACZVijsOeQIXX803oWs24O2NQLlx2Rq+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FFNDNEJN94GW1H754T1N0WB6"
},
"conversation_id": "01FFNHQWGV41414ASFCAZS1DA0QDP21MHC",
"contact_id": "015215SAFZXCVZXZ13G2FS3D1H3N",
"metadata": "",
"accept_time": "2021-09-15T20:19:21.746253Z"
},
"message_metadata": ""
}
Example List picker:
{
"app_id": "01FF5ZM14144124ADASDCVXV1520JT5309CH",
"accepted_time": "2021-09-09T19:53:41.394072Z",
"event_time": "2021-09-09T19:53:41.301265Z",
"project_id": "afe4-1f4b-4079-a5b2-dafdd5ebbbe3",
"message": {
"id": "01FF61YZN421XZM08W0AFTX1CQB",
"direction": "TO_APP",
"contact_message": {
"choice_response_message": {
"message_id": "01FF61YAH5414AFACXC1241A1BR28BPS0KJ4",
"postback_data": "{ \"test\": 2"
}
},
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:AQAAY/zyinAJU+3oWs24O2NQLlx2Rq+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FF5ZM4515213ACAFAFGA5309CH"
},
"conversation_id": "01FF618WMZACZF412R98740ZDF",
"contact_id": "01FF618WAN6YR14CAXCZXFV4H80V30",
"metadata": "",
"accept_time": "2021-09-09T19:53:41.333086Z"
}
}
Sending Events (Typing Indicators)
You can send typing indicators to show the end-user your are typing a message or stopped typing, by using the event endpoint.
Example start typing:
{
"app_id": "{{APP_ID}}",
"recipient": {
"contact_id": "{{CONTACT_ID}}"
},
"event": {
"composing_event": {}
}
}
Example end typing:
{
"app_id": "{{APP_ID}}",
"recipient": {
"contact_id": "{{CONTACT_ID}}"
},
"event": {
"composing_end_event": {}
}
}
Receiving Events (Typing Indicators / Deleted Conversation)
You can receive typing indicators to know that the end-users are typing a message. Also, conversation deleted events are sent to notify the user deleted the conversation and asked to stop receiving messages (Next messages attempts are blocked by Apple).
Note
Make sure to subscribe your webhook to EVENT_INBOUND
trigger to receive the events below.
Example start typing:
{
"app_id": "01FFG7F1XRN8WG18CZE8CR1ZH2",
"event_time": "2021-10-07T18:11:49.718748Z",
"project_id": "37526c91-52b0-4047-9ebf-91a620316cb9",
"event": {
"direction": "TO_APP",
"contact_event": {
"composing_event": {}
},
"contact_id": "01FF618WAN6YR14CAXCZXFV4H80V30",
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:UYAHGDSIUAGHD+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FFNDNEJN94GW1H754T1N0WB6"
},
"accept_time": "2021-10-07T18:11:49.808996Z"
},
"message_metadata": ""
}
Example end typing:
{
"app_id": "01FFG7F1XRN8WG18CZE8CR1ZH2",
"event_time": "2021-10-07T18:11:49.718748Z",
"project_id": "37526c91-52b0-4047-9ebf-91a620316cb9",
"event": {
"direction": "TO_APP",
"contact_event": {
"composing_end_event": {}
},
"contact_id": "01FF618WAN6YR14CAXCZXFV4H80V30",
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:UYAHGDSIUAGHD+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FFNDNEJN94GW1H754T1N0WB6"
},
"accept_time": "2021-10-07T18:11:49.808996Z"
},
"message_metadata": ""
}
Example conversation deleted:
{
"app_id": "01FFG7F1XRN8WG18CZE8CR1ZH2",
"event_time": "2021-10-07T18:11:49.718748Z",
"project_id": "37526c91-52b0-4047-9ebf-91a620316cb9",
"event": {
"direction": "TO_APP",
"contact_event": {
"conversation_deleted_event": {}
},
"contact_id": "01FF618WAN6YR14CAXCZXFV4H80V30",
"channel_identity": {
"channel": "APPLEBC",
"identity": "urn:mbid:UYAHGDSIUAGHD+bLQdPyCiPyjpOSK8tbvklYppJ58DZhx3Z3wfl4zs=",
"app_id": "01FFNDNEJN94GW1H754T1N0WB6"
},
"accept_time": "2021-10-07T18:11:49.808996Z"
},
"message_metadata": ""
}
Explicit messages
You can send unsupported messages like TimePicker (Event), Payment Requests and others as Explicit Messages through Conversation API. For this, you need to send the following JSON with the "explicitchannelmessage" object filled with an escaped json string supported by Apple.
{
"app_id": "01F6T8M717SPW0186EC5A90Z0E",
"recipient": {
"contact_id": "01F6T8NG3ZWF460K28RHAM1DHW"
},
"message": {
"explicit_channel_message": {
"APPLEBC": "{ESCAPED-JSON-STRING}"
}
},
"channel_priority_order": [
"APPLEBC"
]
}
The examples for this "{ESCAPED-JSON-STRING}" value is below.
MTs (sent by the Sinch Business Client):
Example Apple Pay (for more information about this type of message, see Apple Documentation)
{
"type": "interactive",
"interactiveData": {
"data": {
"payment": {
"endpoints": {
"orderTrackingUrl": "{{apple_merchant_payment_gateway}}/orderTrackingUrl",
"paymentGatewayUrl": "{{apple_merchant_payment_gateway}}/paymentGateway"
},
"merchantSession": {
"epochTimestamp": 1631564878343,
"expiresAt": 1631572078343,
"merchantSessionIdentifier": "PSH7D0_516962FB55FAD8D4D893F837596083CA",
"nonce": "890e5e5b",
"merchantIdentifier": "8F8D7C5C3402DE8DF3552C151512341DAGAHGYYHVB5504E26CC53CCB6F5",
"displayName": "Sinch Store",
"signature": "signature",
"initiative": "messaging",
"initiativeContext": "{{apple_merchant_payment_gateway}}/paymentGateway",
"signedFields": [
"merchantIdentifier",
"merchantSessionIdentifier",
"initiative",
"initiativeContext",
"displayName",
"nonce"
],
"operationalAnalyticsIdentifier": "Sinch Store:8FDAGFAVAR4521B6F5",
"retries": 0
},
"paymentRequest": {
"applePay": {
"merchantIdentifier": "merchant.com.sinch.abc.test",
"merchantCapabilities": [
"supports3DS",
"supportsDebit",
"supportsCredit"
],
"supportedNetworks": [
"amex",
"visa",
"discover",
"masterCard"
]
},
"countryCode": "US",
"currencyCode": "USD",
"requiredBillingContactFields": [
"post"
],
"requiredShippingContactFields": [
"post",
"phone",
"email",
"name"
],
"shippingMethods": [
{
"identifier": "in_store_pickup",
"amount": "0.00",
"detail": "Available within an hour",
"label": "In-Store Pickup"
},
{
"identifier": "flat_rate_shipping_id_2",
"amount": "4.99",
"detail": "5-8 Business Days",
"label": "UPS Ground"
},
{
"identifier": "flat_rate_shipping_id_1",
"amount": "29.99",
"detail": "1-3 Business Days",
"label": "FedEx Priority Mail"
}
],
"lineItems": [
{
"amount": "59.00",
"label": "Halibut",
"type": "final"
},
{
"amount": "4.99",
"label": "Shipping",
"type": "final"
}
],
"total": {
"amount": "63.99",
"label": "Sam's Fish",
"type": "final"
}
}
}
},
"receivedMessage": {
"title": "Halibut",
"subtitle": "$63.99 at Sam's Fish",
"imageIdentifier": "1",
"style": "large"
}
}
}
Example List Picker:
{
"type": "interactive",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"images": [
{
"url": "https://www.google.com/logos/doodles/2021/doodle-champion-island-games-begin-6753651837108462.5-s.png",
"identifier": "1"
},
{
"url": "https://img.ibxk.com.br/2015/07/23/23170425700729.jpg",
"identifier": "2"
},
{
"url": "http://cbissn.ibict.br/images/phocagallery/galeria2/thumbs/phoca_thumb_l_image04_grd.png",
"identifier": "3"
},
{
"url": "https://s1.static.brasilescola.uol.com.br/be/conteudo/images/imagem-em-lente-convexa.jpg",
"identifier": "4"
}
],
"listPicker": {
"sections": [
{
"items": [
{
"identifier": "1",
"imageIdentifier": "1",
"order": 0,
"style": "default",
"subtitle": "Product 1 subtitle",
"title": "Product 1"
},
{
"identifier": "2",
"imageIdentifier": "2",
"order": 2,
"style": "default",
"subtitle": "Product 2 subtitle",
"title": "Product 2"
},
{
"identifier": "3",
"imageIdentifier": "3",
"order": 1,
"style": "default",
"subtitle": "Product 3 subtitle",
"title": "Product 3"
}
],
"order": 0,
"title": "First Section",
"multipleSelection": true
},
{
"items": [
{
"identifier": "4",
"imageIdentifier": "4",
"order": 0,
"style": "default",
"subtitle": "Product 4 subtitle",
"title": "Product 4"
},
{
"identifier": "2",
"imageIdentifier": "2",
"order": 0,
"style": "default",
"subtitle": "Product 5 subtitle",
"title": "Product 5"
}
],
"order": 0,
"title": "Second Section",
"multipleSelection": false
}
]
}
},
"receivedMessage": {
"imageIdentifier": "1",
"style": "icon",
"subtitle": "Received Subtitle",
"title": "Select Products"
},
"replyMessage": {
"style": "small",
"title": "Selected Reply Title"
}
}
}
Example Time Picker:
{
"type": "interactive",
"interactiveData": {
"data": {
"event": {
"identifier": "<SOME-ID>",
"location": {
"latitude": 37.7725,
"longitude": -122.4311,
"radius": 100,
"title": "Building One"
},
"timeslots": [
{
"duration": 3600,
"identifier": "<SOME-ID>",
"startTime": "2021-09-26T08:00+0000"
},
{
"duration": 3600,
"identifier": "<SOME-ID>",
"startTime": "2021-09-28T08:45+0000"
},
{
"duration": 3600,
"identifier": "<SOME-ID>",
"startTime": "2021-09-29T12:30+0000"
}
],
"timezoneOffset": 0,
"title": "Schedule an Appointment"
}
},
"receivedMessage": {
"style": "icon",
"subtitle": "We'll see you there!",
"title": "Schedule an Appointment"
},
"replyMessage": {
"style": "icon",
"title": "Your Appointment"
}
}
}
Example Rich Link:
{
"type": "richLink",
"richLinkData": {
"url": "https://www.apple.com/ipad-pro/",
"title": "iPadPro",
"assets": {
"video": {
"url": "https://images.apple.com/media/us/homepod/2018/98e6cc1a_37ec_4e69_b717_9e58c71e1937/films/expand/homepod-expand-tpl-cc-us-20180306_1280x720h.mp4",
"mimeType": "video/mp4"
},
"image": {
"url": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png",
"mimeType": "image/png"
}
}
}
}
MOs (messages sent by the end-user)
Example Apple Pay:
{
"type": "interactive",
"id": "62d806ea-507f-45f0-8134dac8-031dasfaxcc18b",
"v": 1,
"sourceId": "urn:mbid:AQAAY1540414a/LiteBmy6mrNyZB1w9Y=",
"destinationId": "9906701c-717e-46ncmj38-a1fb-504a4acd",
"locale": "en_BR",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"requestIdentifier": "b9d4c656-bf55-495e-ad8brzcxffafdc",
"receivedMessage": {
"title": "Awesome Product",
"style": "large",
"subtitle": "R$1 at Sam's Fish",
"imageIdentifier": "1"
},
"payment": {
"state": "paid",
"endpoints": {
"orderTrackingUrl": "https://3d7d-2804-1b3-6603-159d-7052-5cd3-ca5d-81a1.ngrok.io/orderTrackingUrl"
},
"merchantSession": {
"merchantIdentifier": "8F8D7C5C3402DE8DF354HDUAHIUNVCZMVHGCC53CCB6F5",
"retries": 0,
"displayName": "Sinch Store",
"initiative": "messaging",
"initiativeContext": "https://3d7d-2804-1b3-6603-159d-7052-5cd3-ca5d-81a1.ngrok.io/paymentGateway",
"expiresAt": 1631573641797,
"merchantSessionIdentifier": "PSH_68F71D530A24A31583",
"operationalAnalyticsIdentifier": "Sinch Store:4E26CC53CCB6F5",
"nonce": "2e446651",
"signature": "308006092a86",
"signedFields": [
"merchantIdentifier",
"merchantSessionIdentifier",
"initiative",
"initiativeContext",
"displayName",
"nonce"
],
"epochTimestamp": 1631566441797
},
"paymentRequest": {
"lineItems": [
{
"type": "Final",
"amount": "1",
"label": "Awesome Product"
},
{
"label": "Awesome Product",
"type": "Final",
"amount": "1"
}
],
"total": {
"amount": "1",
"label": "Awesome Product",
"type": "Final"
},
"countryCode": "BR",
"currencyCode": "BRL",
"applePay": {
"merchantCapabilities": [
"supports3DS",
"supportsDebit",
"supportsCredit"
],
"merchantIdentifier": "merchant.com.sinch.abc.test",
"supportedNetworks": [
"amex",
"visa",
"discover",
"masterCard"
]
},
"requiredBillingContactFields": [],
"shippingMethods": []
}
},
"replyMessage": {
"title": "Awesome Product",
"style": "large",
"subtitle": "Paid R$ 1 with Pay",
"imageIdentifier": "1"
},
"version": "1.0"
},
"sessionIdentifier": "a22a31bc-c3bd-5f2d-e089-53ba276dzfdaD"
}
}
Example List Picker
{
"bid":"com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data":{
"receivedMessage":{
"title":"Select Products - multiple false - 2 section",
"style":"small",
"subtitle":"Received Subtitle",
"imageIdentifier":"1"
},
"replyMessage":{
"alternateTitle":"Product 1, Product 3, and Product 4",
"title":"Product 1, Product 3, and Product 4",
"style":"small",
"imageIdentifier":"1"
},
"version":"1.0",
"listPicker":{
"sections":[
{
"multipleSelection":false,
"items":[
{
"order":0,
"imageIdentifier":"1",
"subtitle":"Product 1 subtitle",
"title":"Product 1",
"identifier":"1",
"style":"default"
},
{
"title":"Product 4",
"order":2,
"imageIdentifier":"4",
"style":"default",
"subtitle":"Product 4 subtitle",
"identifier":"4"
}
],
"title":"You Selected",
"order":0
},
{
"multipleSelection":false,
"title":"Others",
"items":[
{
"subtitle":"Product 2 subtitle",
"order":2,
"imageIdentifier":"2",
"identifier":"2",
"title":"Product 2",
"style":"default"
},
{
"imageIdentifier":"3",
"title":"Product 3",
"identifier":"3",
"style":"default",
"order":1,
"subtitle":"Product 3 subtitle"
},
{
"identifier":"2",
"style":"default",
"order":4,
"subtitle":"Product 5 subtitle",
"imageIdentifier":"2",
"title":"Product 5"
}
],
"order":1
}
]
},
"requestIdentifier":"e8d813ba-0ea7-4f2a-927e-b2cd08b52204",
"images":[
{
"identifier":"1",
"data":"hidden"
},
{
"data":"hidden",
"identifier":"2"
},
{
"identifier":"3",
"data":"hidden"
},
{
"identifier":"4",
"data":"hidden"
}
]
},
"sessionIdentifier":"02ed4474-ff06-5fcc-7209-a60fad2fd506"
}
Example Time Picker (Event):
{
"type": "interactive",
"id": "520f0497-e7e8-4d25-818c-d3192",
"v": 1,
"sourceId": "urn:mbid:AQAAY9kCUQv0=",
"destinationId": "4b4737e4-81ca1-ac1c-b31182",
"locale": "en_BR",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"replyMessage": {
"title": "26 Sep 2021 07:00",
"style": "icon",
"alternateTitle": "26 Sep 2021 07:00"
},
"receivedMessage": {
"title": "You can also schedule something using the Time Picker message",
"subtitle": "We'll see you there!",
"style": "icon"
},
"event": {
"identifier": "<SOME-ID>",
"timeslots": [
{
"startTime": "2021-09-26T10:00+0000",
"identifier": "2228e03c-6800-4e8b-a3b2-2a1cf81270c3",
"duration": 3600
}
],
"location": {
"title": "Building One",
"radius": 100,
"longitude": -122.4311,
"latitude": 37.7725
},
"title": "You can also schedule something using the Time Picker message"
},
"version": "1.0",
"requestIdentifier": "c146f7-a7f2-aa15d"
},
"sessionIdentifier": "73ca3ec4-2811-b0e1f7"
}
}