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.

InteractiveData.Data Dictionary

Name Type Description
images array An array of image dictionaries.
requestIdentifier string REQUIRED. An identifier for the authenticate request. Recommend value: uuid.
version string REQUIRED. A numerical version number of the message extension schema.

BaseInteractiveMessage Dictionary

Messages of type interactive should include the interactiveData dictionary. This dictionary tells the Messages app which iMessage extension to use and provides the data to pass into the extension. It also provides settings that control the visual appearance of the interactive message.

The following Interactive Data dictionary keys are common to all interactive messages.

Properties

Name Type Description
bid string REQUIRED. A string identifying the iMessage extension that the user interacts with while using Messages. The bid value format is: com.apple.messages.MSMessageExtensionBalloonPlugin:team-id:extension-id When using your custom interactive message, replace team-id and extension-id with your team and extension IDs. When using a Messages for Business interactive message, set team-id to 0000000000 and the extension-id to com.apple.icloud.apps.messages.business.extension. For example: com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension
receivedMessage REQUIRED. A dictionary with information telling the Messages app how and what content to display the received message bubble. See ReceivedMessage Dictionary.
replyMessage REQUIRED. A dictionary with information telling the Messages app how and what to display in the reply message bubble. See ReplyMessage Dictionary.

InteractiveResponse Dictionary

When Messages for Business or the user sends a list or time picker, the Messages app uses the InteractiveResponse dictionary to set the style, content, and images for the message bubble that the Messages app displays.

The response body is a JSON dictionary of the decoded interactive message data dictionary. The dictionary keys are listed below.

Properties

Name Type Description
imageSubtitle string The attached image's subtitle. Limited to 512 characters. Only custom interactive messages use this key.
imageTitle string The attached image's title. Limited to 512 characters. Only custom interactive messages use this key.
secondarySubtitle string A right-aligned title. Limited to 512 characters. Only custom interactive messages use this key.
style string A style that controls the size of the view rendered by Live Layout. The default is icon. Depending if the message is a reply or response, see Reply Message Style Values or Received Message Style Values for the list of possible values. This key is optional. Default: icon Possible values: icon, small, large
subtitle string The subtitle that appears under the main title in the reply message bubble. When the user taps the reply message bubble, Messages displays the subtitle in the header. Limited to 512 characters.
tertiarySubtitle string A right-aligned subtitle. Limited to 512 characters. Only custom interactive messages use this key.
title string REQUIRED. The main title that Messages shows in the header of the reply message bubble. When the user taps the reply message bubble, Messages replaces the title with the user’s selection. Limited to 512 characters.

InteractiveMessageData Dictionary

Only Messages for Business interactive messages uses the interactive message data dictionary. The dictionary contains information that the Messages app passes to the feature. The contents of the interactive message data dictionary vary based on the feature in use. For example, when using the list picker, the dictionary includes a listPicker key that describes each list item. However, the interactive message data dictionary includes common fields, regardless of the feature.

The keys for the InteractiveMessageData dictionary can be used for all interactive messages.

Properties

Name Type Description
images array An array of image dictionaries. For the list of keys in the image dictionary, see ImageItem dictionary.
requestIdentifier string REQUIRED. A string representing a unique identifier for the request. Messages for Business returns the ID in the response it sends back to the MSP platform.
version string REQUIRED. A string representing the version number of the message extension schema. Should be 1.0.

ImageItem Dictionary

To send images in an interactive message, add the images array to the interactive message data dictionary. Each element in the array is a key from the image item dictionary.

An example of where you may want to include images is when sending a list picker containing products, and you want to display an image for each product in the array.

The keys to the image item dictionary used in sending interactive messages.

Properties

Name Type Description
data byte REQUIRED. A Base64-encoded string representing the image file data. Always provide @3x images at 72 dpi. The system downscales the @3x images to generate @2x and @1x versions for use on lower-resolution devices.
description string Description of the image that the systems reads aloud to users who have VoiceOver enabled on their device. If the value is null, VoiceOver ignores the image. This key is optional.
identifier string A string containing the image identifier, which must be unique within the list of images. The list picker items and other dictionaries, such as receiveMessage and replyMessage, refer to identifier as imageIdentifier.

Below is a listing of a sample array containing two images.

"images": [
  {
    "data": "base64encoded-image-file",
    "description": "Optional image description",
    "identifier": "1"
  },
  {
    "data": "base64encoded-image-file",
    "description": "Optional image description",
    "identifier": "2"
  }
]

InteractiveMessageResponse Dictionary

A list of dictionaries contained in the feature's response.

Properties

Name Type Description
bid string REQUIRED. A string identifying the iMessage extension that the user interacts with while using the Messages app.
data InteractiveMessageData A dictionary containing additional information for Messages for Business interactive messages
receivedMessage ReceivedMessage A dictionary with information telling the Messages app what content and how to display it in the received message bubble.
replyMessage ReplyMessage A dictionary with information telling the Messages app what and how to display it in the reply message bubble.

ReceivedMessage Dictionary

Both text and custom interactive messages use the receivedMessage field. In addition to the key listed here, the InteractiveResponse dictionary also tells the Messages app what and how to display it in the received message bubble.

The keys for the received message dictionary.

Name Type Description
imageIdentifier integer REQUIRED.

The possible string values for the received message style are:

  • icon: Indicates a message bubble size of 280 x 65 points at @3x scale (840 x 195 pixels).
  • small: Indicates a message bubble size of 280 x 85 points at @3x scale (840 x 255 pixels).
  • large: Indicates a message bubble size of 280 x 210 pixels at @3x scale (840 x 630 pixels).

The image size of each imageIdentifier reference should correspond with the style as follows:

  • When style is icon, the expected @3x image size is 40 x 40 points (120 x 120 pixels).
  • When style is small, the expected @3x image size is 60 x 60 points (180 x 180 pixels).
  • When style is large, the expected @3x image size is 263 x 150 points (789 x 450 pixels).

Note

Always provide @3x images at 72 dpi. The system downscales @3x images to generate @2x and @1x versions for use on lower-resolution devices.

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 Messages for Business service uploads the original reply message and sends a reference pointer, interactiveDataRef, to the original interactive data response. The keys in the interactiveDataRef contain the pointer to the Messaging service where the payload, or set of large assets, is contained.

As an MSP, your platform must download the reference pointer to obtain the original interactive data response from Messages for Business.

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

Below is a large interactive data payload.

{
    "interactiveDataRef": {
        "url": "https://p61-content.icloud.com/M58C0A1A2EB62B6E899B4F28996E8DA229E1914295299C39944B2F2CA7482AE50.C01USN00",
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
        "signature-base64": "gdYWyD3loBxhiXGaXSDhdDDGMeHr",
        "key": "00c0d1827fdc858fe7b42421de1fb289c2ee0a9463d787ce4f118506f970bd6e38",
        "signature": "81a619c81da5a01c6139219a5d20e17430c631e1eb",
        "owner": "M58C0A2A1EB62B4E859B4F28996E8DA229E1914295299C39944B2F2CA7482AE50.C01USN00",
        "size": 101267
    },
    "sourceId": "",
    "destinationId": "",
    "v": 1,
    "type": "interactive",
    "id": "80c72dab-dc7b-4750-8fae-ee7a90fae0cb"
}

Download the Encrypted Payload

When the interactiveDataRef key is present, download the encrypted payload from Messages for Business using the following method:

  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 Messages for Business’s /decodePayload endpoint with the request body containing the encoded data from the previous steps. The response body from the /decodePayload request is a decoded interactive data dictionary, which is the original interactive data dictionary that the user sent. For more details, see Decoding Interactive Data Payloads.

Decoding Interactive Data Payloads

Convert an interactive data reference into an interactiveData dictionary by calling the /decodePayload endpoint to decode large interactive data payloads received from Messages for Business. The endpoint takes the encoded attachment and returns the JSON dictionary representing the interactiveData dictionary. For more information, see Receiving Large Interactive Data Payloads.

URL

POST https://mspgw.push.apple.com/v1/decodePayload

HTTP Headers

For more information, see the HTTP Headers in Common Specifications.

HTTP Body

Name Description
data A binary file which is the decrypted downloaded file. For more details on the decrypted downloaded file, see Download the Encrypted Payload

Response Codes

You can find the list of Response Codes in Common Specifications.

Sample Decode Payload

The response body is a JSON dictionary of the decoded interactiveData dictionary. For the list of interactiveData dictionary keys, see BaseInteractiveMessage.

Request

POST https://mspgw.push.apple.com/v1/decodePayload
accept: */*
accept-encoding: gzip, deflate
authorization: Bearer signed-web-token
source-id: business-id
bid: com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension
content-type: application/octet-stream
{ attachment data }

Response

HTTP/1.1 200 OK
content-type: application/json
content-length: (size of stream)
{
    "interactiveData": {
        "bid": "some-bid",
        "URL": "url-data",
        "receivedMessage": {
            "title": "Interaction Title"
        }
    }
}

Quick Reply Message

Provide a simple way for the user to make an inline choice with a single tap during an ongoing conversation. You can have between two and five customizable choices, and the user can select only a single item.

The summaryText should not be considered as the introduction message to the quick reply message. You should use a text message to offer the user to choose one of the items.

Quick reply is an interactive message. Due to its simple structure, it doesn't have receivedMessage or replyMessage fields similar to other interactive message types.

This feature requires iOS 15.1 and macOS 12.0 or higher. For more information, see capability-list under HTTP Headers.

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 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.
style string A string field of the item style. Defaults to default. Styles available are: icon, small and large
subtitle string A string field of the item's subtitle.
title string REQUIRED. A string field of the section title.

Time Picker Message

Allow the customer to schedule an appointment.

To let the customer pick a time slot when scheduling a meeting or appointment, send a time picker interactive message. The interactive message displays conflicts found on the customer’s local calendar so the customer can make an informed decision.

After sending the reply, the customer can tap the reply message bubble to view location information, if available. The customer can also get directions to the location or add the event to their calendar by tapping Get Directions or Add to Calendar.

For more information on the visual design of time pickers, see Messages for Business features.

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. Messages for Business ignores this field when latitude and longitude are missing or empty.
title string A string field of the location title.

Location.TimeItem Dictionary

The time item dictionary keys used in sending a time picker.

Name Type Description
duration integer REQUIRED. An integer representing the duration of the time slot, in seconds.
identifier string REQUIRED. A string field identifying the time item that must be unique within the payload, if more than one exists.
startTime string REQUIRED. A UTC date string, represented by a valid date in ISO-8601 format and specified as absolute GMT +0000 date; for example, 2017-05-26T08:27:55+00:00, 2017-05-26T08:27:55+0000, or 2017-05-26T08:27:55Z. The timezoneOffset, from the EventItem dictionary, determines whether the startTime is in a specific time zone or in the customer's current time zone.

Tutorial Exercise

For more help or guidance, see our Tutorial: Sending Pickers.

Apple Pay Message

Provide an easy and secure way for customers to buy goods and services through Messages for Business using Apple Pay. When a business asks for payment from a customer who is purchasing goods and services through Messages for Business, the customer can use Apple Pay to make the payment.

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

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 Messages for Business after completing the order; provides you with an opportunity to update the order information in your system. For more information, see Tracking Orders.
paymentGatewayUrl string REQUIRED. Called by Apple Pay to process the payment through the payment provider. The URL should match the URL in the initiativeContext field of the payment session. For more information, see Processing Payment Requests.
paymentMethodUpdateUrl string Called by Apple Pay when the customer changes the payment method. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Payment Methods.
shippingContactUpdateUrl string Called by Apple Pay when the customer changes their shipping address information. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Shipping Contacts.
shippingMethodUpdateUrl string Called by Apple Pay when the customer changes the shipping method. If you don’t implement this endpoint and you include this key in the dictionary, the customer sees an error message. For more information, see Updating Shipping Methods.

PaymentRequest.ApplePay Dictionary

Keys for Apple Pay dictionary. The applePay dictionary provides Apple Pay configuration to Messages for Business.

Name Type Description
merchantCapabilities applePay.MerchantCapabilities 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 An array of payment networks supported by the merchant. The array must include one or more of the following values: amex, discover, jcb, masterCard, privateLabel, or visa. For more information, see supportedNetworks.

ApplePay.MerchantCapabilities Dictionary

An array of payment capabilities supported by the merchant.

object applePay.MerchantCapabilities

ApplePay.SupportedNetworks Dictionary

An array of payment networks supported by the merchant.

object applePay.SupportedNetworks

ApplePay.lineItems Dictionary

A set of line items that explain recurring payments and additional charges and discounts.

Name Type Description
amount string REQUIRED. The monetary amount of the line item.
label string REQUIRED. A short, localized description of the line item.
type string A value that indicates whether the line item is final or pending.

The applePay dictionary provides Apple Pay configuration to Messages for Business.

Payment.MerchantSession Dictionary

A unique token representing a transaction between a customer and merchant.

Name Type Description
displayName string REQUIRED. The canonical name for your store, suitable for display and consisting of 64 or fewer UTF-8 characters. Do not localize the name.
epochTimestamp string REQUIRED. The time representation in number of seconds that have elapsed since 00:00:00 UTC, Thursday, January 1, 1970.
expiresAt string REQUIRED. The exipiration time representation in number of seconds that have elapsed since 00:00:00 UTC, Thursday, January 1, 1970.
initiative string REQUIRED. A predefined value that identifies the e-commerce application making the request.
initiativeContext string REQUIRED. A value you provide based on the initiative. The values for initiative and initiativeContext depend on the kind of application you're building. For Messages for Business, use "messaging"for the initiative parameter. For the 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. 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 Messages for Business.

Properties

Name Type Description
merchantCapabilities An array of payment capabilities supported by the merchant. The array must include supports3DS, and may optionally include supportsCredit, supportsDebit, and supportsEMV. For more information, see merchantCapabilities.
merchantIdentifier string REQUIRED. A unique identifier that represents a merchant for Apple Pay.
supportedNetworks An array of payment networks supported by the merchant. The array must include one or more of the following values: amex, discover, jcb, masterCard, privateLabel, or visa. For more information, see supportedNetworks.

Sending an Apple Pay Payment Request

A payment request starts when a customer service agent with the business asks you to send a payment request to a customer. You should create a data dictionary to collect and store information about the payment request.

The first piece of information to collect is a payment session object. To get it, ask Apple Pay to start a new payment session (see Requesting an Apple Pay Payment Session). Apple Pay returns a payment session object which you add to the Payment.MerchantSession dictionary in the data dictionary.

Next, add the ApplePayPaymentRequest dictionary keys to the data dictionary. This is where you specify transaction details such as the purchase amount, payment processing capabilities, available shipping methods, and a list of items or services purchased. You can also request billing and shipping address information through the ApplePayPaymentRequest dictionary.

Finally, add the ApplePayEndpoints dictionary keys to the data dictionary. This dictionary identifies the endpoints needed to process the payment and receive any updates a customer might make before confirming the payment, such as updating the shipping address or changing the shipping method.

After constructing the data dictionary, send it to Messages for Business as part of an interactive message (see Sending a Custom Interactive Message). Messages for Business forwards the payment request to the customer's device, and the customer authorizes the payment from the Apple Pay payment sheet using Touch ID or Face ID. The device then sends the payment information, including the encrypted Apple Pay token and any requested customer contact information, to the paymentGatewayURL endpoint listed in the endpoints dictionary. After processing the payment, the merchant sends the transaction results to the customer's device, which in turn sends the results to you to let you know the payment request is complete.

{
    "type": "interactive",
    "interactiveData": {
      "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
      "data": {
        "images": [
          {
            "data": "base64encoded-image-file",
            "identifier": "1"
          }
        ],
        "version": "1.0",
        "payment": {
          "endpoints": {
            "fallbackUrl": "https://sams.example.com/fallback/",
            "orderTrackingUrl": "https://sams.example.com/orderTrackingUrl/",
            "paymentGatewayUrl": "https://sams.example.com/paymentGateway/",
            "paymentMethodUpdateUrl": "https://sams.example.com/paymentMethodUpdate/",
            "shippingContactUpdateUrl": "https://sams.example.com/shippingContactUpdate/",
            "shippingMethodUpdateUrl": "https://sams.example.com/shippingMethodUpdate/"
          },
          "merchantSession": {
            "epochTimestamp": 1525722894057,
            "expiresAt": 1525730094057,
            "merchantSessionIdentifier": "PSH40080EF4D655442D...FD",
            "nonce": "fe72cd0f",
            "merchantIdentifier": "302B976...8E",
            "displayName": "Sam's Fish",
            "signature": "308006092a864886f...00",
            "initiative": "messaging",
            "initiativeContext": "https://sams.example.com/paymentGateway",
            "signedFields": [
              "merchantIdentifier",
              "merchantSessionIdentifier",
              "initiative",
              "initiativeContext",
              "displayName",
              "nonce"
            ]
          },
          "paymentRequest": {
            "applePay": {
              "merchantCapabilities": [
                "supports3DS",
                "supportsDebit",
                "supportsCredit"
              ],
              "merchantIdentifier": "merchant.com.sams.fish",
              "supportedNetworks": [
                "amex",
                "visa",
                "discover",
                "masterCard"
              ]
            },
            "countryCode": "US",
            "currencyCode": "USD",
            "lineItems": [
              {
                "amount": "59.00",
                "label": "Halibut",
                "type": "final"
              },
              {
                "amount": "4.99",
                "label": "Shipping",
                "type": "final"
              }
            ],
            "requiredBillingContactFields": [
              "post"
            ],
            "requiredShippingContactFields": [
              "post",
              "phone",
              "email",
              "name"
            ],
            "shippingMethods": [
              {
                "amount": "0.00",
                "detail": "Available within an hour",
                "identifier": "in_store_pickup",
                "label": "In-Store Pickup"
              },
              {
                "amount": "4.99",
                "detail": "5-8 Business Days",
                "identifier": "flat_rate_shipping_id_2",
                "label": "UPS Ground"
              },
              {
                "amount": "29.99",
                "detail": "1-3 Business Days",
                "identifier": "flat_rate_shipping_id_1",
                "label": "FedEx Priority Mail"
              }
            ],
            "total": {
              "amount": "63.99",
              "label": "Sam's Fish",
              "type": "final"
            }
          }
        },
        "requestIdentifier": "8EF748B5-3DC5-47AE-B185-65E91518D209"
      },
      "receivedMessage": {
        "imageIdentifier": "1",
        "style": "large",
        "subtitle": "$63.99 at Sam's Fish",
        "title": "Halibut"
      }
  }

Updating Shipping Contacts

Receive changes that the customer makes to their shipping address by implementing the shipping contact update endpoint.

To receive shipping address changes, implement the shipping contact update endpoint. Give the endpoint any name you like, and make sure to set the shippingContactUpdateUrl key in the ApplePayEndpoints dictionary to this endpoint. For more information, see Handling Shipping Contact Updates.

Note

This endpoint must respond to the request within 30 seconds or the request times out.

Shipping Contact Request
POST https://msp.example.com/shippingContactUpdate
Parameters

The request body is a JSON dictionary with the following keys.

Key Description
payment A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary.
requestIdentifier An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform.
version The version number of the message extension schema; the version should be 1.0.
Payment Dictionary

Prior to the customer authorizing the transaction, you receive redacted shipping contact information, which includes only the necessary data for completing transaction related tasks, such as calculating taxes or shipping cost. For more information, see onshippingcontactselected.

The payment dictionary has the following key.

Key Description
shippingContact A dictionary with the customer's updated shipping address information. For more information, see shippingContact.

Updating Payment Methods

Receive changes that the customer makes to the payment method by implementing the payment method update endpoint.

To receive changes that a customer makes to the payment method, such as changing the credit card type, implement the payment method update endpoint. Give the endpoint any name you like, and set the paymentMethodUpdateUrl key in the ApplePayEndpoints dictionary to this endpoint. For more information, see Handling Payment Method Updates.

Note

This endpoint must respond to the request within 30 seconds or the request times out.

Update Payment Method Request
POST https://msp.example.com/paymentMethodUpdate
Parameters

The request body is a JSON dictionary with the following keys.

Key Description
payment A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary.
requestIdentifier An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform.
version The version number of the message extension schema; the version should be 1.0.
Payment Dictionary

The payment dictionary has the following key.

Key Description
paymentMethod A dictionary with payment method information. For the list of dictionary keys, see Payment Method Dictionary.

Payment Method Dictionary

The paymentMethod dictionary has the following key.

Key Description
type Indicates the payment method type. For more information, see ApplePayPaymentMethodType.
Sample Request

Below is a sample update payment request.

POST https://msp.example.com/paymentMethodUpdate

content-type: application/json

{
    "requestIdentifier": "8EF748B5-<truncated>9",
    "version": "1.0",
    "payment": {
        "paymentMethod": {
            "type": "credit"
        }
    }
}
Response

The response body is a JSON dictionary that contains the state of the payment request and indicates that the data has changed. The dictionary can contain a partial or complete payment dictionary. Following are the dictionary keys.

Note

For more information about the payment method update response, see ApplePayPaymentMethodUpdate.

Key Description
endpoints A dictionary containing the endpoints for payment processing, contact updates, and order tracking. For the list of dictionary keys, see ApplePayEndpoints dictionary.
errors An array of ApplePayError types, present only when the request detects errors.
merchantSession The merchant session containing the payment session provided by Apple Pay (see Requesting an Apple Pay Payment Session).
newLineItems An optional list of line items. For more information, see newLineItems.
newTotal The new total resulting from a change in the payment method. For more information, see newTotal.
Sample Response

Below is a sample payment method update response.

{
  "newLineItems": [
    {
      "amount": "59.00",
      "label": "Halibut",
      "type": "final"
    },
    {
      "amount": "29.99",
      "label": "FedEx Priority Mail",
      "type": "final"
    }
  ],
  "newTotal": {
    "amount": "88.99",
    "label": "Total",
    "type": "final"
  }
}

Updating Shipping Methods

Receive changes that the customer makes to the shipping method by implementing the shipping method update endpoint.

If you provide shippingMethods in paymentRequest (see ApplePayPaymentRequest dictionary) when sending an Apple Pay payment request, implement the shipping method update endpoint. If the customer changes the shipping method, you receive the selected shipping method through this endpoint.

Name the endpoint and point the shippingMethodUpdateUrl key in the ApplePayEndpoints dictionary to this endpoint. For more information, see Handling Shipping Method Updates.

Note

This endpoint must respond to the request within 30 seconds or the request times out.

Request
POST https://msp.example.com/shippingMethodUpdate
Parameters

The request body is a JSON dictionary with the following keys.

Key Description
payment A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary.
requestIdentifier An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform.
version The version number of the message extension schema; the version should be 1.0.
Payment Dictionary

The payment dictionary has the following key.

Key Description
shippingMethod The shipping method selected by the customer. For more information, see shippingMethod.
Sample Shipping Method Update Request
POST https://msp.example.com/shippingMethodUpdate

content-type: application/json

{
   "requestIdentifier": "8EF748B5-<truncated>",
   "version": "1.0",
   "payment": {
        "shippingMethod": {
          "amount": "29.99",
          "detail": "1-3 Business Days",
          "identifier": "flat_rate_shipping_id_1",
          "label": "FedEx Priority Mail",
          "type": "Final"
        }
    }
}
Response

The response body is a JSON dictionary that contains the state of the payment request and indicates that the data has changed. The dictionary can contain a partial or complete payment dictionary. Below are the dictionary keys.

Key Description
endpoints A dictionary containing the endpoints for payment processing, contact updates, and order tracking. For the list of dictionary keys, see ApplePayEndpoints dictionary.
errors An array of ApplePayError types, present only when the request detects errors.
merchantSession The merchant session containing the payment session provided by Apple Pay (see Requesting an Apple Pay Payment Session).
newLineItems An optional list of line items. For more information, see newLineItems.
newTotal The new total resulting from a change in the payment method. For more information, see newTotal.

Note

For more information about the shipping method update response, see ApplePayShippingMethodUpdate.

Sample Shipping Method Update Response
{
  "newLineItems": [
    {
      "amount": "59.00",
      "label": "Halibut",
      "type": "final"
    },
    {
      "amount": "29.99",
      "label": "FedEx Priority Mail",
      "type": "final"
    }
  ],
  "newTotal": {
    "amount": "88.99",
    "label": "Total",
    "type": "final"
  }
}

Tracking Orders

Receive final payment information by implementing the order tracking endpoint.

After processing the payment request, Messages for Business calls the order tracking endpoint providing final payment information. To receive that information, implement this endpoint, giving it any name you like. Make sure to set the orderTrackingUrl key in the ApplePayEndpoints dictionary to this endpoint.

Request

POST https://msp.example.com/orderTracking

Parameters

The request body is a JSON dictionary with the following keys.

Key Description
payment A dictionary containing payment information. For the list of payment dictionary keys, see Payment Dictionary.
requestIdentifier An identifier for the request. Messages for Business includes the identifier in its response to the MSP platform.
version The version number of the message extension schema; the version should be 1.0.

Payment Dictionary

Below are the keys for the payment dictionary.

Key Description
billingContact The customer's billing contact information. For more information, see billingContact.
errors An array of ApplePayError types. This field is present only when the payment processing request detects errors.
shippingContact The customer's shipping address information. For more information, see shippingContact.
shippingMethod The shipping method selected by the customer. For more information, see ApplePayShippingMethodItem.
summaryItems An array of ApplePayLineItem dictionaries.

Tutorial Exercise

For more help or guidance, see our Tutorial: Exercise: Integrating Apple Pay.

Authentication Message

Note

A new, upgraded Authentication message type is now available in iOS 16 and macOS 13. Be sure to review it in New Authentication Message Specification. All MSPs are required to support this new type beginning Fall 2022.

Pass a customer's authentication data to a business by using the OAuth protocol. Messages for Business allows authentication data to pass between customers and businesses on the Messaging Service Provider (MSP) using the authenticate endpoint as described in Sending an Authentication Message.

After the user is authorized, the system sends an OAuth response and the user’s device receives a login form. The user enters their username and password in the login form to continue the authorization process.

A screenshot of a login form, as displayed on iPhone.
A login form

Sending an Authentication Message

Pass authentication data between the business or Customer Service Platform and the customer's device using OAuth.

URL

POST https://mspgw.push.apple.com/v1/authenticate

HTTP Headers

For more information, see the HTTP Headers in Common Specifications.

HTTP Body

In iOS 15, Apple enhanced the authentication method built into Messages for Business. Prior to iOS 15, the authorization code and parameters appeared in the URI request.

Pre-iOS 15 example: server.example.com/?grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

Starting in iOS 15, the authorization code and parameters appear in the HTTP entity-body according to the standard for OAuth 2.0.

Name Description
AuthenticateRequestBody Content-Type: application/json

Response Codes

You can find the list of Response Codes in Common Specifications.

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

Pass Authenticate Data

Passing authenticate data requires sending a POST request to the /v1/authenticateendpoint hosted by Messages for Business with the authenticate message in the request body. You must secure the authenticate 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.

You use the AuthenticateRequestBody.Authenticate dictionary key and the responseEncryptionKey to authenticate with the OAuth provider endpoints. This workflow enables the OAuth provider to audit the public key used to encrypt the authentication token. Use the requestIdentifier in the data dictionary to identify the authentication request and map the OAuth token in the response to the request originator. Either the business or the MSP generates the requestIdentifier and responseEncryptionKey.

Messages for Business returns a JSON dictionary containing the encrypted token field. The business or CSP can decrypt the access token and verify the user's access. If the business is responsible for decrypting the access token, the business and MSP must implement the delegation of key generation and token verification. The tall, rectangular boxes on the vertical lines in the figure below denotes key generation and access token verification.

A diagram showing the authentication flow and data as it is passed between a business/MSP and a user's device.
Authentication flow between a MSP and a user's device

Validate the Public Key

Messages for Business authentication uses OAuth to provide a way for the authentication provider and the business to audit the public key sent in a user's authentication request. The audit detects when a public key has been tampered with or replaced, which could result in the customer's authentication token leaking to an unintended party.

When a user's device makes the HTTPS call to the authorization endpoint, it includes two additional request parameters in addition to the standard authentication request: responseEncryptionKey and userHandle. The authentication provider can make an API call to the business with the responseEncryptionKey and the user's opaque ID.

If the business is acting as its own authentication provider, it checks these values against its internal database. If the business made a request with that customer's key, the authentication provider proceeds by sending back the code or access token. If the customer's key does not match the parameter values in its pending requests, the customer's key may have been tampered with and the authentication provider must immediately fail the request from the device.

Note

You can also work with your authentication provider on proper validation of the public key.

Compose an Authentication Request

The authenticate request is an interactive message. When composing an authenticate request, include the AuthenticateRequestBody.Authenticate dictionary key in the BaseInteractiveMessage dictionary to describe the behavior and content of the authentication request.

You can send authentication data 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 authenticate messages have iOS 12 or later and macOS 10.14.0 or later. For more information about the Authorization header field, see Authorize a Message.

Successful Authentication

Example of an authentication request. Note that the clientSecret key is forwarded to the authentication provider as client_secret.

Request
{
    "type": "interactive",
    "interactiveData": {
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
        "data": {
            "version": "1.0",
            "requestIdentifier": "3EF748B5-<truncated>",
            "authenticate": {
                "oauth2": {
                    "responseType": "code",
                    "scope": ["email", "profile"],
                    "state": "security_token",
                    "responseEncryptionKey": "BFz948MTG3OQ0Q69 <truncated>",
                    "clientSecret": "client_secret"
                }
            },
            "images": [{
                "data": "iVBORw0KGgoAAAANSUhEUgAA <truncated>",
                "identifier": "1"
            }]
        },
        "receivedMessage": {
            "title": "Sign In",
            "imageIdentifier": "1"
        },
        "replyMessage": {
            "title": "You Signed In",
            "imageIdentifier": "1"
        }
    }
}
Response
{
    "data": {
        "version": "1.0",
        "requestIdentifier": "8EF748B5-<truncated>",
        "authenticate": {
            "status":"authenticated",
            "token": "<An encrypted Base64-encoded token.>"
        },
        "images": [{
                   "data": "iVBORw0KGgoAAAANSUhEUgAAADIA <truncated>",
                   "identifier": "1"
                   }]
    },
    "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
    "receivedMessage": {
        "title": "Sign In",
        "subtitle": "Authentication required to access your customer data",
        "style": "icon",
        "imageIdentifier": "1"
    },
    "replyMessage": {
        "title": "You Signed In",
        "subtitle": "",
        "style": "icon",
        "imageIdentifier": "1"
    }
}

Failed Authentication

Request
{
    "type": "interactive",
    "interactiveData": {
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
        "data": {
            "version": "1.0",
            "requestIdentifier": "3EF748B5-<truncated>",
            "authenticate": {
                "oauth2": {
                    "responseType": "code",
                    "scope": ["email", "profile"],
                    "state": "security_token",
                    "responseEncryptionKey": "BFz948MTG3OQ0Q69JHUiBG7 <truncated>",
                    "clientSecret": "client_secret"
                }
            },
            "images": [{
                "data": "iVBORw0KGgoAAAANSUhEUgA <truncated>",
                "identifier": "1"
            }]
        },
        "receivedMessage": {
            "title": "Sign In",
            "imageIdentifier": "1"
        }
    }
}
Response
{
    "data": {
        "version": "1.0",
        "requestIdentifier": "8EF748B5-<truncated>",
        "authenticate": {
            "status": "failed",
            "errors": [{
                "code": 2,
                "domain": "com.apple.icloud.messages.business.cryptor",
                "message": "Key is not UTF8"
            }]
        },
        "images": [{
            "data": "iVBORw0KGgoAAAANSUhEUgAA <truncated>",
            "identifier": "1"
        }]
    },
    "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
    "receivedMessage": {
        "title": "Sign In",
        "subtitle": "Authentication required to access your customer data",
        "style": "icon",
        "imageIdentifier": "1"
    },
    "replyMessage": {
        "title": "Authentication Failed",
        "subtitle": "",
        "style": "icon",
        "imageIdentifier": "1"
    }
}

AuthenticateRequestBody Dictionary

InteractiveMessageData dictionary with the authenticate key added used in sending an authentication message.

Properties

Name Type Description
authenticate object REQUIRED. A dictionary that describes the authentication request.
images array REQUIRED. An array of image dictionaries
requestIdentifier string REQUIRED. An identifier for the authenticate request.
version string REQUIRED. A numerical version number of the message extension schema.

AuthenticateRequestBody.Authenticate Dictionary

Keys for the Authenticate Data dictionary used in sending an authentication message.

Properties

Name Type Description
oauth2 object REQUIRED. A dictionary that describes the authentication request.

AuthenticateRequestBody.Authenticate.Oauth2 Dictionary

Keys for the OAuth2 Data dictionary used in sending an authentication message.

Properties

Name Type Description
clientSecret string REQUIRED. A string indicating the secret provisioned by the authorization server.
responseEncryptionKey byte REQUIRED. A string indicating the Base64-encoded public key that encrypts the access token returned in the response.
responseType string REQUIRED. A string indicating the type of authentication request.
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.

AuthenticateRequestBody.Authenticate.Oauth2.Scope Dictionary

An array of short text fields that describes the granted access for read and write. This dictionary entry gives the exact fields of data that the authentication service provides to the client requesting the authentication.

object AuthenticateRequestBody.Authenticate.Oauth2.Scope

Authenticate Webhook Event

Webhook Payload

Keys used in the JSON dictionary which is the response body.

Name Type Description
errors object A list of errors for authentication failure cases. See Error Codes.
status string A string indicating the status of the authentication request.
token string A Base64-encoded authentication token string, which is encrypted with the responseEncryptionKey from the request when authentication is successful.

Errors

Name Type Description
code integer A numerical error code. See Error Codes.
domain string A string indicating the error domain.
message string A string indicating the description of the error.

Decrypting the Authentication Token

To authenticate users, you need to decrypt their encrypted authentication token from the response. The authentication token should include the following:

  • A 384-bit elliptic curve secp384r1 public key specified in the authenticate request.
  • An encrypted authentication token, for use by the Messaging Service Provider (MSP) platform. You can create the token on the customer's device using the eciesEncryptionCofactorVariableIVX963SHA256AESGCM algorithm.

The business or MSP platform uses the associated private key generated for the request to decrypt and obtain the clear text authentication token.

For more information on authentication, see Sending an Authentication Message.

About the Authentication Token

When a customer successfully completes authenticating with a business, the MSP platform receives an authentication token. This token includes encrypted information and requires a decryption procedure to retrieve the information to determine the authenticity of the customer.

The authentication token is a Base64-encoded string contained in the JSON payload returned by the interactive message from the Messages for Business server. You can find it nested in the interactiveData/data/authenticate/token folder.

The authentication token uses the Elliptic Curve Integrated Encryption Scheme (ECIES). There are several versions for ECIES and keys, and encrypted data are not always compatible between versions. Some applications use a derivative or a subset of a version, so they may not be compatible with other implementations.

Messages for Business uses the secp384r1 curve for generating public/private key pairs, and X9.63 for encoding the public keys. Libraries compatible with these standards are available across many languages and platforms.

Before developing the production code for your implementation, you should understand the concepts of encryption and be familiar with the libraries to handle these items on your platform. Some libraries have an abstract cryptographic library that requires deep understanding to apply the correct algorithm and parameters. Other libraries implement many methods and are fairly straightforward to use, but require a great deal of research to determine a suitable method for a particular application. Understand these concepts before you begin your production code.

You should validate the compatibility of your particular implementation with the standards by building a comprehensive test. You should also review your implementation with information security experts. It is recommended to perform a security review with an independent security team before deployment.

Decrypt the Authentication Token

In this decryption exercise, you use a Base64-encoded binary data and an X9.63-encoded uncompressed public key. The unsigned scalar private key example has been converted to bytes. The private key is not sent in the request, so businesses can choose any encoding format.

Use the following values so that you can follow along with the exercises. You can use the immediate mode on your favorite language or write sample code on your platform.

  • Public Key

    BNY+I93aHVkXnNWKVLdrMJLXpQ1BsyHYoiv6UNi4rDUsRx3sNNhW8FNy9yUwxYprAwwfj1ZkoJ61Fs+SwjIbGPtXi52arvSbPglyBN4uAxtP3VP3LCP4JtSEjdgsgsretA==

  • Private Key

    pX/BvdXXUdpC79mW/jWi10Z6PJb5SBY2+aqkR/qYOjqgakKsqZFKnl0kz10Ve+BP

  • Encrypted Authentication Token

    BDiRKNnPiPUb5oala31nkmCaXMB0iyWy3Q93p6fN7vPxEQSUlFVsInkJzPBBqmW1FUIY1KBA3BQb3W3Qv4akZ8kblqbmvupE/EJzPKbROZFBNvxpvVOHHgO2qadmHAjHSmnxUuxrpKxopWnOgyhzUx+mBUTao0pcEgqZFw0Y/qZIJPf1KusCMlz5TAhpjsw=

To decrypt the authentication token, use the following steps:

  1. Extract the ephemeral public key from the encrypted data.
  2. Derive the public numbers from the ephemeral public key.
  3. Obtain a shared key using an Elliptic Curve Cyrptopgraphy Cofactor Diffie-Hellman (ECC CDH).
  4. Generate the derived key and initial vector by running the shared key through the X9.63 Key Derivation Function with SHA256 hash function.
  5. Perform an AES-GCM decryption using the encrypted data string and initialization vector (IV) obtained in step 4.

The following sections take you through the process of decrypting the authentication token, as detailed in the previous steps.

Extract and Confirm the Ephemeral Public Key

Extract the ephemeral public key from the encrypted data. The authentication token contains several parts:

  • Byte 0 is 0x04 and indicates an uncompressed key form.
  • Bytes 0...96 are the ephemeral public key. Note that 0-byte is part of the ephemeral public key in addition to indicating the uncompressed form.
  • Bytes 97...n-16 are the encrypted data, where n is the length of the authentication token.
  • Bytes n-15...n-1 are the encryption tag.

When you compute the key on the secp384r1 curve, the key data is 96 bytes (384/8 * 2). The x and y coordinates can have up to 384-bytes.

Exercise

First, Base64-decode the authentication token string. This results in a 142-byte binary which is the actual authentication token. The first byte, 0x04, indicates the key in an uncompressed form.

Use the Base64 library and binary object manipulation library for your language and platform. Base64-encode the ephemeral public key from the binary form. The following uncompressed ephemeral key should result:

  • BDiRKNnPiPUb5oala31nkmCaXMB0iyWy3Q93p6fN7vPxEQSUlFVsInkJzPBBqmW1FUIY1KBA3BQb3W3Qv4akZ8kblqbmvupE/EJzPKbROZFBNvxpvVOHHgO2qadmHAjHSg==

Derive the binary for the encrypted data portion and Base64-encode it. The resulting encrypted data string is:

  • afFS7GukrGilac6DKHNTH6YFRNqjSlwSCpkXDRj+

The Base64-encoded encryption tag is:

  • pkgk9/Uq6wIyXPlMCGmOzA==

Save the encrypted data string and tag as these are used in Perform an AES-GCM Decryption.

Derive the Public Numbers

Derive the public numbers from the public key. The public numbers are the x and y coordinates of the elliptic curve used in the encryption process. Use a method within the cryptographic library on your platform to derive these values.

Some libraries pass the secp384r1 curve to the routine as a parameter along with the public key. Other libraries have a method for the secp384r1 that accepts the public key as a parameter. Familiarize yourself with the cryptographic library and apply the best method to this step.

Exercise

Pass the secp384r1 curve and the ephemeral public key into your cryptography library method for deriving the public numbers.

Continuing from the values in the previous section, you should receive the following two coordinates:

  • x=8706462696031173094919866327685737145866436939551712382591956952075131891462487598200779332295613073905587629438229
  • y=10173258529327482491525749925661342501140613951412040971418641469645769857676705559747557238888921287857458976966474

Obtain the Shared Key Using the ECC CDH

To obtain the shared key, perform an ECC CDH operation using the ephemeral public key and the private key. You should get the following shared key after using the ECC CDH operation:

  • 2lvSJsBO2keUHRfvPG6C1RMUmGpuDbdgNrZ9YD7RYnvAcfgq/fjeYr1p0hWABeif

Generate the Derived Key and Initial Vector

Run the shared key through the X9.63 Key Derivation Function with SHA256 hash function. This results in a 48-byte payload.

Use the initialization vector to perform the decryption in Perform an AES-GCM Decryption.

The first 32-bytes yields the derived key, for this exercise:

  • mAzkYatDlz4SzrCyM23NhgL/+mE3eGgfUz9h1CFPhZM=

The last 16-bytes serve as the IV:

  • rV3qrszd0PMPgeRhNnlOYA==

Perform an AES-GCM Decryption

Refer back to the saved values from the first step, Extract and Confirm the Ephemeral Public Key. Use the following encrypted data string:

  • afFS7GukrGilac6DKHNTH6YFRNqjSlwSCpkXDRj+

and the IV from Generate the Derived Key and Initial Vector:

  • rV3qrszd0PMPgeRhNnlOYA==

to perform a message authentication code (MAC) validation, include the encryption tag from Extract and Confirm the Ephemeral Public Key:

  • pkgk9/Uq6wIyXPlMCGmOzA==

This yields a plain text string token that you can use for authentication:

  • xXTi32iZwrQ6O8Sy6r1isKwF6Ff1Py

Troubleshooting

Decryption fails if the keys or associated tag derived in Generate the Derived Key and Initial Vector are incorrect. Failed decryptions result in rejected tokens, including the associated tag validation.

Using Password AutoFill to Authenticate Users

Provide customers with an easy solution to perfom authentication on their iOS devices.

Supporting the Password AutoFill feature requires that the authorization input element must 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.

Error Codes

Possible errors thrown by the customer's device.

The device may return various errors as listed in the following tables. All errors in the tables are from the com.apple.icloud.messages.business domain.

Table 1 Authentication domain errors

Error Code Message Description
BCTokenMissingError 1 Missing Token or Missing Code. Thrown when the authentication plugin cannot retrieve a token or a code from the redirect URL.
BCEmptyDataReceivedError 2 Empty data received when exchanging token. Thrown when the authentication plugin receives an empty response when exchanging the code for a token.
BCAccessTokenMissingFromResponseError 3 Missing access token from response. Thrown when the authentication plugin receives a valid response, but the response is missing access_token from the JSON body.

Table 2 Cryptor domain errors

Error Code Message Description
BCPublicKeyIsEmptyError 1 Empty string received for key. Thrown when the cryptor is given an empty public key.
BCPublicKeyIsNotUTF8Error 2 Key is not UTF-8. Thrown when the cryptor Base64-decodes the public key and fails because the encoding is not UTF-8.
BCPublicKeyIsInvalidError 3 Public key is invalid. Thrown when the cryptor fails to validate the key against SecKeyAlgorith.eciesEnCryptionCofactorVariableVX963SHA256AESGCM.
BCPublicKeyInternalError 3 Failed adding key.Failed reading key.Failed deleting key. Thrown when the cryptor cannot complete the given task due to an internal error.
BCEncryptionError 4 Unable to encrypt token. Thrown when the cryptor fails to encrypt a given payload using the provided public key.

Tutorial Exercise

For more help or guidance, see our Tutorial: Exercise: Sending an Authentication Message.

iMessage App

Below is the iMessage app, also referred to as CustomInteractiveData, request body. The request body is based on InteractiveData.

Name Type Description
InteractiveData Custom InteractiveData

InteractiveData

The CustomInteractiveData dictionary keys. In addition to the keys from the BaseInteractiveMessage dictionary, the message can also include the keys from the CustomInteractiveData dictionary.

Name Type Description
appIcon byte REQUIRED. A Base64-encoded string representing the app icon of the iMessage app. The Messages app displays the icon when a customer's device receives a iMessageApp message that uses an iMessage extension not installed on the device. The MSP platform must include this key when sending an interactive message that uses an iMessage extension provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage extension. For more information, see Sending Custom iMessage app.
appId string REQUIRED. The App Store identifier of the iMessage app. The MSP platform must include this key when sending an interactive message that uses an iMessage extension provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage extension. For more information, see Sending Custom iMessage app.
appName string REQUIRED. The name of the iMessage app. The MSP platform must include this key when sending an interactive message that uses an iMessage app provided by the business. Don’t include this key when sending an interactive message that uses a Messages for Business iMessage app. For more information, see Sending Custom iMessage apps.
receivedMessage REQUIRED. A dictionary with information telling the Messages app what content and how to display it in the received message bubble.
replyMessage REQUIRED. A dictionary with information telling the Messages app what and how to display it in the reply message bubble.
URL string REQUIRED. A URL string containing data that the Messages app sends to the iMessage app.
useLiveLayout boolean REQUIRED. A Boolean that determines whether the Messages app should use Live Layout. The default is true. Default: true

InteractiveData.ReceivedMessage

A dictionary with information telling Messages how to display the received message bubble and what content to include. For more information, see ReceivedMessage.

object InteractiveData.ReceivedMessage

InteractiveData.ReplyMessage

A dictionary with information telling Messages how to display the reply message bubble and what content to include.

object InteractiveData.ReplyMessage

When the MSP platform sends a custom interactive message, the contents of the title and subtitle may not show up on the response if the customer overwrites these fields. For more information, see ReplyMessage.

Sending a Custom Interactive Message

Provide a unique user experience with custom interactive messages.

You can use your custom interactive message—by setting the bid, appId, appName, and appIcon to reference your extension.

When sending a custom interactive message, use the type value of interactive and include the interactiveData field in the message JSON. The interactiveData field is a dictionary that describes the iMessages extension to use. The dictionary also contains data that the Messages app passes to the extension.

To control the appearance of the interactive message that Messages displays on the customer’s device, use the receivedMessage dictionary. Note that the Messages app ignores the imageIdentifier and style keys when using a custom interactive message. For the list of received message dictionary keys, see receivedMessage dictionary.

{
    "type": "interactive",
    "interactiveData": {
        "appId": "<app - store - id>",
        "appName": "Name of the App",
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:{team-id}:{ext-bundle-id}",
        "URL": "?data=passed-to-app&data2=more-data-passed-to-app",
        "sessionIdentifier": "uuid-for-this-interaction",
        "receivedMessage": {
            "title": "Title of Bubble",
            "subtitle": "Subtitle to be displayed under title",
            "imageTitle": "Title of image attachment",
            "imageSubtitle": "Subtitle of the image attachment.",
            "secondarySubtitle": "Title that is aligned right",
            "tertiarySubtitle": "Subtitle that is aligned right"
        }
    },
    "sourceId": "",
    "destinationId": "",
    "v": 1,
    "id": "d2f99c0e-f64c-4c3b-abbf-4a8567891ef5"
}

Tutorial Exercise

For more help or guidance, see our Tutorial: Exercise: Integrating Your iMessage App.

Form Message

Messages for Business Forms allow you to create rich, multipage interactive flows for users on iOS and iPadOS devices using a single JSON payload. This document provides the Forms specifications, along with example outbound and inbound JSON payloads.

You and your brands may already have ideas which could benefit from this type of interaction. Below are some example use cases:

  • Triage flows
  • CSAT Survey
  • Account creation or service sign-up

Known Issues

  • When a user task switches out to another app and back to Messages, the form closes. The user must tap to re-open the form. The form resets and the user has to re-enter their responses.

Because a user may have to re-open the form and re-enter their responses, we recommend you give less complicated use cases that provide quick answers through a simple triage menu. For example, if you use a technical support triage, the following choices appear:

  • Did you plug it in?
  • Did you turn it on?
  • Is the green light flashing?

Form Specifications

The specifications below define the content of the JSON payloads used to render the Form on user devices. For JSON examples, see the Sample Request Payload and Response Payload.

Request Payload

The type of interactiveMessage that initiates the experience is dynamic.

Field Description
version REQUIRED. Should be 1.1 or the specified value when the feature launches.
template REQUIRED. Type is 'messageForms'. Tells the client which template to use to render the view.
data REQUIRED. Place all the data in this field.
Data Dictionary Objects
Object Description
splash Shown at the start of the form. When using splash, ensure the appropriate fields listed below display:
-header: If set, it displays in bold the title on the page underneath the image.
-splashtext: Use this to display the body copy for the page.
-buttonTitle: REQUIRED. Text on the button shown on the page. If buttonTitle is missing then this view doesn't display and continues onto the first module.
-imageIdentifier: Image to be shown at the top of the view.
startPageIdentifier REQUIRED. Identifier for the starting page of the form. Must match one of the string identifiers for the configured pages. See pageIdentifier under pages below.
private Defaults to false. Boolean value indicates whether to mark the response as private. If value is true, the response object contains this property (interactiveData > data > dynamic > private).
showSummary Defaults to false. If set to true then it shows the summary of all the selections made within the form.
pages REQUIRED. An array of different pages to be shown in the form. Every page object has following common objects.
-pageIdentifier: REQUIRED. A unique identifier, as a string, for the page being shown, that is less than 20 characters in length. Do not reuse. Ex: "firstNamePage" or "0001".
-type: REQUIRED. Use one of the following values: select, picker, datePicker, or input.
-title: If set this displays the title in bold on the page.
-subtitle: REQUIRED. Use this object to display the question for the page.
-nextPageIdentifier: REQUIRED except for single select option page, where you specify the nextPageIdentifier within each of the item objects. If a page does not have a nextPageIdentifier set on it, the client assumes the current page to be the final page and proceeds to send or provides a summary page based on the data. This is a unique page identifier to show the next page.
-submitForm: A Bool value placed on the pages to denote the end page of the form. Since multiple pages can act as an end page, this object can be set on multiple pages.
Types of Pages

Pages is an array of page elements and there needs to be at least be one page to trigger the Form experience.

Page Type Field Description
select multipleSelection A Bool value that defaults to false or singleSelect. Set to true to enable multipleSelection on the page.
items An array of objects defining the user experience.
-title: Localized string value for display.
-value: A string value of the object itself.
-identifier: A unique identifier for the item.
- imageIdentifier: A string containing the image identifier, from the imageItem dictionary. For more information about sending an image, see ImageItem dictionary.
-nextPageIdentifier: A unique page identifier to show the next page. Set this value only when multipleSelection is not defined or set to false.
picker pickerTitle A string value representing optional text shown next to the picker text field. This value defaults to an empty string. When empty the picker text field centers to the page
selectedItemIndex A zero-indexed number identifying the item in the picker wheel should be selected by default. Defaults to item at index 0.
items An array of objects defining the user experience.
-title: Localized string value for display.
-value: A string value of the object itself.
-identifier: A unique identifier for the item.
datePicker hintText A string representing optional text to give the user more input context that displays below the Date field.
options Dictionary containing optional values for the Date Picker element.
-dateFormat: A string representing the date format on the page. Defaults to MM/dd/yyyy. Unless this property is explicitly set, all of the date properties are defined using this format. For format string specifications see: Use Format Strings to Specify Custom Formats.
-startDate: A string representing the date displayed by the date picker. Defaults to current date.
-maximumDate: A string representing the maximum date that a date picker can show. Defaults to current date.
-minimumDate: A string representing the minimum date that a date picker can show.
-labelText: A string representing the text string to be shown next to date field. Defaults to text 'Date'.
input hintText A string representing optional text to give the user more input context that displays below the Input field.
options Dictionary containing optional values for the input field.
-regex: A string representing a JSON encoded regular expression (regex) string to limit the type of input for input field to use. An example is when you want to limit input to only have proper decimal values provide a regex string: ^\\d*\\.?\\d?\\d?$. JSON encode all regex strings
-placeholder: A text string used when there is no other text in the input text field. Default value are Required or Optional.
-required: A Boolean value that defaults to false. When set to true, the next button on page is disabled until the user provides input.
-inputType: A string value that defaults to singleline. Other values are multiline or singleline.
-labelText: A string value representing a text label shown to identify the input field. This value defaults to an empty string. Only applies to inputType : singleline.
-prefixText: A string value representing optional text shown next to the text field. This value defaults to an empty string. For example, you can set this value to denote the $ character for the field. Only applies to inputType : singleline.
-maximumCharacterCount: An integer value representing the field size in characters for singleline and multiline. The field size defaults to 30 characters for singleline and 300 characters for multiline.
-keyboardType: Optional string value. Type of keyboard to be shown. Possible values:
-default: Default value. Specifies the default keyboard for the current input method.
-asciiCapable: Specifies a keyboard that displays standard ASCII characters.
-numbersAndPunctuation: Specifies the numbers and punctuation keyboard.
URL: Specifies a keyboard optimized for URL entry. This keyboard type prominently features the period (.), forward slash (/) characters, and the .com string.
-numberPad: Specifies a numeric keypad designed for PIN entry. This keyboard type prominently features the numbers 0 through 9. This keyboard type does not support autocapitalization.
-phonePad: Specifies a keypad designed for entering telephone numbers. This keyboard type prominently features the numbers 0 through 9 and the asterisk (*) and hash tag (#) characters.
-namePhonePad: Specifies a keypad designed for entering a person’s name or phone number. This keyboard type does not support auto-capitalization.
-emailAddress: Specifies a keyboard optimized for entering email addresses. This keyboard type prominently features the at (@), period (.), and space characters.
-decimalPad: Specifies a keyboard with numbers and a decimal point.
-UIKeyboardTypeTwitter: Specifies a keyboard optimized for Twitter text entry, with easy access to the at (@) and hash tag (#) characters.
-webSearch: Specifies a keyboard optimized for web search terms and URL entry. This keyboard type prominently features the space and period (.) characters.
-textContentType: A string value representing the keyboard and system information about the expected semantic meaning for the content that users enter. Supported values are name, namePrefix, givenName, middleName, familyName, nameSuffix, nickname, jobTitle, organizationName, location, fullStreetAddress, streetAddressLine1, streetAddressLine2, addressCity, addressState, addressCityAndState, sublocality, countryName, postalCode, telephoneNumber, emailAddress, URL, creditCardNumber, username, password, newPassword, and oneTimeCode. For a full description of each supported value, see UITextContentType on Apple Developer.
Sample Request Payload

Below is a sample request payload in JSON.

{
    "type": "interactive",
    "interactiveData": {
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
        "data": {
            "version": "1.0",
            "requestIdentifier": "da39a3ee5e6b4b0d3255 <truncated>",
            "dynamic": {
                "version": "1.1",
                "template": "messageForms",
                "data": {
                    "startPageIdentifier": "0",
                    "showSummary": true,
                    "splash": {
                        "header": "Apple Card",
                        "splashtext": "Kindly answer the following questions to help us dispute this transaction.",
                        "buttonTitle": "Continue",
                        "imageIdentifier": "2"
                    },
                    "pages": [{
                            "pageIdentifier": "0",
                            "type": "select",
                            "title": "Type of Product",
                            "subtitle": "Was the merchandise you received defective or not as the merchant described?",
                            "multipleSelection": true,
                            "nextPageIdentifier": "1",
                            "items": [{
                                    "title": "Option 1",
                                    "value": "option1",
                                    "identifier": "001"
                                },
                                {
                                    "title": "Option 2",
                                    "value": "option2",
                                    "identifier": "002"
                                },
                                {
                                    "title": "Option 3",
                                    "value": "option3",
                                    "identifier": "003"
                                },
                                {
                                    "title": "Option 4",
                                    "value": "option4",
                                    "identifier": "004"
                                },
                                {
                                    "title": "Option 5",
                                    "value": "option5",
                                    "identifier": "005"
                                },
                                {
                                    "title": "Option 6",
                                    "value": "option6",
                                    "identifier": "006"
                                }
                            ]
                        },
                        {
                            "pageIdentifier": "1",
                            "type": "select",
                            "title": "Item Condition",
                            "subtitle": "Was the merchandise you received defective or not as the merchant described?",
                            "multipleSelection": false,
                            "items": [{
                                    "title": "Defective",
                                    "value": "defective",
                                    "identifier": "101",
                                    "nextPageIdentifier": "2"
                                },
                                {
                                    "title": "Not as described",
                                    "value": "notAsDescribed",
                                    "identifier": "102",
                                    "nextPageIdentifier": "3"
                                }
                            ]
                        },
                        {
                            "pageIdentifier": "2",
                            "type": "select",
                            "title": "Supporting Documents",
                            "subtitle": "Do you have any supporting documents that demonstrate that the product quality was not sufficient?",
                            "multipleSelection": false,
                            "items": [{
                                    "title": "Yes",
                                    "value": "yes",
                                    "identifier": "201",
                                    "nextPageIdentifier": "3"
                                },
                                {
                                    "title": "No",
                                    "value": "no",
                                    "identifier": "202",
                                    "nextPageIdentifier": "3"
                                }
                            ]
                        },
                        {
                            "pageIdentifier": "3",
                            "type": "picker",
                            "pickerTitle": "Select Your Region",
                            "nextPageIdentifier": "4",
                            "items": [{
                                    "title": "APAC",
                                    "value": "apac",
                                    "identifier": "301"
                                },
                                {
                                    "title": "EMEA",
                                    "value": "emea",
                                    "identifier": "302"
                                },
                                {
                                    "title": "LATAM",
                                    "value": "latam",
                                    "identifier": "303"
                                },
                                {
                                    "title": "NAM",
                                    "value": "nam",
                                    "identifier": "304"
                                }
                            ]
                        },
                        {
                            "pageIdentifier": "4",
                            "type": "datePicker",
                            "title": "Retrieval Date",
                            "subtitle": "What date did you receive, or expect to receive the product?",
                            "nextPageIdentifier": "5",
                            "options": {
                                "startdate": "2020-02-12",
                                "maximumdate": "2020-02-13",
                                "minimumdate": "2020-01-01",
                                "dateFormat": "MM/dd/yyyy"
                            }
                        },
                        {
                            "pageIdentifier": "5",
                            "type": "input",
                            "title": "Remaining Issues",
                            "subtitle": "Please provide details about remaining issue",
                            "nextPageIdentifier": "6",
                            "options": {
                                "required": true,
                                "inputType": "multiline",
                                "maximumCharacterCount": 300,
                                "keyboardType": "UIKeyboardTypeEmailAddress"
                            }
                        },
                        {
                            "pageIdentifier": "6",
                            "type": "input",
                            "title": "Product name",
                            "subtitle": "Please provide name of the product",
                            "options": {
                                "required": false,
                                "inputType": "singleline",
                                "maximumCharacterCount": 25,
                                "keyboardType": "UIKeyboardTypePhonePad"
                            },
                            "submitForm": true
                        }
                    ]
                }
            },
            "images": [{
                    "data": "base64encoded-image-file",
                    "identifier": "1"
                },
                {
                    "data": "base64encoded-image-file",
                    "identifier": "2"
                },
                {
                    "data": "base64encoded-image-file",
                    "identifier": "3"
                },
                {
                    "data": "base64encoded-image-file",
                    "identifier": "4"
                }
            ]
        },
        "receivedMessage": {
            "title": "Apple Card Dispute Form",
            "subtitle": "Please fill out the following dispute form.",
            "style": "small",
            "imageIdentifier": "1"
        },
        "replyMessage": {
            "title": "Tap to view your response.",
            "subtitle": "",
            "style": "small",
            "imageIdentifier": "1"
        }
    }
}

Response Payload

The response from the client is encapsulated within interactiveData > data > dynamic > selections object.

Each of the objects within the selections object would have the following elements.

Element Description
pageIdentifier A unique identifier representing the page from which the response is mapped.
title A string representing the title of the page
subtitle A string representing the question or subtitle on the page.
items An array containing all the selections made on the page. Each of the objects within the array items contains the following structure:
-identifier: A unique identifier set on the individual items for each type of page selected. Except for pages with type of input and datePicker the identifier is the same value as the pageIdentifier.
-type: One of the following values select, datePicker, or input that corresponds to the page’s type value.
-title: The localized value of an item selected or user input. For example, the datePicker type would format the date value. For input type if any prefixLabel is provided, and the title needs to contain the prefixLabel + inputValue.
-value: A string value included in the request payload. For the selections objects and for input type, this is the same value as in title (user input). For datePicker pages, this field returns the value in UTC format: yyyy-MM-dd'T'HH:mm:ss'Z'.
Sample Response Payload

Below is an example of a response payload in JSON.

{
    "type": "interactive",
    "interactiveData": {
        "bid": "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.icloud.apps.messages.business.extension",
        "sessionIdentifier": "ad461c33-7534 <truncated>",
        "data": {
            "version": "1.0",
            "dynamic": {
                "template": "messageForms",
                "version": "1.1",
                "selections": [{
                        "pageIdentifier": "001",
                        "items": [{
                            "identifier": "001_03",
                            "value": "option03",
                            "type": "select",
                            "title": "Single 3"
                        }],
                        "subtitle": "Single Select Page",
                        "title": "Please Choose One Selection To Move On To The Next Page"
                    },
                    {
                        "pageIdentifier": "002",
                        "items": [{
                                "identifier": "002_01",
                                "value": "multi1",
                                "type": "select",
                                "title": "Multi 1"
                            },
                            {
                                "identifier": "002_03",
                                "value": "multi3",
                                "type": "select",
                                "title": "Multi 3"
                            },
                            {
                                "identifier": "002_05",
                                "value": "multi5",
                                "type": "select",
                                "title": "Multi 5"
                            }
                        ],
                        "subtitle": "Multiple Selection",
                        "title": "Select All That Apply"
                    },
                    {
                        "pageIdentifier": "003",
                        "items": [{
                            "identifier": "003",
                            "value": "2021-03-30T07:00:00Z",
                            "type": "datePicker",
                            "title": "03/30/2021"
                        }],
                        "subtitle": "Date Picker",
                        "title": "Date Picker With Min/Max Date and Label Text"
                    },
                    {
                        "pageIdentifier": "004",
                        "items": [{
                            "identifier": "004",
                            "value": "50.00",
                            "type": "input",
                            "title": "$50.00"
                        }],
                        "subtitle": "Numeric Input - Currency",
                        "title": "With Custom Label, Prefix, Regex and Placeholder Text"
                    },
                    {
                        "pageIdentifier": "005",
                        "items": [{
                            "identifier": "005",
                            "value": "J. Appleseed",
                            "type": "input",
                            "title": "J. Appleseed"
                        }],
                        "subtitle": "Text Input - Single Line",
                        "title": "With Placeholder, Label and Expecting a Name"
                    },
                    {
                        "pageIdentifier": "006",
                        "items": [{
                            "identifier": "006",
                            "value": "Multi\nLine\nText\nInput",
                            "type": "input",
                            "title": "Multi\nLine\nText\nInput"
                        }],
                        "subtitle": "Text Input - Multiple Lines",
                        "title": "Optional Additional Comment Field"
                    }
                ]
            },
            "receivedMessage": {
                "subtitle": "Tap to view the available pages",
                "imageIdentifier": "1",
                "style": "small",
                "title": "Messages for Business Form"
            },
            "replyMessage": {
                "subtitle": "Tap to review your selections",
                "alternateTitle": "Messages for Business Form",
                "imageIdentifier": "1",
                "style": "small",
                "title": "Messages for Business Form"
            },
            "requestIdentifier": "42bcfae9-3da6 <truncated>",
            "images": [{
                    "identifier": "1",
                    "data": "base64encoded-image-file"
                },
                {
                    "identifier": "2",
                    "data": "base64encoded-image-file"
                }
            ]
        }
    }
}