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:

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.
sessionIdentifier string sessionIdentifier is related to generic iMessage app sessions. If the interactive data in the message from MSP contains sessionIdentifier, Apple Messages for Business server will use the same sessionIdentifier in the payload to device. Otherwise, Apple will generate a random session identifier (UUID) and use it in the bp payload to device.

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 an Apple 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 Apple 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 Apple 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. Apple 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 Apple 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.

Illustration showing the layout of a message bubble that Messages displays on the user's device. The larger, top portion, displays attachments, and the image's title and subtitle. Along the bottom, the message title and subtitle are shown at left, and the secondary and tertiary subtitles are shown at right.
Message bubble layout that Messages displays on the user's device

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 Apple 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 Apple Messages for Business.

Diagram showing the download flow for a large interactive data dictionary from Messages for Business. Using metadata from the interactive data reference dictionary, call the /preDownload endpoint to get a temporary URL. Use the URL to download the encrypted file. Decrypt the file, then call the /decodePayload endpoint to retrieve the binary payload
Steps to follow when receiving a large interactive data payload

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 interactiveDataRefkey (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 Apple 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 Apple Messages for Business using the following method:

  1. 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.
  2. Download the payload by sending a GET request to the URL returned by /preDownload.
  3. 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 Apple 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 Apple 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.

A screenshot of a quick reply, as displayed on iPhone
Quick Reply message type on an iPhone
A screenshot of a quick reply response, as displayed on iPhone
Quick Reply Response message type on an iPhone
A screenshot of a quick reply, as displayed on macOS
Quick Reply message type on macOS
A screenshot of a quick reply response on macOS
Quick Reply Response message type on macOS

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 Apple Messages for Business features.

A list picker screenshot on iPhone
A list picker displaying on iPhone

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 Apple Messages for Business features.

A time picker screenshot on iPhone
A time picker displaying on iPhone

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. Apple 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 Apple Messages for Business using Apple Pay. When a business asks for payment from a customer who is purchasing goods and services through Apple Messages for Business, the customer can use Apple Pay to make the payment.

To learn more about Apple Pay, see Apple Pay for Developers.

Apple Pay screenshot on iPhone.
Apple Pay message on iPhone

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 Apple 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 Apple 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 Apple 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 Apple Messages for Business, use "messaging"for the initiative parameter. For the initiativeContextparameter, 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. Apple 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 the version: 1.0 pair both indicate version numbers.

The v indicates the version of the REST API that corresponds to the endpoint version at https://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 while version 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 of ApplePayError 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 Apple 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 Apple Messages for Business as part of an interactive message (see Sending a Custom Interactive Message). Apple 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. Apple 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. Apple 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. Apple 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, Apple 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. Apple 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.

The new authentication flow
The new authentication 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 Apple 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&parameter2=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": "success"
            }
        }
    }
}

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. 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. 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. 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

Apple Messages for Business Form allow you to create rich, multipage interactive flows for users on iOS and iPadOS devices using a single JSON payload. This document provides the Form 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). private allows the MSP to detect that the payload requires special handling, and then decide how to handle it based on the brand’s requirements.
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": "Apple Messages for Business Form"
            },
            "replyMessage": {
                "subtitle": "Tap to review your selections",
                "alternateTitle": "Apple Messages for Business Form",
                "imageIdentifier": "1",
                "style": "small",
                "title": "Apple Messages for Business Form"
            },
            "requestIdentifier": "42bcfae9-3da6 <truncated>",
            "images": [{
                    "identifier": "1",
                    "data": "base64encoded-image-file"
                },
                {
                    "identifier": "2",
                    "data": "base64encoded-image-file"
                }
            ]
        }
    }
}