Interactive Message Types
You can provide users with a rich experience by using interactive messages, like list picker, time picker, authentication, and Apple Pay.
The following rich messages use the type Interactive
:
- Quick Reply Message
- List Picker Message
- Time Picker Message
- Apple Pay Message
- Authentication Message
- iMessage App Message (Custom InteractiveData)
- Form Message
InteractiveData Common Properties
In addition to the Common Specifications, the following Dictionary keys are also used for all interactive message types.
InteractiveData Dictionary
Name | Type | Description |
---|---|---|
bid |
string | com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension |
data |
object | A collection of name and values used for interactive message types. |
InteractiveData.Data Dictionary
Name | Type | Description |
---|---|---|
images |
array | An array of image dictionaries. |
requestIdentifier |
string | REQUIRED. An identifier for the authenticate request. Recommend value: uuid. |
version |
string | REQUIRED. A numerical version number of the message extension schema. |
BaseInteractiveMessage Dictionary
Messages of type interactive
should include the interactiveData
dictionary. This
dictionary tells the Messages app which iMessage extension to use and provides the data to
pass into the extension. It also provides settings that control the visual appearance of
the interactive message.
The following Interactive Data dictionary keys are common to all interactive messages.
Properties
Name | Type | Description |
---|---|---|
bid |
string | REQUIRED. A string identifying the iMessage extension that the user interacts with while using Messages. The bid value format is: com.apple.messages.MSMessageExtensionBalloonPlugin:team-id:extension-id When using your custom interactive message, replace team-id and extension-id with your team and extension IDs. When using a Messages for Business interactive message, set team-id to 0000000000 and the extension-id to com.apple.icloud.apps.messages.business.extension . For example: com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension |
receivedMessage |
REQUIRED. A dictionary with information telling the Messages app how and what content to display the received message bubble. See ReceivedMessage Dictionary. | |
replyMessage |
REQUIRED. A dictionary with information telling the Messages app how and what to display in the reply message bubble. See ReplyMessage Dictionary. |
InteractiveResponse Dictionary
When Messages for Business or the user sends a list or time picker, the Messages app uses the InteractiveResponse dictionary to set the style, content, and images for the message bubble that the Messages app displays.
The response body is a JSON dictionary of the decoded interactive message data dictionary. The dictionary keys are listed below.
Properties
Name | Type | Description |
---|---|---|
imageSubtitle |
string | The attached image's subtitle. Limited to 512 characters. Only custom interactive messages use this key. |
imageTitle |
string | The attached image's title. Limited to 512 characters. Only custom interactive messages use this key. |
secondarySubtitle |
string | A right-aligned title. Limited to 512 characters. Only custom interactive messages use this key. |
style |
string | A style that controls the size of the view rendered by Live Layout. The default is icon. Depending if the message is a reply or response, see Reply Message Style Values or Received Message Style Values for the list of possible values. This key is optional. Default: icon Possible values: icon , small , large |
subtitle |
string | The subtitle that appears under the main title in the reply message bubble. When the user taps the reply message bubble, Messages displays the subtitle in the header. Limited to 512 characters. |
tertiarySubtitle |
string | A right-aligned subtitle. Limited to 512 characters. Only custom interactive messages use this key. |
title |
string | REQUIRED. The main title that Messages shows in the header of the reply message bubble. When the user taps the reply message bubble, Messages replaces the title with the user’s selection. Limited to 512 characters. |
InteractiveMessageData Dictionary
Only Messages for Business interactive messages uses the interactive message data dictionary. The
dictionary contains information that the Messages app passes to the feature. The contents
of the interactive message data dictionary vary based on the feature in use. For example,
when using the list picker, the dictionary includes a listPicker
key that describes each
list item. However, the interactive message data dictionary includes common fields, regardless
of the feature.
The keys for the InteractiveMessageData
dictionary can be used for all interactive messages.
Properties
Name | Type | Description |
---|---|---|
images |
array | An array of image dictionaries. For the list of keys in the image dictionary, see ImageItem dictionary. |
requestIdentifier |
string | REQUIRED. A string representing a unique identifier for the request. Messages for Business returns the ID in the response it sends back to the MSP platform. |
version |
string | REQUIRED. A string representing the version number of the message extension schema. Should be 1.0. |
ImageItem Dictionary
To send images in an interactive message, add the images array to the interactive message data dictionary. Each element in the array is a key from the image item dictionary.
An example of where you may want to include images is when sending a list picker containing products, and you want to display an image for each product in the array.
The keys to the image item dictionary used in sending interactive messages.
Properties
Name | Type | Description |
---|---|---|
data |
byte | REQUIRED. A Base64-encoded string representing the image file data. Always provide @3x images at 72 dpi. The system downscales the @3x images to generate @2x and @1x versions for use on lower-resolution devices. |
description |
string | Description of the image that the systems reads aloud to users who have VoiceOver enabled on their device. If the value is null, VoiceOver ignores the image. This key is optional. |
identifier |
string | A string containing the image identifier, which must be unique within the list of images. The list picker items and other dictionaries, such as receiveMessage and replyMessage , refer to identifier as imageIdentifier . |
Below is a listing of a sample array containing two images.
"images": [
{
"data": "base64encoded-image-file",
"description": "Optional image description",
"identifier": "1"
},
{
"data": "base64encoded-image-file",
"description": "Optional image description",
"identifier": "2"
}
]
InteractiveMessageResponse Dictionary
A list of dictionaries contained in the feature's response.
Properties
Name | Type | Description |
---|---|---|
bid |
string | REQUIRED. A string identifying the iMessage extension that the user interacts with while using the Messages app. |
data InteractiveMessageData |
A dictionary containing additional information for Messages for Business interactive messages | |
receivedMessage ReceivedMessage |
A dictionary with information telling the Messages app what content and how to display it in the received message bubble. | |
replyMessage ReplyMessage |
A dictionary with information telling the Messages app what and how to display it in the reply message bubble. |
ReceivedMessage Dictionary
Both text and custom interactive messages use the receivedMessage
field. In addition to
the key listed here, the InteractiveResponse dictionary also tells
the Messages app what and how to display it in the received message bubble.
The keys for the received message dictionary.
Name | Type | Description |
---|---|---|
imageIdentifier |
integer | REQUIRED. |
The possible string values for the received message style are:
icon
: Indicates a message bubble size of 280 x 65 points at @3x scale (840 x 195 pixels).small
: Indicates a message bubble size of 280 x 85 points at @3x scale (840 x 255 pixels).large
: Indicates a message bubble size of 280 x 210 pixels at @3x scale (840 x 630 pixels).
The image size of each imageIdentifier
reference should correspond with the style as follows:
- When style is icon, the expected @3x image size is 40 x 40 points (120 x 120 pixels).
- When style is small, the expected @3x image size is 60 x 60 points (180 x 180 pixels).
- When style is large, the expected @3x image size is 263 x 150 points (789 x 450 pixels).
Note
Always provide @3x images at 72 dpi. The system downscales @3x images to generate @2x and @1x versions for use on lower-resolution devices. For Apple Pay, only large style is supported.

ReplyMessage Dictionary
A dictionary with information telling Messages how and what to display in the reply message bubble.
When the user’s device receives a list or time picker, the Messages app uses the ReplyMessage dictionary to set the style, content, and images for the reply message bubble that the Messages app displays after the user makes their selection and returns a reply to the business. When sending an interactive message, the contents of the title and subtitle may not show up on the response if these fields are overwritten by the user.
Declaration
object ReplyMessage
The following are the replyMessage dictionary keys.
Name | Description |
---|---|
title |
The main title that the Messages app shows in the header of the reply message bubble. When the user taps the reply message bubble, the Messages app replaces the title with the user’s selection. Limited to 512 characters. |
subtitle |
The subtitle that appears under the main title in the reply message bubble. When the user taps the reply message bubble, the Messages app displays the subtitle in the header. Limited to 512 characters. |
imageTitle |
The attached image's title. Limited to 512 characters. Only custom interactive messages use this key. |
imageSubtitle |
The attached image's subtitle. Limited to 512 characters. Only custom interactive messages use this key. |
secondarySubtitle |
A right-aligned title. Limited to 512 characters. Only custom interactive messages use this key. |
tertiarySubtitle |
A right-aligned subtitle. Limited to 512 characters. Only custom interactive messages use this key. |
imageIdentifier |
The identifier for one of the images specified in interactiveData.data.images . |
style |
A style that controls the size of the view rendered by Live Layout. The default is icon. See Reply Message Style Values for the list of possible values. |
Reply Message Style Values
The possible reply message style values are:
icon
: Indicates a message bubble size of 280 x 65 points at @3x scale (840 x 195 pixels).small
: Indicates a message bubble size of 280 x 85 points at @3x scale (840 x 255 pixels).large
: Indicates a message bubble size of 280 x 210 pixels at @3x scale (840 x 630 pixels).
Sending Interactive Messages
Add the necessary dictionaries and fields in your request to send an interactive message.
To send an interactive message, use the type
value of interactive
and include the
interactiveData
field in the message JSON. The interactiveData
field is a dictionary
that describes the features to use. The dictionary also contains data that Messages passes
to the feature.
Below is a sample interactive message showing all possible values.
{
"type": "interactive",
"interactiveData": {
"appId": app-store-id,
"appName": "Name of the App",
"appIcon": A Base64-encoded string representing the app icon of the iMessage extension.
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:{team-id}:{ext-bundle-id}",
"URL": "?data=passed-to-app&data2=more-data-passed-to-app",
"sessionIdentifier": "uuid-for-this-interaction",
"receivedMessage": {
"title": "Title of bubble",
"subtitle": "Subtitle to be displayed under title",
"imageTitle": "Title of image attachment",
"imageSubtitle": "Subtitle of the image attachment.",
"secondarySubtitle": "Title that is aligned right",
"tertiarySubtitle": "Subtitle that is aligned right"
"style":"A style that controls the size of the view rendered by Live Layout"
}
"useLiveLayout": A Boolean that determines whether Messages should use Live Layout
},
"attachments": [
{
"name":"FileName",
"mimeType":"image/jpeg",
"size":file size,
"key":decryption_key,
"url":mmcs_url,
"owner": mmcs_owner,
"signature-base64":base64_encoded_signature
}
],
"sourceId": "A string that identifies the message sender",
"destinationId": "A string that identifies the message recipient",
"v": The message payload version number,
"intent": "Purpose, of the chat",
"group": "Designates the department or individuals best qualified to handle the user’s particular question or problem",
"locale": "Language in ISO 639-1",
"id": "A UUID string that identifies the message"
}
Receiving an Interactive Message
Download the interactive data when a user's reply contains a large attachment or payload.
A user’s reply to an interactive message may cause the Interactive Message Dictionaries
in the message JSON to grow beyond 10 KB in size. When this happens, the Messages for
Business service uploads the original reply message and sends a reference pointer, interactiveDataRef
,
to the original interactive data response. The keys in the interactiveDataRef
contain the
pointer to the Messaging service where the payload, or set of large assets, is contained.
As an MSP, your platform must download the reference pointer to obtain the original interactive data response from Messages for Business.

Identify a Large Interactive Data Payload
When your MSP platform receives a message of type interactive
from the Messaging service,
the MSP platform inspects the message JSON, looking for the interactiveDataRef
key (see below).
Its presence indicates that the received message is an interactive data reference and
contains a payload to download. For more details on an interactive data reference in the
message JSON payload, see Receiving Messages from the Messages for Business Service.
Below is a large interactive data payload.
{
"interactiveDataRef": {
"url": "https://p61-content.icloud.com/M58C0A1A2EB62B6E899B4F28996E8DA229E1914295299C39944B2F2CA7482AE50.C01USN00",
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"signature-base64": "gdYWyD3loBxhiXGaXSDhdDDGMeHr",
"key": "00c0d1827fdc858fe7b42421de1fb289c2ee0a9463d787ce4f118506f970bd6e38",
"signature": "81a619c81da5a01c6139219a5d20e17430c631e1eb",
"owner": "M58C0A2A1EB62B4E859B4F28996E8DA229E1914295299C39944B2F2CA7482AE50.C01USN00",
"size": 101267
},
"sourceId": "",
"destinationId": "",
"v": 1,
"type": "interactive",
"id": "80c72dab-dc7b-4750-8fae-ee7a90fae0cb"
}
Download the Encrypted Payload
When the interactiveDataRef
key is present, download the encrypted payload from Messages
for Business using the following method:
- Using the fields in the received
interactiveDataRef
key, retrieve the URL to the payload by calling the/preDownload
endpoint. See Getting an Attachment's URL. - Download the payload by sending a
GET
request to the URL returned by/preDownload
. - Decrypt the downloaded file. See Downloading and Decrypting an Attachment.
For improved performance, the interactive data reference can be reused for sending another
request with the same content. However, it has the same 30-day expiry as payloads like an
image, PDF, or other file type, as described in Sending Messages with Attachments.
Although you can reuse requests with interactiveDataRef
in the next send request, you must
immediately process responses with interactiveDataRef
and cannot reuse them.
Decode the Payload Data
The decrypted payload of the downloaded file yields encoded data. To decode the data, the
MSP platform must send a POST
request to Messages for Business’s /decodePayload
endpoint with the
request body containing the encoded data from the previous steps. The response body from
the /decodePayload
request is a decoded interactive data dictionary
, which is the
original interactive data dictionary
that the user sent. For more details, see Decoding Interactive Data Payloads.
Decoding Interactive Data Payloads
Convert an interactive data reference into an interactiveData
dictionary by calling the
/decodePayload
endpoint to decode large interactive data payloads received from
Messages for Business. The endpoint takes the encoded attachment and returns the JSON dictionary
representing the interactiveData
dictionary. For more information, see Receiving Large Interactive Data Payloads.
URL
POST https://mspgw.push.apple.com/v1/decodePayload
HTTP Headers
For more information, see the HTTP Headers in Common Specifications.
HTTP Body
Name | Description |
---|---|
data |
A binary file which is the decrypted downloaded file. For more details on the decrypted downloaded file, see Download the Encrypted Payload |
Response Codes
You can find the list of Response Codes in Common Specifications.
Sample Decode Payload
The response body is a JSON dictionary of the decoded interactiveData
dictionary. For the
list of interactiveData
dictionary keys, see BaseInteractiveMessage
.
Request
POST https://mspgw.push.apple.com/v1/decodePayload
accept: */*
accept-encoding: gzip, deflate
authorization: Bearer signed-web-token
source-id: business-id
bid: com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension
content-type: application/octet-stream
{ attachment data }
Response
HTTP/1.1 200 OK
content-type: application/json
content-length: (size of stream)
{
"interactiveData": {
"bid": "some-bid",
"URL": "url-data",
"receivedMessage": {
"title": "Interaction Title"
}
}
}
Quick Reply Message
Provide a simple way for the user to make an inline choice with a single tap during an ongoing conversation. You can have between two and five customizable choices, and the user can select only a single item.
The summaryText
should not be considered as the introduction message to the quick reply message. You should use a text message to offer the user to choose one of the items.
Quick reply is an interactive message. Due to its simple structure, it doesn't have
receivedMessage
or replyMessage
fields similar to other interactive message types.
This feature requires iOS 15.1 and macOS 12.0 or higher. For more information, see capability-list
under HTTP Headers.




Request
InteractiveData.Data Dictionary
Name | Type | Description |
---|---|---|
quick-reply |
object | REQUIRED. An array of objects. |
Data.Quick-Reply Dictionary
Name | Type | Description |
---|---|---|
summaryText |
string | REQUIRED. A summary text that will be used for device notification but also shown in the transcript after user makes a choice. |
items |
object | REQUIRED. An array of section items. |
Quick-Reply.Items Dictionary
Name | Type | Description |
---|---|---|
identifier |
string | REQUIRED. An identifier to identify the item. |
title |
string | REQUIRED. Title of the quick reply item. Max 1 line of text. |
Order of the items is based on the JSON order. Max of 5 items.
Quick Reply Webhook Event
Webhook object for quick reply.
Data.Quick-Reply Dictionary
Only 1 item is allowed to be selected
Name | Type | Description |
---|---|---|
selectedIndex |
integer | The selected item number from top order. |
selectedIdentifier |
string | The selected identifier of the item. |
items |
object | The array of section items. |
Tutorial Exercise
For more help or guidance, see our Tutorial: Sending Quick Reply.
List Picker Message
Allow the customer to choose from a list of items. A list picker displays a list of items, and information about the items—such as product name, description, and image—in the Messages app on the customer's device. The customer can choose one or more items from the list to send with a reply.
For more information on the visual design of list pickers, see Messages for Business features.

ListPickerMessage Dictionary
If the item dictionary includes the imageIdentifier
key, the list picker displays an image
that is 60 x 60 points. To ensure that the image looks its best on Retina and standard
resolution displays, send a @3x image (180 x 180 pixels). The system downscales the @3x
image to @2x and @1x for display on lower-resolution screens. For more information about
sending an image, see ImageItem dictionary.
InteractiveData.data Dictionary
A data dictionary containing fields used to describe the properties of a list picker.
Name | Type | Description |
---|---|---|
listPicker |
object | REQUIRED. An array of objects. See ListPickerSection. |
Data.ListPickerSection Dictionary
Keys for list picker section dictionary.
Name | Type | Description |
---|---|---|
listPickerItem |
object | An array of section items. See ListPickerItem. |
multipleSelection |
boolean | A Boolean that indicates whether the customer can make multiple selections within the section. Defaults to false. |
order |
integer | An integer containing the ordinal pn the sections array. |
title |
string | REQUIRED. A string field of the section title. |
ListPickerSection.ListPickerItem Dictionary
Keys for the item dictionary.
Name | Type | Description |
---|---|---|
identifier |
string | REQUIRED. A string field identifying the item. |
imageIdentifier |
string | A string field of the item title. |
order |
integer | An integer representing the ordinal position for the item. If this key is missing, the item isn't sorted within the items array. |
subtitle |
string | A string field of the item's subtitle. |
title |
string | REQUIRED. A string field of the section title. |
Time Picker Message
Allow the customer to schedule an appointment.
To let the customer pick a time slot when scheduling a meeting or appointment, send a time picker interactive message. The interactive message displays conflicts found on the customer’s local calendar so the customer can make an informed decision.
After sending the reply, the customer can tap the reply message bubble to view location information, if available. The customer can also get directions to the location or add the event to their calendar by tapping Get Directions or Add to Calendar.
For more information on the visual design of time pickers, see Messages for Business features.

Tutorial Exercise
For more help or guidance, see our Tutorial: Sending Pickers.
TimePickerMessage Dictionary
Message body for time picker.
InteractiveData.Data
A data dictionary containing fields used to describe the properties of a time picker.
Name | Type | Description |
---|---|---|
event |
object | REQUIRED. A dictionary containing specific information for the user. See Event |
Data.Event Dictionary
Keys for time picker section dictionary.
Name | Type | Description |
---|---|---|
identifier |
string | REQUIRED. A string field identifying the event that must be unique within the payload, if more than one exists. |
imageIdentifier |
string | An identifier for the image to show when the user taps a reply message bubble. The image should be a @3x image sized at 375 x 208 points (that is, 1125 x 624 pixels). |
location |
A dictionary describing a location. For the list of location dictionary keys, see LocationItem dictionary. | |
timeslots |
array | An array of time slots. For the list of time slot dictionary keys, see TimeItem dictionary. |
timezoneOffset |
integer | An integer representing the number of minutes from GMT, specifying the timezone of the event’s location. If not set, times are shown according to the customer’s current time zone. If set, the times are shown according to the event’s time zone, regardless of the customer’s location. |
title |
string | A string field of the event title. |
EventItem.LocationItem Dictionary
The keys for the location dictionary used in sending a time picker.
Name | Type | Description |
---|---|---|
latitude |
double | A double representing the latitude of the location. |
longitude |
double | A double representing the longitude of the location. |
radius |
double | A double representing the location radius, in meters. Messages for Business ignores this field when latitude and longitude are missing or empty. |
title |
string | A string field of the location title. |
Location.TimeItem Dictionary
The time item dictionary keys used in sending a time picker.
Name | Type | Description |
---|---|---|
duration |
integer | REQUIRED. An integer representing the duration of the time slot, in seconds. |
identifier |
string | REQUIRED. A string field identifying the time item that must be unique within the payload, if more than one exists. |
startTime |
string | REQUIRED. A UTC date string, represented by a valid date in ISO-8601 format and specified as absolute GMT +0000 date; for example, 2017-05-26T08:27:55+00:00, 2017-05-26T08:27:55+0000, or 2017-05-26T08:27:55Z. The timezoneOffset , from the EventItem dictionary, determines whether the startTime is in a specific time zone or in the customer's current time zone. |
Tutorial Exercise
For more help or guidance, see our Tutorial: Sending Pickers.
Apple Pay Message
Provide an easy and secure way for customers to buy goods and services through Messages for Business using Apple Pay. When a business asks for payment from a customer who is purchasing goods and services through Messages for Business, the customer can use Apple Pay to make the payment.
To learn more about Apple Pay, see Apple Pay for Developers.

ApplePayMessage Dictionary
Add these keys to the message body of the Apply Pay payment requests in addition to the InteractiveMessageData dictionary keys.
Properties
Name | Type | Description |
---|---|---|
InteractiveData |
object | REQUIRED. Fields that contain all the data needed to submit an Apple Pay payment request. See Sending an Apple Pay Payment Request. |
ApplePay.InteractiveData Dictionary
Name | Type | Description |
---|---|---|
receivedMessage |
object | REQUIRED. Contains fields giving the specifics of an Apple Pay request |
InteractiveData.Data
A data dictionary containing fields used to describe the properties of a Apple Pay.
Name | Type | Description |
---|---|---|
payment | object | REQUIRED. Contains fields giving the specifics of an Apple Pay request |
Data.Payment Dictionary
Name | Type | Description |
---|---|---|
endpoints ApplePayEndpoints |
dictionary | REQUIRED. A dictionary containing the endpoints for payment processing, contact updates, and order tracking. For the list of dictionary keys, see ApplePayEndpoints dictionary. |
merchantSession ApplePayMerchantSession |
dictionary | REQUIRED. A dictionary containing the payment session provided by Apple Pay after requesting a new payment session. For more information, see Requesting an Apple Pay Payment Session. |
paymentRequest |
dictionary | REQUIRED. A dictionary with information about the payment request. For the list of dictionary keys, see ApplePayPaymentRequest dictionary. |
PaymentRequest.requiredBillingContactFields Dictionary
Use the following field names to request contact information in a payment request.
Name | Type | Description |
---|---|---|
email |
string | REQUIRED. Email address of the Apple Pay contact. |
name |
string | REQUIRED. Full name of the Apple Pay contact. |
phone |
string | REQUIRED. Phone number of the Apple Pay contact. |
phoneticName |
string | REQUIRED. Phonetic spelling of the Apple Pay contact. |
post |
string | REQUIRED. Postal address of the Apple Pay contact. |
Payment.ApplePayEndpoints Dictionary
The endpoints dictionary contains a list of URLs that Apple Pay calls during the payment
process. Apple Pay requires the paymentGatewayUrl
endpoint for use in asking the payment
provider to process the payment; all other endpoints are optional.
Name | Type | Description |
---|---|---|
fallbackUrl |
string | A URL that opens in a web browser so the customer can complete the purchase if their device is unable to make payments using Apple Pay. |
orderTrackingUrl |
string | Called by Messages for Business after completing the order; provides you with an opportunity to update the order information in your system. For more information, see Tracking Orders. |
paymentGatewayUrl |
string | REQUIRED. Called by Apple Pay to process the payment through the payment provider. The URL should match the URL in the initiativeContext field of the payment session. For more information, see Processing Payment Requests. |
paymentMethodUpdateUrl |
string | Called by Apple Pay when the customer changes the payment method. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Payment Methods. |
shippingContactUpdateUrl |
string | Called by Apple Pay when the customer changes their shipping address information. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Shipping Contacts. |
shippingMethodUpdateUrl |
string | Called by Apple Pay when the customer changes the shipping method. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Shipping Methods. |
PaymentRequest.ApplePay Dictionary
Keys for Apple Pay dictionary. The applePay
dictionary provides Apple Pay configuration to Messages for Business.
Name | Type | Description |
---|---|---|
merchantCapabilities applePay.MerchantCapabilities ](type-interactive.md#applePay.MerchantCapabilities) |
An array of payment capabilities supported by the merchant. The array must include supports3DS , and may optionally include supportsCredit , supportsDebit , and supportsEMV . For more information, see [merchantCapabilities . |
|
merchantIdentifier |
string | REQUIRED. A unique identifier that represents a merchant for Apple Pay. |
supportedNetworks applePay.SupportedNetworks ](type-interactive.md#applePay.SupportedNetworksc') |
An array of payment networks supported by the merchant. The array must include one or more of the following values: amex , discover , jcb , masterCard , privateLabel , or visa . For more information, see [supportedNetworks . |
ApplePay.MerchantCapabilities Dictionary
An array of payment capabilities supported by the merchant.
object applePay.MerchantCapabilities
ApplePay.SupportedNetworks Dictionary
An array of payment networks supported by the merchant.
object applePay.SupportedNetworks
ApplePay.lineItems Dictionary
A set of line items that explain recurring payments and additional charges and discounts.
Name | Type | Description |
---|---|---|
amount |
string | REQUIRED. The monetary amount of the line item. |
label |
string | REQUIRED. A short, localized description of the line item. |
type |
string | A value that indicates whether the line item is final or pending. |
The applePay
dictionary provides Apple Pay configuration to Messages for Business.
Payment.MerchantSession Dictionary
A unique token representing a transaction between a customer and merchant.
Name | Type | Description |
---|---|---|
displayName |
string | REQUIRED. The canonical name for your store, suitable for display and consisting of 64 or fewer UTF-8 characters. Do not localize the name. |
epochTimestamp |
string | REQUIRED. The time representation in number of seconds that have elapsed since 00:00:00 UTC, Thursday, January 1, 1970. |
expiresAt |
string | REQUIRED. The exipiration time representation in number of seconds that have elapsed since 00:00:00 UTC, Thursday, January 1, 1970. |
initiative |
string | REQUIRED. A predefined value that identifies the e-commerce application making the request. |
initiativeContext |
string | REQUIRED. A value you provide based on the initiative. The values for initiative and initiativeContext depend on the kind of application you're building. For Messages for Business, use "messaging" for the initiative parameter. For the initiativeContext parameter, pass your payment gateway URL. See Processing Payment Requests for more information. |
merchantIdentifier |
string | REQUIRED. A unique identifier that represents a merchant for Apple Pay. |
merchantSessionIdentifier |
string | REQUIRED. A unique identifier that represents a merchant's session for Apple Pay. |
nonce |
binary | A single-use string that checks the integrity of the interaction. |
signature |
binary | A hash of the public key used to sign the interactions. |
The Apple Pay Server generates a unique token, called ApplePayMerchantSession
, that represents a transaction between a customer and a merchant. The ApplePayMerchantSession
token allows an update, such as a change of shipping charges or refunding an item, and captures it as a single financial transaction within Apple Pay. For more information, see Requesting an Apple Pay Payment Session.
PaymentRequest Dictionary
Keys for the paymentRequest dictionary.
PaymentRequest.supportedCountries Dictionary
An array of countries or regions to support.
object paymentRequest.supportedCountries
List each country or region with its ISO country code. This key is optional.
PaymentRequest.shippingMethodItem Dictionary
The itemized shipping method for delivering physical goods.
Name | Type | Description |
---|---|---|
amount |
string | REQUIRED. The nonnegative cost associated with this shipping method. |
detail |
string | REQUIRED. Additional description of the shipping method. |
identifier |
string | REQUIRED. A client-defined value used to identify this shipping method. |
label |
string | REQUIRED. A short description of the shipping method. |
For more information, see ApplePayShippingMethod
.
Processing Payment Requests
If you support Apple Pay payment requests, you need to obtain the Apple Pay payment token from the customer's device. To receive this token, implement the payment gateway endpoint. Apple Pays calls this endpoint to send you the token and ask that you process the transaction. The URL to the endpoint must match the value in the paymentGatewayUrl field defined in the ApplePayEndpoints dictionary. For more information, see Sending an Apple Pay Payment Request.
Request
POST https://msp.example.com/paymentGateway
Parameters
The request body is a JSON dictionary with the following keys.
Key | Description |
---|---|
payment |
A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary. |
requestIdentifier |
An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform. |
version |
The version number of the message extension schema; the version should be 1.0. |
Note
The
v: 1
key-value pair and theversion: 1.0
pair both indicate version numbers.The
v
indicates the version of the REST API that corresponds to the endpoint version athttps://mspgw.push.apple.com/v1
.The
version
inside of the interactive message indicates the version of the requested list picker implementation. Currently, both have only a single version. Apple architected the system to increase the list picker and other interactive message components as a higher number than the underlying API.Also the
v
is an integer data type whileversion
is a string.
Payment Dictionary
Use the following payment
dictionary keys.
Key | Description |
---|---|
billingContact |
The customer's billing contact information. For more information, see billingContact . |
paymentToken |
The payment token. For more information, see Payment Token Format Reference for more information. |
shippingContact |
The customer's shipping address information. For more information, see shippingContact . |
Sample Payment Gateway Request
POST https://msp.example.com/paymentGateway
content-type: application/json
{
"requestIdentifier": "8EF748B5-3DC5-47AE-B185-65E91518D209",
"version": "1.0",
"payment": {
"billingContact": {
"phoneticFamilyName": "",
"locality": "Cupertino",
"postalCode": "95014",
"subLocality": "",
"administrativeArea": "CA",
"country": "United States",
"familyName": "Appleseed",
"addressLines": ["1 Infinite Loop"],
"givenName": "Johnny",
"phoneticGivenName": "",
"countryCode": "us"
},
"shippingContact": {
"phoneNumber": "55555555555",
"emailAddress": "user@example.com",
"subLocality": "",
"phoneticGivenName": "",
"countryCode": "us",
"phoneticFamilyName": "",
"administrativeArea": "CA",
"addressLines": ["1 Infinite Loop"],
"givenName": "",
"postalCode": "95014",
"familyName": "",
"locality": "Cupertino",
"country": "United States"
},
"shippingMethod": {
"amount": "0",
"label": "In-Store Pickup",
"detail": "Available within an hour",
"type": "Final",
"identifier": "in_store_pickup"
},
"paymentToken": {
"transactionIdentifier": "5394..00",
"paymentData": {
"version": "EC_v1",
"data": "kdHd..GQ==",
"signature": "MIAGCSqGSIb3DQEH...AAA",
"header": {
"applicationData": "94ee0..C2",
"transactionId": "d3b28af..f8",
"ephemeralPublicKey": "MFkwE..Q==",
"publicKeyHash": "dxCK..6o="
}
}
}
}
}
Response
After processing the payment, send a response with the transaction results and errors, if any. The body of the response is a JSON dictionary with the following fields:
errors
: An array ofApplePayError
types. This field is present only when the payment processing request detects errors.status
: Indicates the status of the transaction. For a list of status codes, see Apple Pay Status Codes.
Sample Payment Gateway Response
{
"status": "STATUS_SUCCESS"
}
ApplePayPaymentRequest Dictionary
Keys for the paymentRequest dictionary.
Properties
Name | Type | Description |
---|---|---|
applePay |
REQUIRED. A dictionary that describes the Apple Pay configuration. For the list of dictionary keys, see [ApplePayItem](#ApplePayItem) dictionary. |
|
countryCode |
string | REQUIRED. The merchant’s two-letter ISO 3166 country code. |
currencyCode |
string | REQUIRED. The three-letter ISO 4217 currency code for the payment. |
lineItems |
string | REQUIRED. An array of line items explaining payments and additional charges. Line items are not required. However, the array cannot be empty if the lineItems key is present. For more information, see lineItems. |
requiredBillingContactFields |
The list of the customer's required billing information needed to process the transaction. For the list of possible strings, see requiredBillingContactFields. Require only the contact fields needed to process the payment. Requesting unnecessary fields adds complexity to the transaction, which can increase the chances of the customer canceling the payment request. |
|
requiredShippingContactFields |
The list of shipping or contact information required from the customer to fulfill the order. For example, if you need the customer's email or phone number, then include this key. For the list of possible strings, see requiredShippingContactFields. | |
shippingMethods |
An array that lists the available shipping methods. The Apple Pay payment sheet displays the first shipping method from the array as the default shipping method. For the list of shipping method dictionary keys, see ApplePayShippingMethod. | |
supportedCountries |
An array of countries to support. List each country with their ISO 3166 country code. | |
total |
REQUIRED. A dictionary containing the total. The total amount must be greater than zero to pass validation. The label, defined in the total dictionary, appears on the payment sheet and should be the doing-business-as name of the business. For more information, see total. |
For additional information about the payment request dictionary, see ApplePayPaymentRequest
.
ApplePayItem Dictionary
The applePay
dictionary provides Apple Pay configuration to Messages for Business.
Properties
Name | Type | Description |
---|---|---|
merchantCapabilities | An array of payment capabilities supported by the merchant. The array must include supports3DS , and may optionally include supportsCredit , supportsDebit , and supportsEMV . For more information, see merchantCapabilities. |
|
merchantIdentifier | string | REQUIRED. A unique identifier that represents a merchant for Apple Pay. |
supportedNetworks | An array of payment networks supported by the merchant. The array must include one or more of the following values: amex , discover , jcb , masterCard , privateLabel , or visa . For more information, see supportedNetworks. |
Sending an Apple Pay Payment Request
A payment request starts when a customer service agent with the business asks you to send
a payment request to a customer. You should create a data
dictionary to collect and store
information about the payment request.
The first piece of information to collect is a payment session object. To get it, ask Apple
Pay to start a new payment session (see Requesting an Apple Pay Payment Session).
Apple Pay returns a payment session object which you add to the Payment.MerchantSession
dictionary in the data
dictionary.
Next, add the ApplePayPaymentRequest
dictionary keys to the
data
dictionary. This is where you specify transaction details such as the purchase amount,
payment processing capabilities, available shipping methods, and a list of items or services
purchased. You can also request billing and shipping address information through the
ApplePayPaymentRequest
dictionary.
Finally, add the ApplePayEndpoints
dictionary keys to the
data
dictionary. This dictionary identifies the endpoints needed to process the payment
and receive any updates a customer might make before confirming the payment, such as updating
the shipping address or changing the shipping method.
After constructing the data dictionary, send it to Messages for Business as part of an interactive
message (see Sending a Custom Interactive Message).
Messages for Business forwards the payment request to the customer's device, and the customer
authorizes the payment from the Apple Pay payment sheet using Touch ID or Face ID. The device
then sends the payment information, including the encrypted Apple Pay token and any requested
customer contact information, to the paymentGatewayURL
endpoint listed in the endpoints
dictionary. After processing the payment, the merchant sends the transaction results to the
customer's device, which in turn sends the results to you to let you know the payment
request is complete.
{
"type": "interactive",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"images": [
{
"data": "base64encoded-image-file",
"identifier": "1"
}
],
"version": "1.0",
"payment": {
"endpoints": {
"fallbackUrl": "https://sams.example.com/fallback/",
"orderTrackingUrl": "https://sams.example.com/orderTrackingUrl/",
"paymentGatewayUrl": "https://sams.example.com/paymentGateway/",
"paymentMethodUpdateUrl": "https://sams.example.com/paymentMethodUpdate/",
"shippingContactUpdateUrl": "https://sams.example.com/shippingContactUpdate/",
"shippingMethodUpdateUrl": "https://sams.example.com/shippingMethodUpdate/"
},
"merchantSession": {
"epochTimestamp": 1525722894057,
"expiresAt": 1525730094057,
"merchantSessionIdentifier": "PSH40080EF4D655442D...FD",
"nonce": "fe72cd0f",
"merchantIdentifier": "302B976...8E",
"displayName": "Sam's Fish",
"signature": "308006092a864886f...00",
"initiative": "messaging",
"initiativeContext": "https://sams.example.com/paymentGateway",
"signedFields": [
"merchantIdentifier",
"merchantSessionIdentifier",
"initiative",
"initiativeContext",
"displayName",
"nonce"
]
},
"paymentRequest": {
"applePay": {
"merchantCapabilities": [
"supports3DS",
"supportsDebit",
"supportsCredit"
],
"merchantIdentifier": "merchant.com.sams.fish",
"supportedNetworks": [
"amex",
"visa",
"discover",
"masterCard"
]
},
"countryCode": "US",
"currencyCode": "USD",
"lineItems": [
{
"amount": "59.00",
"label": "Halibut",
"type": "final"
},
{
"amount": "4.99",
"label": "Shipping",
"type": "final"
}
],
"requiredBillingContactFields": [
"post"
],
"requiredShippingContactFields": [
"post",
"phone",
"email",
"name"
],
"shippingMethods": [
{
"amount": "0.00",
"detail": "Available within an hour",
"identifier": "in_store_pickup",
"label": "In-Store Pickup"
},
{
"amount": "4.99",
"detail": "5-8 Business Days",
"identifier": "flat_rate_shipping_id_2",
"label": "UPS Ground"
},
{
"amount": "29.99",
"detail": "1-3 Business Days",
"identifier": "flat_rate_shipping_id_1",
"label": "FedEx Priority Mail"
}
],
"total": {
"amount": "63.99",
"label": "Sam's Fish",
"type": "final"
}
}
},
"requestIdentifier": "8EF748B5-3DC5-47AE-B185-65E91518D209"
},
"receivedMessage": {
"imageIdentifier": "1",
"style": "large",
"subtitle": "$63.99 at Sam's Fish",
"title": "Halibut"
}
}
Updating Shipping Contacts
Receive changes that the customer makes to their shipping address by implementing the shipping contact update endpoint.
To receive shipping address changes, implement the shipping contact update endpoint.
Give the endpoint any name you like, and make sure to set the shippingContactUpdateUrl
key in the ApplePayEndpoints
dictionary to this endpoint.
For more information, see Handling Shipping Contact Updates.
Note
This endpoint must respond to the request within 30 seconds or the request times out.
Shipping Contact Request
POST https://msp.example.com/shippingContactUpdate
Parameters
The request body is a JSON dictionary with the following keys.
Key | Description |
---|---|
payment |
A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary. |
requestIdentifier |
An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform. |
version |
The version number of the message extension schema; the version should be 1.0. |
Payment Dictionary
Prior to the customer authorizing the transaction, you receive redacted shipping contact
information, which includes only the necessary data for completing transaction related tasks,
such as calculating taxes or shipping cost. For more information, see onshippingcontactselected
.
The payment dictionary has the following key.
Key | Description |
---|---|
shippingContact |
A dictionary with the customer's updated shipping address information. For more information, see shippingContact . |
Updating Payment Methods
Receive changes that the customer makes to the payment method by implementing the payment method update endpoint.
To receive changes that a customer makes to the payment method, such as changing the credit
card type, implement the payment method update endpoint. Give the endpoint any name you like,
and set the paymentMethodUpdateUrl
key in the ApplePayEndpoints
dictionary to this endpoint. For more information, see Handling Payment Method Updates.
Note
This endpoint must respond to the request within 30 seconds or the request times out.
Update Payment Method Request
POST https://msp.example.com/paymentMethodUpdate
Parameters
The request body is a JSON dictionary with the following keys.
Key | Description |
---|---|
payment |
A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary. |
requestIdentifier |
An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform. |
version |
The version number of the message extension schema; the version should be 1.0. |
Payment Dictionary
The payment dictionary has the following key.
Key | Description |
---|---|
paymentMethod |
A dictionary with payment method information. For the list of dictionary keys, see Payment Method Dictionary. |
Payment Method Dictionary
The paymentMethod dictionary has the following key.
Key | Description |
---|---|
type |
Indicates the payment method type. For more information, see ApplePayPaymentMethodType . |
Sample Request
Below is a sample update payment request.
POST https://msp.example.com/paymentMethodUpdate
content-type: application/json
{
"requestIdentifier": "8EF748B5-<truncated>9",
"version": "1.0",
"payment": {
"paymentMethod": {
"type": "credit"
}
}
}
Response
The response body is a JSON dictionary that contains the state of the payment request and indicates that the data has changed. The dictionary can contain a partial or complete payment dictionary. Following are the dictionary keys.
Note
For more information about the payment method update response, see
ApplePayPaymentMethodUpdate
.
Key | Description |
---|---|
endpoints |
A dictionary containing the endpoints for payment processing, contact updates, and order tracking. For the list of dictionary keys, see ApplePayEndpoints dictionary. |
errors |
An array of ApplePayError types, present only when the request detects errors. |
merchantSession |
The merchant session containing the payment session provided by Apple Pay (see Requesting an Apple Pay Payment Session). |
newLineItems |
An optional list of line items. For more information, see newLineItems. |
newTotal |
The new total resulting from a change in the payment method. For more information, see newTotal. |
Sample Response
Below is a sample payment method update response.
{
"newLineItems": [
{
"amount": "59.00",
"label": "Halibut",
"type": "final"
},
{
"amount": "29.99",
"label": "FedEx Priority Mail",
"type": "final"
}
],
"newTotal": {
"amount": "88.99",
"label": "Total",
"type": "final"
}
}
Updating Shipping Methods
Receive changes that the customer makes to the shipping method by implementing the shipping method update endpoint.
If you provide shippingMethods
in paymentRequest
(see ApplePayPaymentRequest
dictionary)
when sending an Apple Pay payment request, implement the shipping method update endpoint.
If the customer changes the shipping method, you receive the selected shipping method through
this endpoint.
Name the endpoint and point the shippingMethodUpdateUrl
key in the ApplePayEndpoints
dictionary to this endpoint. For more information, see Handling Shipping Method Updates.
Note
This endpoint must respond to the request within 30 seconds or the request times out.
Request
POST https://msp.example.com/shippingMethodUpdate
Parameters
The request body is a JSON dictionary with the following keys.
Key | Description |
---|---|
payment |
A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary. |
requestIdentifier |
An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform. |
version |
The version number of the message extension schema; the version should be 1.0. |
Payment Dictionary
The payment
dictionary has the following key.
Key | Description |
---|---|
shippingMethod |
The shipping method selected by the customer. For more information, see shippingMethod . |
Sample Shipping Method Update Request
POST https://msp.example.com/shippingMethodUpdate
content-type: application/json
{
"requestIdentifier": "8EF748B5-<truncated>",
"version": "1.0",
"payment": {
"shippingMethod": {
"amount": "29.99",
"detail": "1-3 Business Days",
"identifier": "flat_rate_shipping_id_1",
"label": "FedEx Priority Mail",
"type": "Final"
}
}
}
Response
The response body is a JSON dictionary that contains the state of the payment request and indicates that the data has changed. The dictionary can contain a partial or complete payment dictionary. Below are the dictionary keys.
Key | Description |
---|---|
endpoints |
A dictionary containing the endpoints for payment processing, contact updates, and order tracking. For the list of dictionary keys, see ApplePayEndpoints dictionary. |
errors |
An array of ApplePayError types, present only when the request detects errors. |
merchantSession |
The merchant session containing the payment session provided by Apple Pay (see Requesting an Apple Pay Payment Session). |
newLineItems |
An optional list of line items. For more information, see newLineItems . |
newTotal |
The new total resulting from a change in the payment method. For more information, see newTotal . |
Note
For more information about the shipping method update response, see
ApplePayShippingMethodUpdate
.
Sample Shipping Method Update Response
{
"newLineItems": [
{
"amount": "59.00",
"label": "Halibut",
"type": "final"
},
{
"amount": "29.99",
"label": "FedEx Priority Mail",
"type": "final"
}
],
"newTotal": {
"amount": "88.99",
"label": "Total",
"type": "final"
}
}
Tracking Orders
Receive final payment information by implementing the order tracking endpoint.
After processing the payment request, Messages for Business calls the order tracking endpoint
providing final payment information. To receive that information, implement this endpoint,
giving it any name you like. Make sure to set the orderTrackingUrl
key in the ApplePayEndpoints
dictionary to this endpoint.
Request
POST https://msp.example.com/orderTracking
Parameters
The request body is a JSON dictionary with the following keys.
Key | Description |
---|---|
payment |
A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary. |
requestIdentifier |
An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform. |
version |
The version number of the message extension schema; the version should be 1.0. |
Payment Dictionary
Below are the keys for the payment dictionary.
Key | Description |
---|---|
billingContact |
The customer's billing contact information. For more information, see billingContact . |
errors |
An array of ApplePayError types. This field is present only when the payment processing request detects errors. |
shippingContact |
The customer's shipping address information. For more information, see shippingContact . |
shippingMethod |
The shipping method selected by the customer. For more information, see ApplePayShippingMethodItem . |
summaryItems |
An array of ApplePayLineItem dictionaries. |
Tutorial Exercise
For more help or guidance, see our Tutorial: Exercise: Integrating Apple Pay.
Authentication Message
The new built-in Authentication flow uses the latest OAuth 2.0 Authorization Framework to allow implementation of latest authorization flows, and compatibility with OpenID Connect. The update also includes changes to improve security in the OAuth 2.0 flow.
In the new flow the device initiates the authorization flow and the business or Messaging Service Provider (MSP) is responsible to complete the authorization flow.

Requirements
You need an Apple device running iOS 16, iPadOS 16 or macOS 13 to test the new built-in Authentication flow. For more information see Apple Developer Downloads.
Sending an Authentication Message
The new authentication flow does not require private/public key generation and follows the OAuth specification to redirect the user to the ‘redirect_uri’ provided. It removes the requirement to provide the client secret on the payload, and is compatible with OpenID Connect.
Following are the responsibilities for the Business & MSP:
- The Business & MSP needs to use the
state
to verify the session and user for authentication. - The Business & MSP is responsible for retrieving the Access Token (ID Token) to complete the authentication.
URL
POST https://mspgw.push.apple.com/v1/authenticate
End Point Registration
Businesses supply authentication details about the OAuth provider, including authentication endpoint URLs, client identifier, and business information verified by Apple Business Register. Changing any of these authentication parameters requires additional verification and approval from multiple customers that own or administer the business.
Initiate Authorization Flow
Initiating the authorization flow requires sending a POST
request to the /v1/authenticate
endpoint
hosted by Messages for Business with the authentication message in the request body. You must secure
the authentication endpoint before sending a request from a business to the customer. When
the OAuth request is sent to the provider, the endpoints must present a valid Extended
Validation (EV) certificate for a successful authorization.
The authentication request is an interactive message. When composing an authentication request, include the InteractiveData Properties for New Authentication Message to describe the behavior and content of the authentication request.
You can send the New Authentication Message to a customer’s device with the auth capability announced,
which is included in the capability-list
header of the message request. Devices that
support the New Authentication Message will have the value AUTH2
in the capability-list
header.
For more information about the Authorization
header field, see Authorizing Messages.
Example of Authentication Request
Request
{
"v": 1,
"sourceId": "<sourceId>",
"destinationId": "<destinationId>",
"type": "interactive",
"locale": "en_us",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"version": "2.0",
"requestIdentifier": "f8ad656-12a0-4fc9-a28d-22d103a0ae5d",
"authenticate": {
"oauth2": {
"state": "3D138r5719ru3e1%26AQAAY+jbFom1SW+wCRR2yq3eh+k0VtLQrTRnVPYF9V2fQ5LM5c53uamshW1DYOF2d+jnENvo5c1sV+UWvjV2+rmGwJ+q2GsvPziBDsgw+Jps7YjbvqwtB+SVdLV2EJC4H0l3cVj8tMuEC0gSw3lGeRP4z+QhhPQ=",
"responseType": "code",
"scope": ["r_liteprofile"],
"redirectURI" : "https://example.com/auth/linkedin/callback"
}
}
},
"receivedMessage": {
"title": "Lets Sign In"
},
"replyMessage": {
"title": "Sign In Completed"
}
}
}
Response
200 OK
InteractiveData Properties
The New Authentication Message is an Interactive Message Type, which has the following properties. See Common Specifications for interactive messages types.
InteractiveData Dictionary
Name | Type | Description |
---|---|---|
bid |
string | REQUIRED. com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000: com.apple.icloud.apps.messages.business.extension |
data |
object | REQUIRED. A collection of name and values used for interactive message types. |
receivedMessage |
REQUIRED. A dictionary with information telling the Messages app how and what content to display the received message bubble. See ReceivedMessage. | |
replyMessage |
REQUIRED. A dictionary with information telling the Messages app how and what to display in the reply message bubble. See ReplyMessage. |
InteractiveData.Data Dictionary
Name | Type | Description |
---|---|---|
images |
array | An array of image dictionaries. |
requestIdentifier |
string | REQUIRED. An identifier for the authentication request. |
version |
string | REQUIRED. A numerical version number of the message extension schema. Set 2.0 for the New Authentication Message. |
authenticate |
object | REQUIRED. An object to construct the authorization URL. |
InteractiveData.Data.Authenticate Dictionary
Name | Type | Description |
---|---|---|
oauth2 |
object | REQUIRED. A dictionary that describes the authentication request. |
Data.Authenticate.Oauth2 Dictionary
Name | Type | Description |
---|---|---|
responseType |
string | REQUIRED. A string indicating the type of authentication request. Set code for authorization flow. |
scope |
array | REQUIRED. An array of scope items that specifies the scope of the request.This dictionary entry gives the exact fields of data that the authentication service provides to the client requesting the authentication. |
state |
string | REQUIRED. A string indicating the state of the authentication request. |
redirectURI |
string | REQUIRED. A string representing the redirect URL that the OAuth provider redirects the user. |
additionalParameters |
string | A string value that you can add on the authorization URL query parameter. |
Generating state
Value
The state
is used to prevent request forgery attacks. It is important that you create a session token that is unique to that session and constructed with a high quality random number. Use the state to link the user with the session using the OpaqueID provided on each message.
For example :
3D138r5719ru3e1%26AQAAY+jbFom1SW+wCRR2yq3eh+k0VtLQrTRnVPYF9V2fQ5LM5c53uamshW1DYOF2d+jnENvo5c1sV+UWvjV2+rmGwJ+q2GsvPziBDsgw+Jps7YjbvqwtB+SVdLV2EJC4H0l3cVj8tMuEC0gSw3lGeRP4z+QhhPQ=
The above example is created with
<Random string using cryptographic> & <OpaqueID>
Do not use a static value on the session token that an attacker could easily identify.
Using this format you can confirm the session token for anti-forgery and the OpaqueID with requestIdentifier
to link to the user.
Additional Parameters
The additionalParameters
allows to add additional query parameters to the authorization URI request. This allows specific parameters required for custom OAuth providers.
For example:
parameter1=01¶meter2=02
Complete the OAuth flow
Once the user completes the authorization, the user is redirected to the redirectURI
with the state
and authorization code to complete the OAuth 2.0 flow. The Business & MSP are responsible to complete the authentication flow to retrieve the access token or id token for the user authentication.
Note
For more details on OAuth 2.0 authorization code flow, please check the OAuth 2.0 RFC.
Finishing the New Authentication Flow
Once the OAuth flow has been completed, the Business and MSP can finish the flow by redirecting the user to the following URL scheme which closes the window and bubble. After the flow is complete, be sure to send a welcome message to the user.
URL Scheme
messages-auth://?
Query Parameters
Query Name | Parameter | Description |
---|---|---|
status |
success , failure , cancel , unknown |
REQUIRED. A string that describes the authentication status. |
error_code |
string (numeric) | A numeric string to provide reference of a specific error. |
Examples:
302 messages-auth://?status=success
302 messages-auth://?status=failure&error_code=400
Authentication Webhook Event
The authentication webhook event is sent when closing the window with status
as success
or failure
using the URL scheme.
See Finishing the New Authentication Flow for more details.
Authentication Webhook Payload Properties
InteractiveData.Data Dictionary
Name | Type | Description |
---|---|---|
requestIdentifier |
string | An identifier for the authentication request. |
version |
string | A numerical version number of the message extension schema. 2.0 for the New Authentication Message. |
authenticate |
array | An array object to construct the authorization URL. |
Data.authenticate Dictionary
Name | Type | Description |
---|---|---|
status |
string | success , failure , cancel , unknown is returned as a value, which indicates that the authentication flow was closed. |
error_code |
string | A numeric number of the error_code sent from |
Example of Authentication Webhook Event
{
"type": "interactive",
"id": "a2cb006d-8025-4f68-832f-78922518d1b9",
"v": 1,
"sourceId": "<OpaqueID>",
"destinationId": "<BusinessID>",
"locale": "en_us",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"requestIdentifier": "f8ad656-12b0-43c9-a28d-13d103a0ae5d",
"version": "2.0",
"authenticate": {
"status": "completed"
}
}
}
}
Using Password AutoFill to Authenticate Users
Provide customers with an easy solution to perform authentication on their iOS devices.
Supporting the Password AutoFill feature requires that the authorization input element annotate the autocomplete HTML attribute in the following format:
<input autocomplete=”value”>
Possible values for the autocomplete attribute are username, current-password, new-password, and one-time code. For more information about these values, see Enabling Password AutoFill on an HTML Input Element.
Note
Password AutoFill is supported in Safari 12 for iOS 12 and later, and Safari 12 for macOS 10.14 and later.
After the customer has been authorized, the system sends an OAuth response. In this step, the customer’s device is redirected to a URL that triggers a login form using an existing third party login system. For more information, see Password AutoFill.
iMessage App
Below is the iMessage app, also referred to as CustomInteractiveData
, request body. The request body is
based on InteractiveData
.
Name | Type | Description |
---|---|---|
InteractiveData |
Custom InteractiveData |
InteractiveData
The CustomInteractiveData
dictionary keys. In addition to the keys from the BaseInteractiveMessage
dictionary, the message can also include the keys from the CustomInteractiveData
dictionary.
Name | Type | Description |
---|---|---|
appIcon |
byte | REQUIRED. A Base64-encoded string representing the app icon of the iMessage app. The Messages app displays the icon when a customer's device receives a iMessageApp message that uses an iMessage extension not installed on the device. The MSP platform must include this key when sending an interactive message that uses an iMessage extension provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage extension. appIcon should be smaller than 15kb. For more information, see Sending Custom iMessage app . |
appId |
string | REQUIRED. The App Store identifier of the iMessage app. The MSP platform must include this key when sending an interactive message that uses an iMessage extension provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage extension. For more information, see Sending Custom iMessage app . |
appName |
string | REQUIRED. The name of the iMessage app. The MSP platform must include this key when sending an interactive message that uses an iMessage app provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage app. For more information, see Sending Custom iMessage apps. |
receivedMessage |
REQUIRED. A dictionary with information telling the Messages app what content and how to display it in the received message bubble. | |
replyMessage |
REQUIRED. A dictionary with information telling the Messages app what and how to display it in the reply message bubble. | |
URL |
string | REQUIRED. A URL string containing data that the Messages app sends to the iMessage app. |
useLiveLayout |
boolean | REQUIRED. A Boolean that determines whether the Messages app should use Live Layout. The default is true. Default: true |
InteractiveData.ReceivedMessage
A dictionary with information telling Messages how to display the received message bubble
and what content to include. For more information, see ReceivedMessage
.
object InteractiveData.ReceivedMessage
InteractiveData.ReplyMessage
A dictionary with information telling Messages how to display the reply message bubble and what content to include.
object InteractiveData.ReplyMessage
When the MSP platform sends a custom interactive message, the contents of the title and
subtitle may not show up on the response if the customer overwrites these fields. For more information, see ReplyMessage
.
Sending a Custom Interactive Message
Provide a unique user experience with custom interactive messages.
You can use your custom interactive message—by setting the bid
, appId
, appName
, and
appIcon
to reference your extension.
When sending a custom interactive message, use the type value of interactive
and include
the interactiveData
field in the message JSON. The interactiveData
field is a dictionary
that describes the iMessages extension to use. The dictionary also contains data that the
Messages app passes to the extension.
To control the appearance of the interactive message that Messages displays on the customer’s
device, use the receivedMessage
dictionary. Note that the Messages app ignores the imageIdentifier
and style keys when using a custom interactive message. For the list of received message
dictionary keys, see receivedMessage
dictionary.
{
"type": "interactive",
"interactiveData": {
"appId": "<app - store - id>",
"appName": "Name of the App",
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:{team-id}:{ext-bundle-id}",
"URL": "?data=passed-to-app&data2=more-data-passed-to-app",
"sessionIdentifier": "uuid-for-this-interaction",
"receivedMessage": {
"title": "Title of Bubble",
"subtitle": "Subtitle to be displayed under title",
"imageTitle": "Title of image attachment",
"imageSubtitle": "Subtitle of the image attachment.",
"secondarySubtitle": "Title that is aligned right",
"tertiarySubtitle": "Subtitle that is aligned right"
}
},
"sourceId": "",
"destinationId": "",
"v": 1,
"id": "d2f99c0e-f64c-4c3b-abbf-4a8567891ef5"
}
Tutorial Exercise
For more help or guidance, see our Tutorial: Exercise: Integrating Your iMessage App.
Form Message
Messages for Business Forms allow you to create rich, multipage interactive flows for users on iOS and iPadOS devices using a single JSON payload. This document provides the Forms specifications, along with example outbound and inbound JSON payloads.
You and your brands may already have ideas which could benefit from this type of interaction. Below are some example use cases:
- Triage flows
- CSAT Survey
- Account creation or service sign-up
Known Issues
- When a user task switches out to another app and back to Messages, the form closes. The user must tap to re-open the form. The form resets and the user has to re-enter their responses.
Because a user may have to re-open the form and re-enter their responses, we recommend you give less complicated use cases that provide quick answers through a simple triage menu. For example, if you use a technical support triage, the following choices appear:
- Did you plug it in?
- Did you turn it on?
- Is the green light flashing?
Form Specifications
The specifications below define the content of the JSON payloads used to render the Form on user devices. For JSON examples, see the Sample Request Payload and Response Payload.
Request Payload
The type of interactiveMessage
that initiates the experience is dynamic.
Field | Description |
---|---|
version |
REQUIRED. Should be 1.1 or the specified value when the feature launches. |
template |
REQUIRED. Type is 'messageForms'. Tells the client which template to use to render the view. |
data |
REQUIRED. Place all the data in this field. |
Data Dictionary Objects
Object | Description |
---|---|
splash |
Shown at the start of the form. When using splash, ensure the appropriate fields listed below display: -header : If set, it displays in bold the title on the page underneath the image. -splashtext : Use this to display the body copy for the page. -buttonTitle : REQUIRED. Text on the button shown on the page. If buttonTitle is missing then this view doesn't display and continues onto the first module. -imageIdentifier : Image to be shown at the top of the view. |
startPageIdentifier |
REQUIRED. Identifier for the starting page of the form. Must match one of the string identifiers for the configured pages. See pageIdentifier under pages below. |
private |
Defaults to false. Boolean value indicates whether to mark the response as private. If value is true, the response object contains this property (interactiveData > data > dynamic > private ). |
showSummary |
Defaults to false. If set to true then it shows the summary of all the selections made within the form. |
pages |
REQUIRED. An array of different pages to be shown in the form. Every page object has following common objects. -pageIdentifier : REQUIRED. A unique identifier, as a string, for the page being shown, that is less than 20 characters in length. Do not reuse. Ex: "firstNamePage" or "0001" . -type : REQUIRED. Use one of the following values: select , picker , datePicker , or input . -title : If set this displays the title in bold on the page. -subtitle : REQUIRED. Use this object to display the question for the page. -nextPageIdentifier : REQUIRED except for single select option page, where you specify the nextPageIdentifier within each of the item objects. If a page does not have a nextPageIdentifier set on it, the client assumes the current page to be the final page and proceeds to send or provides a summary page based on the data. This is a unique page identifier to show the next page. -submitForm : A Bool value placed on the pages to denote the end page of the form. Since multiple pages can act as an end page, this object can be set on multiple pages. |
Types of Pages
Pages is an array of page elements and there needs to be at least be one page to trigger the Form experience.
Page Type | Field | Description |
---|---|---|
select |
multipleSelection |
A Bool value that defaults to false or singleSelect . Set to true to enable multipleSelection on the page. |
items |
An array of objects defining the user experience. -title : Localized string value for display. -value : A string value of the object itself. -identifier : A unique identifier for the item. - imageIdentifier : A string containing the image identifier, from the imageItem dictionary. For more information about sending an image, see ImageItem dictionary. -nextPageIdentifier : A unique page identifier to show the next page. Set this value only when multipleSelection is not defined or set to false . |
|
picker |
pickerTitle |
A string value representing optional text shown next to the picker text field. This value defaults to an empty string. When empty the picker text field centers to the page |
selectedItemIndex |
A zero-indexed number identifying the item in the picker wheel should be selected by default. Defaults to item at index 0. | |
items |
An array of objects defining the user experience. -title : Localized string value for display. -value : A string value of the object itself. -identifier : A unique identifier for the item. |
|
datePicker |
hintText |
A string representing optional text to give the user more input context that displays below the Date field. |
options |
Dictionary containing optional values for the Date Picker element. -dateFormat : A string representing the date format on the page. Defaults to MM/dd/yyyy . Unless this property is explicitly set, all of the date properties are defined using this format. For format string specifications see: Use Format Strings to Specify Custom Formats. -startDate : A string representing the date displayed by the date picker. Defaults to current date. -maximumDate : A string representing the maximum date that a date picker can show. Defaults to current date. -minimumDate : A string representing the minimum date that a date picker can show. -labelText : A string representing the text string to be shown next to date field. Defaults to text 'Date'. |
|
input |
hintText |
A string representing optional text to give the user more input context that displays below the Input field. |
options |
Dictionary containing optional values for the input field. -regex : A string representing a JSON encoded regular expression (regex) string to limit the type of input for input field to use. An example is when you want to limit input to only have proper decimal values provide a regex string: ^\\d*\\.?\\d?\\d?$ . JSON encode all regex strings -placeholder : A text string used when there is no other text in the input text field. Default value are Required or Optional . -required : A Boolean value that defaults to false. When set to true, the next button on page is disabled until the user provides input. -inputType : A string value that defaults to singleline . Other values are multiline or singleline . -labelText : A string value representing a text label shown to identify the input field. This value defaults to an empty string. Only applies to inputType : singleline . -prefixText : A string value representing optional text shown next to the text field. This value defaults to an empty string. For example, you can set this value to denote the $ character for the field. Only applies to inputType : singleline . -maximumCharacterCount : An integer value representing the field size in characters for singleline and multiline . The field size defaults to 30 characters for singleline and 300 characters for multiline . -keyboardType : Optional string value. Type of keyboard to be shown. Possible values: -default : Default value. Specifies the default keyboard for the current input method. -asciiCapable : Specifies a keyboard that displays standard ASCII characters. -numbersAndPunctuation : Specifies the numbers and punctuation keyboard. URL : Specifies a keyboard optimized for URL entry. This keyboard type prominently features the period (.), forward slash (/) characters, and the .com string. -numberPad : Specifies a numeric keypad designed for PIN entry. This keyboard type prominently features the numbers 0 through 9. This keyboard type does not support autocapitalization. -phonePad : Specifies a keypad designed for entering telephone numbers. This keyboard type prominently features the numbers 0 through 9 and the asterisk (*) and hash tag (#) characters. -namePhonePad : Specifies a keypad designed for entering a person’s name or phone number. This keyboard type does not support auto-capitalization. -emailAddress : Specifies a keyboard optimized for entering email addresses. This keyboard type prominently features the at (@), period (.), and space characters. -decimalPad : Specifies a keyboard with numbers and a decimal point. -UIKeyboardTypeTwitter : Specifies a keyboard optimized for Twitter text entry, with easy access to the at (@) and hash tag (#) characters. -webSearch : Specifies a keyboard optimized for web search terms and URL entry. This keyboard type prominently features the space and period (.) characters. -textContentType : A string value representing the keyboard and system information about the expected semantic meaning for the content that users enter. Supported values are name , namePrefix , givenName , middleName , familyName , nameSuffix , nickname , jobTitle , organizationName , location , fullStreetAddress , streetAddressLine1 , streetAddressLine2 , addressCity , addressState , addressCityAndState , sublocality , countryName , postalCode , telephoneNumber , emailAddress , URL , creditCardNumber , username , password , newPassword , and oneTimeCode . For a full description of each supported value, see UITextContentType on Apple Developer. |
Sample Request Payload
Below is a sample request payload in JSON.
{
"type": "interactive",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"data": {
"version": "1.0",
"requestIdentifier": "da39a3ee5e6b4b0d3255 <truncated>",
"dynamic": {
"version": "1.1",
"template": "messageForms",
"data": {
"startPageIdentifier": "0",
"showSummary": true,
"splash": {
"header": "Apple Card",
"splashtext": "Kindly answer the following questions to help us dispute this transaction.",
"buttonTitle": "Continue",
"imageIdentifier": "2"
},
"pages": [{
"pageIdentifier": "0",
"type": "select",
"title": "Type of Product",
"subtitle": "Was the merchandise you received defective or not as the merchant described?",
"multipleSelection": true,
"nextPageIdentifier": "1",
"items": [{
"title": "Option 1",
"value": "option1",
"identifier": "001"
},
{
"title": "Option 2",
"value": "option2",
"identifier": "002"
},
{
"title": "Option 3",
"value": "option3",
"identifier": "003"
},
{
"title": "Option 4",
"value": "option4",
"identifier": "004"
},
{
"title": "Option 5",
"value": "option5",
"identifier": "005"
},
{
"title": "Option 6",
"value": "option6",
"identifier": "006"
}
]
},
{
"pageIdentifier": "1",
"type": "select",
"title": "Item Condition",
"subtitle": "Was the merchandise you received defective or not as the merchant described?",
"multipleSelection": false,
"items": [{
"title": "Defective",
"value": "defective",
"identifier": "101",
"nextPageIdentifier": "2"
},
{
"title": "Not as described",
"value": "notAsDescribed",
"identifier": "102",
"nextPageIdentifier": "3"
}
]
},
{
"pageIdentifier": "2",
"type": "select",
"title": "Supporting Documents",
"subtitle": "Do you have any supporting documents that demonstrate that the product quality was not sufficient?",
"multipleSelection": false,
"items": [{
"title": "Yes",
"value": "yes",
"identifier": "201",
"nextPageIdentifier": "3"
},
{
"title": "No",
"value": "no",
"identifier": "202",
"nextPageIdentifier": "3"
}
]
},
{
"pageIdentifier": "3",
"type": "picker",
"pickerTitle": "Select Your Region",
"nextPageIdentifier": "4",
"items": [{
"title": "APAC",
"value": "apac",
"identifier": "301"
},
{
"title": "EMEA",
"value": "emea",
"identifier": "302"
},
{
"title": "LATAM",
"value": "latam",
"identifier": "303"
},
{
"title": "NAM",
"value": "nam",
"identifier": "304"
}
]
},
{
"pageIdentifier": "4",
"type": "datePicker",
"title": "Retrieval Date",
"subtitle": "What date did you receive, or expect to receive the product?",
"nextPageIdentifier": "5",
"options": {
"startDate": "2020-02-12",
"maximumDate": "2020-02-13",
"minimumDate": "2020-01-01",
"dateFormat": "MM/dd/yyyy"
}
},
{
"pageIdentifier": "5",
"type": "input",
"title": "Remaining Issues",
"subtitle": "Please provide details about remaining issue",
"nextPageIdentifier": "6",
"options": {
"required": true,
"inputType": "multiline",
"maximumCharacterCount": 300,
"keyboardType": "UIKeyboardTypeEmailAddress"
}
},
{
"pageIdentifier": "6",
"type": "input",
"title": "Product name",
"subtitle": "Please provide name of the product",
"options": {
"required": false,
"inputType": "singleline",
"maximumCharacterCount": 25,
"keyboardType": "UIKeyboardTypePhonePad"
},
"submitForm": true
}
]
}
},
"images": [{
"data": "base64encoded-image-file",
"identifier": "1"
},
{
"data": "base64encoded-image-file",
"identifier": "2"
},
{
"data": "base64encoded-image-file",
"identifier": "3"
},
{
"data": "base64encoded-image-file",
"identifier": "4"
}
]
},
"receivedMessage": {
"title": "Apple Card Dispute Form",
"subtitle": "Please fill out the following dispute form.",
"style": "small",
"imageIdentifier": "1"
},
"replyMessage": {
"title": "Tap to view your response.",
"subtitle": "",
"style": "small",
"imageIdentifier": "1"
}
}
}
Response Payload
The response from the client is encapsulated within interactiveData > data > dynamic > selections object.
Each of the objects within the selections object would have the following elements.
Element | Description |
---|---|
pageIdentifier |
A unique identifier representing the page from which the response is mapped. |
title |
A string representing the title of the page |
subtitle |
A string representing the question or subtitle on the page. |
items |
An array containing all the selections made on the page. Each of the objects within the array items contains the following structure: -identifier : A unique identifier set on the individual items for each type of page selected. Except for pages with type of input and datePicker the identifier is the same value as the pageIdentifier . -type : One of the following values select , datePicker , or input that corresponds to the page’s type value. -title : The localized value of an item selected or user input. For example, the datePicker type would format the date value. For input type if any prefixLabel is provided, and the title needs to contain the prefixLabel + inputValue . -value : A string value included in the request payload. For the selections objects and for input type, this is the same value as in title (user input) . For datePicker pages, this field returns the value in UTC format: yyyy-MM-dd'T'HH:mm:ss'Z' . |
Sample Response Payload
Below is an example of a response payload in JSON.
{
"type": "interactive",
"interactiveData": {
"bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
"sessionIdentifier": "ad461c33-7534 <truncated>",
"data": {
"version": "1.0",
"dynamic": {
"template": "messageForms",
"version": "1.1",
"selections": [{
"pageIdentifier": "001",
"items": [{
"identifier": "001_03",
"value": "option03",
"type": "select",
"title": "Single 3"
}],
"subtitle": "Single Select Page",
"title": "Please Choose One Selection To Move On To The Next Page"
},
{
"pageIdentifier": "002",
"items": [{
"identifier": "002_01",
"value": "multi1",
"type": "select",
"title": "Multi 1"
},
{
"identifier": "002_03",
"value": "multi3",
"type": "select",
"title": "Multi 3"
},
{
"identifier": "002_05",
"value": "multi5",
"type": "select",
"title": "Multi 5"
}
],
"subtitle": "Multiple Selection",
"title": "Select All That Apply"
},
{
"pageIdentifier": "003",
"items": [{
"identifier": "003",
"value": "2021-03-30T07:00:00Z",
"type": "datePicker",
"title": "03/30/2021"
}],
"subtitle": "Date Picker",
"title": "Date Picker With Min/Max Date and Label Text"
},
{
"pageIdentifier": "004",
"items": [{
"identifier": "004",
"value": "50.00",
"type": "input",
"title": "$50.00"
}],
"subtitle": "Numeric Input - Currency",
"title": "With Custom Label, Prefix, Regex and Placeholder Text"
},
{
"pageIdentifier": "005",
"items": [{
"identifier": "005",
"value": "J. Appleseed",
"type": "input",
"title": "J. Appleseed"
}],
"subtitle": "Text Input - Single Line",
"title": "With Placeholder, Label and Expecting a Name"
},
{
"pageIdentifier": "006",
"items": [{
"identifier": "006",
"value": "Multi\nLine\nText\nInput",
"type": "input",
"title": "Multi\nLine\nText\nInput"
}],
"subtitle": "Text Input - Multiple Lines",
"title": "Optional Additional Comment Field"
}
]
},
"receivedMessage": {
"subtitle": "Tap to view the available pages",
"imageIdentifier": "1",
"style": "small",
"title": "Messages for Business Form"
},
"replyMessage": {
"subtitle": "Tap to review your selections",
"alternateTitle": "Messages for Business Form",
"imageIdentifier": "1",
"style": "small",
"title": "Messages for Business Form"
},
"requestIdentifier": "42bcfae9-3da6 <truncated>",
"images": [{
"identifier": "1",
"data": "base64encoded-image-file"
},
{
"identifier": "2",
"data": "base64encoded-image-file"
}
]
}
}
}