Tutorial: Add Alexa for Apps V2 to Your Custom Skill

This tutorial walks you through adding Alexa for Apps to your own custom skill. The code examples in this tutorial are for a skill called "City Guide."

You start by adding app and website metadata to the skill manifest. You edit the skill endpoint to send deep links, and then you test the skill.

For an overview of this feature, see About Alexa for Apps V2.

Prerequisites

Before you can add Alexa for Apps to your own skill, you need the following items:

  • Your own Alexa custom skill.
  • An iOS or Android app with available deep links, or a website.

High-level steps to add Alexa for Apps to your custom skill

The following steps show you how to add Alexa for Apps to your skill.

Step 1: Add app and website metadata to your skill manifest (skill.json)

In this step, you specify in your skill manifest which apps and websites your skill links to, and provide information about each one.

To add app and website metadata to your skill manifest

  1. Install the ASK CLI as described in Quick Start: Alexa Skills Kit Command Line Interface (ASK CLI).
  2. To download the skill manifest for your custom skill to a new file named skill.json, use the get-skill-manifest CLI command as follows:

    ask smapi get-skill-manifest -s <skill-id> -g <stage> > skill.json

  3. To declare support for Alexa for Apps in your skill manifest, add a type property with value APP_LINKS_V2 in the interfaces array (manifest.apis.custom.interfaces), as shown in the following example:
       {
          "type":"APP_LINKS_V2"
       },
    
  4. To add metadata to your skill manifest for the apps your skill links to, add an appLink object under manifest.apis.custom.appLink, as shown in the following City Guide skill example with a localized name in German.
    {
       "manifest": {
          "apis": {
             "custom": {
                "endpoint": {
                   "uri": "..."
                },
                "interfaces": [
                   {
                      "type": "APP_LINKS_V2"
                   }
                ],
       ================== ALEXA FOR APPS ADDITIONS START ==================
                "appLink": {
                   "linkedApplications": [
                      {
                         "friendlyName":{
                            "default":"CityGuide",
                            "localizedNames": [
                               {
                                  "locale":"de-DE",
                                  "name":"Stadtführer"
                               }
                            ]
                         },
                         "catalogInfo": {
                            "type": "IOS_APP_STORE",
                            "identifier": "id123456789"
                         },
                         "customSchemes": [
                            "cityguide://",
                            "ctgd://"
                         ],
                         "domains": [
                            "cityguide.com",
                            "ctgd.com"
                         ]
                      },
                      {
                         "friendlyName":{
                            "default":"CityGuide",
                            "localizedNames": [
                               {
                                  "locale":"de-DE",
                                  "name":"Stadtführer"
                               }
                            ]
                         },
                         "catalogInfo": {
                            "type": "GOOGLE_PLAY_STORE",
                            "identifier": "com.cityguide.app"
                         },
                         "customSchemes": [
                            "cityguide://",
                            "ctgd://"
                         ],
                         "domains": [
                            "cityguide.com",
                            "ctgd.com"
                         ],
                         "androidCustomIntents": [
                            {
                               "component": "com.someapp.SomeActivity",
                               "action": "com.someapp.SOME_ACTION"
                            }
                         ]
                      }
                   ],
                   "linkedWebDomains": [
                      "grubbhouse.com",
                      "amazon.com",
                      "yahoo.com"
                   ],
                   "linkedCommonSchemes": {
                      "IOS_APP_STORE": [
                         "MAPS",
                         "TEL"
                      ],
                      "GOOGLE_PLAY_STORE": [
                         "MAPS",
                         "TEL"
                      ]
                   },
                   "linkedAndroidCommonIntents": [
                      {
                         "intentName": "SHOW_IN_MAP",
                         "catalogType": "GOOGLE_PLAY_STORE"
                      }
                   ]
                }
    ================== ALEXA FOR APPS ADDITIONS END ==================
             }
          }
       }
    }
    
  5. To be able to send push notifications in the non-mobile flow, your skill also needs to declare the skill permission "alexa::devices:app:push_notifications" inside the permissions array in your skill manifest, as shown in the following example.
    "permissions": [
       {
         "name": "alexa::devices:app:push_notifications"
       }
    ],
    
  6. For mobile-specific commands, you can update the description and examplePhrases attributes for your skill. You can update these attributes directly in the manifest.publishingInformation.locales section of your skill manifest. Or, if you prefer, you can update this information in the Alexa developer console at any time before you test and publish your skill. Be sure to let users know what mobile apps your skill can access, and provide sample utterances that work on mobile. If the skill only works on mobile devices, be sure to customers know that as well. The following example shows how to update these attributes for the City Guide skill.

    {
       "locales": {
          "en-US": {
             "name": "City Guide",
             "smallIconUri": "<s3 link>",
             "largeIconUri": "<s3 link>",
             "summary": "Find your way with City Guide!",
             "description": "Search faster with City Guide on mobile devices! Try saying, Alexa, ask City Guide to search for boba! Asking Alexa for walking directions, now also shortcuts you into the app to see the live tracking map!",
             "examplePhrases": [
                "Alexa, ask City Guide for coffee shops near me",
                "Alexa, ask City Guide for the bus schedule",
                "Alexa, ask City Guide for walking directions to My Favorite Landmark!"
             ],
             "keywords": []
          },
       }
    }
    

    To minimize utterance conflicts, use the pattern "Ask <skill name> to <do action>" in your example phrases, even if "<Do Action> in <app name>" flows better.

  7. To upload the updated skill manifest for your custom skill, use the update-skill-manifest CLI command as follows.
    ask smapi update-skill-manifest -s <skill-id> -g <stage> --manifest <manifest>
    

Step 2: Edit your skill endpoint to send deep links

In this step, your skill examines each incoming request to determine whether it originated from a device that supports Alexa for Apps. It also examines the originating platform (Android or iOS) and locale.

To edit your skill endpoint to send deep links

  1. To make sure the customer's device supports Alexa for Apps, check whether the context.System.device.SupportedInterfaces object includes an AppLink field, with the following structure:
       "AppLink": {
          "version": "2.0"
       }
    
  2. When the incoming request comes from a mobile device, your skill can directly launch app links on the customer's phone. To determine whether this mobile experience is possible, check the AppLink.directLaunch field in the context object.

    In this example, the field includes the key IOS_APP_STORE, indicating that the request came from an iOS device. Note that the directLaunch.IOS_APP_STORE field value is an empty object. This indicates that the mobile (direct launch) experience is enabled.

    "AppLink": {
         "directLaunch": {
             "IOS_APP_STORE": {}
         }
     }
    

    In this example, the field includes the key GOOGLE_PLAY_STORE, indicating that the request came from an Android device. Note that the directLaunch.GOOGLE_PLAY_STORE field value is an empty object. This indicates that the mobile (direct launch) experience is enabled.

    "AppLink": {
         "directLaunch": {
             "GOOGLE_PLAY_STORE": {}
         }
     }
    
  3. When the incoming request comes from an Alexa-enabled device, such as an Amazon Echo Dot, your skill can send links to a customer's mobile device in a notification from the Alexa app. To determine whether it can do so, check the context.AppLink.sendToDevice object. The following example shows a skill that receives requests from iOS devices. Note that the directLaunch.IOS_APP_STORE and sendToDevice field values are empty objects. This indicates that both directLaunch and sendToDevice are enabled.

    {
    "version": "1.0",
    "session": {...},
    "context": {
       "System": {
          "device": {
             "deviceId": "string",
             "supportedInterfaces": {
                "AudioPlayer": {...},
    ================== ALEXA FOR APPS ADDITIONS START ==================
                 "AppLink": {
                    "version": "2.0"
                 },
    ================== ALEXA FOR APPS ADDITIONS END ====================
             }
          },
          "application": {
             "applicationId": "amzn1.ask.skill.[unique-value-here]"
          },
          "user": {...},
          "apiEndpoint": "https://api.amazonalexa.com",
          "apiAccessToken": "AxThk..."
       },
       "AudioPlayer": {...},
    ================== ALEXA FOR APPS ADDITIONS START ==================
       "AppLink": {
          "directLaunch": {
              "IOS_APP_STORE": {}
          },
          "sendToDevice": {}
       }
    ================== ALEXA FOR APPS ADDITIONS END ====================
    },
    "request": {...}
    
  4. If your skill sends different links for different locales, it should first determine the locale of the requesting device by checking the handlerInput.requestEnvelope.request.locale property.
  5. To send deep links to an app or website, your skill connection request must have a Connections.StartConnection directive in the response body. Along with the deep links, you also need to provide a topic. The topic is a prompt helps the customer know what the deep-link does (for example, "Check your messages" or "See your flight status"). You can also play TTS (response.outputSpeech) as you normally would in your skill response as part of the call to Alexa for Apps. For example, a travel skill might say, "Your flight is on time, leaving Los Angeles International Airport at 2:15 PM.". For more details on the connection request, see Alexa for Apps Skill Connection Request Reference. The following example shows a sample connection request:
    {
        "version": "1.0",
        "sessionAttributes": {},
        "response": {
            "outputSpeech": {
                ...
            },
            "card": {
                ...
            },
            "reprompt": {
                ...
            },
            "directives": [
    ================== ALEXA FOR APPS ADDITIONS START ==================
              {
                "type": "Connections.StartConnection",
                "uri": "connection://AMAZON.LinkApp/2",
                "input": {
                    "links": {
                        "IOS_APP_STORE": {
                            "primary": {
                                "UNIVERSAL_LINK": {
                                    "appIdentifier": "id123456789",
                                    "url": "https://www.cityguide.com/search/search_terms=coffee"
                                }
                            }
                        },
                        "GOOGLE_PLAY_STORE": {
                            "primary": {
                                "UNIVERSAL_LINK": {
                                    "appIdentifier": "com.cityguide.app",
                                    "url": "https://www.cityguide.com/search/search_terms=coffee"
                                }
                            }
                        }
                    },
                    "prompt": {
                        "topic": "see your search results"
                    }
                }
            }
    ================== ALEXA FOR APPS ADDITIONS END ====================
          ]
        }
    }   
    
  6. After the skill connection request is complete, your skill receives a response showing the success or failure of the primary deep link action and the fallback, along with a reason for failure cases. Your skill should always handle a SessionResumedRequest with the type ConnectionCompleted. In the success case where the customer had the app directly open on their phone (directLaunch), the skill can clean up and end so that the rest of the interaction occurs on the mobile app/website. If both the primary and fallback are unsuccessful on mobile, or any time a request is made on a non-mobile device, the customer can continue interaction in the skill. The following examples show sample responses for a successful direct launch request and a send-to-device request. For send-to-device requests, you can continue the session to interact with the customer.
    {
       "type": "SessionResumedRequest"
       "requestId": "<string>",
       "timestamp": "<string>",
       "locale": "<string>",
       "cause": {
          "type": "ConnectionCompleted",
          "token": "1234",
          "status": {
             "code": "200",
             "message": "OK"
          },
          "result": {
             "directLaunch": {
                "primary": {
                   "status": "SUCCESS"
                }
             }
          }
       }
    }
    
    {
       "type": "SessionResumedRequest"
       "requestId": "<string>",
       "timestamp": "<string>",
       "locale": "<string>",
       "cause": {
          "type": "ConnectionCompleted",
          "token": "1234",
          "status": {
             "code": "200",
             "message": "OK"
          },
          "result": {
             "sendToDevice": {
                "status": "SUCCESS"
             }
          }
       }
    }
    

    For details about the response payload, see Skill connection response reference.

Step 3: Test and publish your skill

Test your skill

Currently the Alexa developer console Test page doesn't send an AppLink object in the skill request. For end-to-end testing, you must test on a mobile device connected to a developer or beta account with access to the skill.

You can test your skill on any mobile device, by using one of three methods:

  • Using an Alexa Built-in Phone.
  • Using a Alexa mobile accessory, such as Echo Buds.
  • Directly from the Alexa mobile app.

You can test using the Alexa mobile app by making a request using the built-in wake capability or by tapping the Alexa icon.

For the mobile experience, we recommend that you test the following items:

  • Test that end-to-end use cases work as expected, including app-specific actions.
  • Test locked and unlocked devices.
  • Test with different locales that your skill supports.
  • Test fallback scenarios where the app isn't installed.
  • Test recovery scenarios where the deep link fails (for example, on an unsupported device type). Make sure that the deep link fails in a way that allows your skill to continue its interaction with the user.

For the non-mobile (Send to Phone) experience, we recommend that you test the following items:

  • Test that end-to-end use cases work as expected, including app-specific actions.
  • Test tapping push notifications. In order to receive a push notification, you need to:
    1. Enable Notifications in OS Settings for the Alexa App
    2. Enable Push Notification skill permission in the Alexa app's Skill Settings page for your skill.
  • Test tapping the home card in the Alexa app.
  • Test with different locales that your skill supports.
  • Test fallback scenarios where the app isn't installed.
  • Test recovery scenarios where the deep link fails (for example, if the mobile device doesn't have the app installed). Make sure the deep link fails in a way that allows your skill to continue its interaction with the user.

Certify and publish your skill