Tutorial: Add Alexa for Apps 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.

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. If you haven't already, install the ASK CLI as described in Quick Start: Alexa Skills Kit Command Line Interface (ASK CLI).
  2. Open the command prompt.
  3. To download the skill manifest for your custom skill to a new file named skill.json, enter the string for the get-skill-manifest CLI command as shown in the following example:

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

  4. 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"
       },
    
  5. 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 ==================
             }
          }
       }
    }
    
  6. To be able to send push notifications in the non-mobile flow, 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"
       }
    ],
    
  7. For mobile-specific commands, update the description and examplePhrases attributes for your skill in the manifest.publishingInformation.locales section of your skill manifest. Or update this information in the Alexa developer console at any time before you test and publish your skill. Make sure to let customers 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 let your 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": []
          },
       }
    }
    
  8. To upload the updated skill manifest for your custom skill, use the update-skill-manifest CLI command as shown in the following example.
    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. Your skill 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"
       }
    

    When the incoming request comes from a mobile device, your skill can directly launch app links on the customer's phone.

  2. To determine whether this mobile experience is possible, check the AppLink.directLaunch field in the context object.

    In the following example, the field includes the key IOS_APP_STORE, indicating that the request came from an iOS device.

    Note: 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 the following example, the field includes the key GOOGLE_PLAY_STORE, indicating that the request came from an Android device.

    Note: 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": {}
         }
     }
    

    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.

  3. To determine whether your skill can send links, check the context.AppLink.sendToDevice object.

    The following example shows a skill that receives requests from iOS devices.

    Note: 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, have your skill 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, place a Connections.StartConnection directive in the response body of your skill connection request.

  6. Along with the deep links, provide a topic, which is a prompt that helps the customer know what the deep-link does (for example, "Check your messages" or "See your flight status").

  7. (Optional) Play text-to-speech (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 ====================
          ]
        }
    }   
    
  8. 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 or 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 your Alexa for Apps 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 an 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.

To test your skill on a mobile device

  • For the mobile experience, 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 customer hasn't installed the app.
    • 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 customer.

To test your skill in a non-mobile experience

  • For the non-mobile (Send to Phone) experience, test the following items:
    • Test that end-to-end use cases work as expected, including app-specific actions.
    • Test tapping push notifications. To receive a push notification, you must:
      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 that the deep link fails in a way that allows your skill to continue its interaction with the customer.