Add PIN Confirmation to Alexa Skills

For Alexa skills, personalization refers to providing personalized experiences for recognized skill users. For example, Alexa can provide personalized greetings and prompts for recognized speakers. Another way to personalize a skill is to give your users the option of using a PIN to control access to your skill. For example, if your skill implements personalization, and the Alexa user is a recognized speaker with a voice profile and Personalize skills enabled in the Alexa app, a ride-hailing skill might use PIN confirmation in the following way:

User: Alexa, order me a ride to the Space Needle.
Alexa: A ride to the Space Needle will cost five dollars and take ten minutes. Ready to book it?
User: Yes.
Alexa: Ok, <user name>. What's your profile PIN?
User: One two three four.
Alexa: Great. Your driver will arrive in eight minutes.

When the skill needs to confirm the profile PIN of the user, the skill passes control to Alexa by using an Alexa feature called skill connections. Alexa interacts with the user to handle the PIN confirmation process and then passes control back to the skill with a success or failure status so that the skill can handle the outcome accordingly.

Prerequisites

To use PIN confirmation, your skill must meet the following requirements:

The user must meet the following requirements:

  • The user must have a voice profile and profile PIN in the Alexa app. For details, see Manage skill personalization as a user.
  • If the skill supports account linking, the account must be linked to a specific user, rather than to a shared account. That is, the linked account can't be the Amazon account to which the device is registered; it must be to a specific user.

User flow for PIN confirmation

The user flow depends on whether your skill configuration specifies PIN confirmation as mandatory or optional, as follows:

  • Mandatory – If you configure the skill such that PIN confirmation is mandatory, the user must set up PIN confirmation before they can use the skill. The user can't opt out of PIN confirmation.
  • Optional – If you configure the skill such that PIN confirmation is optional, the user can use the Alexa app to opt in to PIN confirmation for a particular skill. In this case, the user only needs to confirm their profile PIN if they have enabled PIN confirmation for the skill.

User flow for the mandatory case

If you configure your skill such that PIN confirmation is mandatory, the user experience is as follows:

  1. The user enables your skill on the detail page of the skill.
  2. The user goes through the account linking flow to link their account to the skill.
  3. If the user hasn't set up a profile PIN and voice profile, there is guidance for the user to set up a profile PIN and voice profile.

User flow for the optional case

If you configure your skill such that PIN confirmation is optional, the user experience is as follows:

  1. The user enables your skill on the detail page of the skill.
  2. The user goes through the account linking flow to link their account to the skill.
  3. The user turns on the PIN confirmation toggle on the skill setting page in the Alexa app.
  4. If the user hasn't set up a profile PIN and voice profile, there is guidance for the user to set up a profile PIN and voice profile.

Steps to implement PIN confirmation in your skill

To implement PIN confirmation in your skill, take the following steps:

  1. Create a custom skill.
  2. Enable PIN confirmation, personalization, and account linking for your skill.
  3. Use PIN confirmation in your skill code.
  4. Test your implementation.
  5. Certify your skill.

Step 1: Create a custom skill

Create a custom skill. For details, see Understand Custom Skills or Steps to Build a Custom Skill.

Step 2: Enable PIN confirmation, personalization, and account linking for your skill

To enable PIN confirmation, personalization, and account linking for your skill, set the relevant options in the developer console as follows.

To enable PIN confirmation, personalization, and account linking for a skill

  1. Log in to the Alexa Skills Kit developer console.
  2. From the skill list, select your skill.
  3. In the left pane, click TOOLS, and then click Permissions.
  4. On the Permissions page, enable PIN Confirmation and select whether you would like PIN confirmation to be mandatory or optional. These options are as follows:
    • Mandatory – If you configure the skill such that PIN confirmation is mandatory, the user must set up PIN confirmation before they can use the skill. The user can't opt out of PIN confirmation.
    • Optional – If you configure the skill such that PIN confirmation is optional, the user can use the Alexa app to opt in to PIN confirmation for a particular skill. In this case, the user only needs to confirm their profile PIN if they have enabled PIN confirmation for the skill.
  5. On the Permissions page, enable Skills Personalization.
  6. On the TOOLS > Account linking page of the developer console, enable account linking and fill in the required options.
    You must also implement account linking in your skill code. For implementation details, see Steps to Implement Account Linking.

Step 3: Use PIN confirmation in your skill code

In your skill code, do the following:

For details about the fields, see API reference.

Step 4: Test your implementation

Use the developer console to test your implementation as follows:

To test your implementation

  1. Enable testing for your skill as follows:
    1. Log in to the Alexa Skills Kit developer console.
    2. From the skill list, select your skill.
    3. At the top, click the Test tab.
    4. On the left, under the header bar, for Skill testing is enabled in, select Development.
  2. As an Alexa user, enable your skill in the skill store and follow the prompts to set up a voice profile, account linking, and profile PIN.
  3. On an Echo device, test your skill with different scenarios such as a failed, retried, and successful PIN confirmation. Also try different user account configurations, such as a test account with no voice profile, a voice profile without Personalize skills enabled, and so on.

Step 5: Certify your skill

After you build your skill and test it with your account, you can submit your skill for certification. For details about certifying a custom skill, see Certification Requirements.

API reference for PIN confirmation

To start the PIN confirmation experience, your skill sends a Connections.StartConnection directive from a request handler. After the PIN confirmation skill connections task is complete, your skill receives a SessionResumedRequest request.

The skill connection fields specific to PIN confirmation are described in the following sections:

For general information about skill connections, see Use Skill Connections to Request Tasks.

Connections.StartConnection directive format

The following is a sample Connections.StartConnection directive that you use to pass control to Alexa. You put this directive in a response to a request from Alexa.

{
   "type": "Connections.StartConnection",
   "uri": "connection://AMAZON.VerifyPerson/2",
   "input": {
      "requestedAuthenticationConfidenceLevel": {
         "level": 400,
         "customPolicy": {
            "policyName": "VOICE_PIN"
         }
      }   
   }
}

Connections.StartConnection fields

The following sections describe the fields within the Connections.StartConnection directive.

Name Required? Type Description
type Yes

String

Directive type. Set this to Connections.StartConnection.

uri Yes

String

Resource that defines the task and the task version. Set this to connection://AMAZON.VerifyPerson/2.

input Yes

Object

An object that contains information about the task request. For details, see input object.

token No

String

A token that is returned to the skill as-is in the SessionResumedRequest. You can use the token to resume the skill after the task is complete.

input object

Name Required? Type Description

requestedAuthenticationConfidenceLevel

Yes

Object

An object that specifies the desired confidence level of Alexa when attempting to identify the speaker. For details, see requestedAuthenticationConfidenceLevel object.

requestedAuthenticationConfidenceLevel object

Name Required? Type Description

level

Yes

Integer

The requested confidence level of Alexa when attempting to identify the speaker.

Currently, 400 is the only supported value. For descriptions of confidence levels, see Authentication confidence levels.

customPolicy

Yes

Object

An object that identifies the custom policy to initiate PIN confirmation. For details, see Custom policy object.

Custom policy object

Name Required? Type Description

policyName

Yes

String

An indication of how the user is confirmed to the requested confidence level. Currently, only VOICE_PIN is supported. For details, see Policy name.

Authentication confidence levels

Authentication confidence levels are part of an Alexa solution that simplifies how skills receive information about the confidence of Alexa in the identity of a speaker.

Level Level Definition

400

The speaker is verified by both a profile PIN and voice recognition.

Below 400

The speaker is identified by voice recognition. For details, see Authentication confidence levels for skill personalization.

Policy name

Policy Policy Definition

VOICE_PIN

By applying this policy, the speaker is always confirmed with a profile PIN and medium/high accuracy voice recognition. This policy only applies to the 400 authentication confidence level.

SessionResumedRequest format

After the PIN confirmation is complete, your skill receives the results of the PIN confirmation in a SessionResumedRequest. You can find the details of the response payload in the cause.result field of the SessionResumedRequest.

{
   "context": {
      "System": {
         ...
         "person": {
            "authenticationConfidenceLevel": {
               "level": 300
            },
            "accessToken": "Atza|AAAAAAAA...",
            "personId": "amzn1.ask.person.*",
         }
         ...
      }
      ....
   },
   ....
   "request": {
      "type": "SessionResumedRequest",
      ....
      "cause": {
         "type": "ConnectionCompleted",
         "token": "some connection token data",
         "status": {
            "code": "200",
            "message": "User didn't set up profile PIN."
         },
         "result": {
            "status": "NOT_ACHIEVED",
            "reason": "PREREQUISITE_NOT_SETUP_ERROR"
         }
      }
   }
}

Click the following button for an example of a full SessionResumedRequest sent to the skill after PIN confirmation.

SessionResumedRequest fields

The following sections describe the fields within the cause object of the SessionResumedRequest.

cause object

Name Type Description

type

String

The type of SessionResumedRequest, which is ConnectionCompleted in this case.

token

String

A string that the Connections.StartConnection directive included. You can use this token to resume the skill after the task request is complete.

status

Object

A status code and message. For details, see status object.

result

Object

The outcome of the PIN confirmation. For details, see result object.

status object

Name Type Description

code

String

An HTTP status code that Alexa provides to your skill after fulfilling the task request. Possible values:

  • 200 – Alexa successfully fulfilled the request. However, the requested authentication confidence may or may not have been achieved.
  • 400 – Bad request. The request was invalid.
  • 403 – The requester was not allowed to invoke provider. This error might occur because you didn't configure PIN confirmation for the skill as described in Enable PIN confirmation, personalization, and account linking for your skill.
  • 404 – There are no providers available at this time.
  • 500 – Server error.

message

String

A message that describes the outcome of the request.

result object

Name Type Description

status

String enum

Enum string that indicates the result of the PIN confirmation. In all cases, the status code is 200. Valid values:

  • ACHIEVED – PIN confirmation succeeded.
  • NOT_ACHIEVED – PIN confirmation attempt failed.
  • NOT_ENABLED – The user didn't enable PIN confirmation for this skill. This value only applies to optional PIN confirmation.

reason

String enum

Optional. When the status is NOT_ACHIEVED, this field contains the reason why PIN confirmation was not achieved. Valid values:

  • METHOD_LOCKOUT – The user failed PIN confirmation too many times and the PIN confirmation method has been locked out.
  • VERIFICATION_METHOD_NOT_SETUP – The user hasn't set up a profile PIN.
  • NOT_MATCH – The user hasn't set up a voice profile or Alexa failed to match the user with a voice profile.

person object

You can get the person object for the person who is confirmed from the context.System object of the skill request, as shown in the following example.

{
   "version": "1.0",
   "session": {
    .....
   },
   "context": {
      "System": {
         ...
         "person": {
            "authenticationConfidenceLevel": {
               "level": 400
            },
            "accessToken": "Atza|AAAAAAAA...",
            "personId": "amzn1.ask.person.*"
         }
      ...
    }
    ....
  },
  "request": {
    ...
  }
}

For an example of the person object within a full response, see SessionResumedRequest format.

Name Type Description

authenticationConfidenceLevel

Object

Object indicates the actual achieved confidence level. For details, see authenticationConfidenceLevel object.

accessToken

String

A token that identifies the user in another system. This value is only provided if the user has successfully linked their account. For details, see Understand Account Linking.

personId

String

The ID of the person.

authenticationConfidenceLevel object

Name Type Description

level

Integer

Achieved level of authentication confidence. This value might be different from the requested confidence level. For example, if a skill requests a confidence level of 400, the response might report that the confidence level is 200. For descriptions of confidence levels, see Authentication confidence levels.

Implement PIN confirmation in your skill code

Your skill enforces PIN confirmation by using skill connections. Skill connections is an Alexa feature that enables a skill to use another skill or service to perform a specific task. A requester (in this case, your skill) uses a skill connection to request a task, which is then fulfilled by a provider (in this case, Alexa). Alexa interacts with the user and returns control to your skill after the task is complete. Skill connections works as follows:

  • To pass control to Alexa by using skill connections, the skill sends a Connections.StartConnection directive.
  • To pass control back to the skill after confirming the profile PIN, Alexa sends a SessionResumedRequest to the skill.

For details about using skill connections, see Use Skill Connections to Request Tasks.

The following example shows when control is passed from the skill to Alexa and then back to the skill when the user orders a car through a ride-hailing skill. This example is for demonstration purposes only. When you implement PIN confirmation, you can alter the dialog for the skill, but Amazon controls the dialog for Alexa.

Step Actor Speaker Speech or Action

1

Skill

User

"Alexa, order me a ride to the Space Needle."

2

Skill

Alexa

"A ride to the Space Needle will cost five dollars and take ten minutes. Ready to book it?"

3

Skill

User

"Yes."

4

Skill

Alexa

"Ok, <user name>."

5

Skill

N/A

The skill sends a Connections.StartConnection directive to pass control to Alexa through skill connections.

6

Alexa

Alexa

"What's your profile PIN?"

7

Alexa

User

"One two three four."

8

Alexa

N/A

A successful PIN confirmation sound plays, and Alexa sends the skill a SessionResumedRequest request to pass control back to the skill.

9

Skill

Alexa

"Great. Your driver will arrive in eight minutes.

Send a Connections.StartConnection directive

After the user makes a request that requires PIN confirmation, have your skill pass control to Alexa by returning a Connections.StartConnection directive in the response object. Your skill code must leave the shouldEndSession flag undefined when it returns a Connections.StartConnection directive.

The following example shows how to implement a handler to return a Connections.StartConnection directive. For details about the fields, see API reference for PIN confirmation.

return handlerInput.responseBuilder
   .addDirective({
      'type': 'Connections.StartConnection',
      'uri': 'connection://AMAZON.VerifyPerson/2',
      'input': {
         'requestedAuthenticationConfidenceLevel': {
            'level': 400,
            "customPolicy": {
               "policyName": "VOICE_PIN"
            }            
         }
      },
      'token': 'example-token',
   })
   .getResponse();

Receive a SessionResumedRequest

After attempting to confirm the profile PIN, Alexa sends the result of Connections.StartConnection to your skill by using a SessionResumedRequest that includes the result of the PIN confirmation.

The following code shows how to handle a session resumed request.

Copied to clipboard.

/**
 * Handler to handle SessionResumedRequest.
 */
const SessionResumedRequestHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'SessionResumedRequest';
    },
    handle(handlerInput) {
        const connectionsStatus = handlerInput.requestEnvelope.request.cause.status;
        const connectionsCode = connectionsStatus.code;
        const person = handlerInput.requestEnvelope.context.System.person;
        
        // First, check to see if the skill connection attempt completed successfully.
        // This does not tell us if the task was successful or not; we will check that next.
        if (connectionsCode != 200) {
            const speechText = "Sorry, something went wrong while verifying your identity.";
            return handlerInput.responseBuilder
                .speak(speechText)
                .getResponse();
        }        
        // Now check to see if the user passed or failed verification.
        const verificationTaskResult = handlerInput.requestEnvelope.request.cause.result;
        const verificationTaskStatus = verificationTaskResult.status;        
            if (verificationTaskStatus == 'ACHIEVED') {
            // The verification request was successful and the user was successfully verified to the desired ACL.            
            // Perform your business logic personal access token.
            performBusinessLogic(person.accessToken);
            // You can add a greeting to the response as well.
            speechText = "<alexa:name type='first' personId='" + person.personId + "'/>"
                + ", you were verified and your request was completed.";
        } else if (verificationTaskStatus == 'NOT_ENABLED') {
            // The skill has PIN confirmation set to optional and the user opted to disable PIN confirmation.
            // This block serves as a reminder that you should handle this case if your skill is set to Optional.            
            performBusinessLogic(person.accessToken);
            speechText = "Your request was completed.";
        } else {
            // We were not able to successfully reach our desired ACL.
            // Person info may be in the request envelope with a lower ACL than what is requested.
            // You could potentially use this if you wanted to have a fallback experience for a lower ACL.            
            // For this demo, we will just fail the request.
            speechText = "Sorry, verification failed. Your request was not completed.";
        }        
        return handlerInput.responseBuilder
            .speak(speechText)
            .getResponse();
    }
};

Developer support

For inquiries and support, please reach out to the Alexa Identity team at alexa-personal-identity-support@amazon.com.