Overview

Using ID.me's verification technology, partners may target the following affinity groups with special benefits or offers.


Group Credential Name

Military

Troop ID

Students

Student ID

First Responders

Responder ID

Teachers

Teacher ID

Government Employees

Government ID

Getting Started

To get started with an integration you'll need to do the following.

  • Sign up for an ID.me developer account.
  • Register one organization for your company.
  • Register an application for each website property that will need access to verification data.
  • Contact partnersupport@id.me to setup the appropriate policies associated with the affinity groups you want to verifiy.
  • Place one or more ID.me verification buttons on your site for each group you wish to target.
  • Once users complete the verification flow at ID.me, send requests to ID.me's API to retrieve their group affiliation data.

You can reach us for support at any time by emailing partnersupport@id.me

API Terms of Use

Before you start using the API, we have a few guidelines that we'd like to tell you about. We encourage you to read the full API Terms of Use, but here are the bullet points:

  • ID.me users own their data.
  • ID.me is a user-centric, permissions based platform that requires explicit permission for each transmission of information from a user to a partner brand through ID.me.
  • You may not sell ID.me user data to third party sites.
  • You cannot replicate the core user experience of ID.me

Sample User Flows

The typical flow begins at one of our partner websites, where an end user may see an ID.me verification button during registration or in the checkout flow.

Step 1: Checking out at UnderArmour.com

Underarmour

When the user clicks a verification button, a popup window opens and they are taken to ID.me's website to verify their status in the selected group. Before verification begins the user must either sign in to an existing account or create a new account.

Step 2: Sign In to ID.me

Sign in

Step 3: Sign Up for ID.me

Sign up

Step 4: Military Verification

After authenticating, the next step is for the user to verify their affiliation with the selected group. They will be presented with a number of options to verify depending on the group. The following is an example of our military verification.

Mil verify

Note: If a user has an existing ID.me Wallet account that is verified they will skip the verification screen.

Step 5: User Consent

After a successful verification, the user is presented with a screen where they are asked to consent to the release of their data to the partner. The user will see exactly what data fields the partner will have access to.

Consent

If consent is granted, the user will be taken back to the partner website at the redirect URI specified by the partner during application registration. At this point it is up to the partner to apply the business logic on their site to grant the end user access to the specified benefit.

OAuth Overview

ID.me uses OAuth to provide authorized access to its API. We currently use OAuth 2 draft-22. This section describes how you can use the OAuth 2 protocol to to gain access to a user's group affiliation data. Requests to retrieve user data require an access_token that is used to query ID.me's REST API. These tokens are unique to a user and should be stored securely. Access tokens expire 5 minutes after being issued.


The following diagram shows an overview of the OAuth flow. The "RP" in this diagram stands for "Relying Party", a.k.a the partner.

Oauth flow

Integration Guide

Upon application registration, you will immediately have access to the application details page which will list the client_id and client_secret needed to configure your OAuth client.

Getting an access token

In order to get an access_token you must do the following:

  • Direct the user to ID.me's authorization endpoint
    • If the user is not signed in they will be asked to sign in or sign up.
    • After verifying their group affiliation the user will be asked to grant access to your app.
  • After access is granted, the server will redirect the user to your redirect_uri and you can retrieve the access_token in one of two ways:
    • Server-side (authorization code flow): Take the provided code parameter in the redirect and exchange it for an access_token by POSTing the code to our access token request endpoint.
    • Client-side: Instead of handling an authorization code, we include the access_token as a fragment (#) in the redirect. This method allows applications without any server component to receive an access_token with ease.

Server-side (Explicit) Flow

ID.me supports both a full page redirect to the authorization endpoint as well as a popup window. Once you have registered an application, sample code and documentation will be available on the application details page. The ability to upload your company logo and customize the colors of the buttons on the ID.me screen are also available.

Step 1. Direct users to the authorization endpoint

The client app must send the user to the authorization endpoint in order to initiate the OAuth process. At the authorization endpoint, the user authenticates on the ID.me server and then grants or denies access to the app.


The endpoint to be used for your app is available at the bottom of the app details page.

Endpoint

Authorization Endpoint
https://api.id.me/oauth/authorize

HTTP Request Method

GET

Parameters

Name Required Description
client_id

yes

The client identifier received during app registration. It is automatically generated and located in your application dashboard.

redirect_uri

yes

Where the user gets redirected after an authorizing an app. Set by the developer within the application dashboard.

response_type

yes

code

scope

yes

A parameter that defines the group affiliation you are requesting permission to access.


Possible values:
  • military
  • student
  • responder
  • government
  • teacher
Note: Your account must first be set up with policies to enable these scopes to be accepted.

Contact partnersupport@id.me if you receive errors regarding an invalid scope.

state

no

An optional parameter to carry through any server-specific state you need to, for example, protect against CSRF issues. This param will be passed back to your redirect URI untouched.

Example
https://api.id.me/oauth/authorize?client_id=ed455f0f4a05538bf53dedef0661446f&redirect_uri=http://example.com/callback&response_type=code&scope=military&state=488e864b

Step 2. Receive the authorization code

When the user completes the authorization process on ID.me, we will redirect the user to your redirect_uri with the authorization code parameter appended. This code is used to obtain an access token and is only valid for 5 minutes.


Redirect URI with code
http://example.com/callback?code=488e864b

Simply grab the code off of the URL fragment and you’re good to go. If the user chooses not to grant access to your app, you will receive an error response. See error examples here.

Step 3. Exchange the authorization code for an Access Token

Endpoint

Token Endpoint
https://api.id.me/oauth/token

HTTP Request Method

POST

Response Content Type

application/json

Parameters

Name Description
code

The authorization code that you received in the previous step

client_id

The client identifier received during app registration. It is automatically generated and located in your application dashboard.

client_secret

A secret identifier received during app registration. It is automatically generated and located in your application dashboard.

redirect_uri

Where the user gets redirected after an authorizing an app. Set by the developer within the application dashboard.

grant_type

The only supported value is currently authorization_code.

Example
curl -X POST -d "code=488e864b&client_id=ed455f0f4a05538bf53dedef0661446f&client_secret=da4ca0338450ae011a475bc105e0495c&redirect_uri=http://example.com/callback&grant_type=authorization_code" https://api.id.me/oauth/token

Step 4. Obtain the Access Token

Using the authorization code from the previous step, send a request to ID.me's Token Endpoint to retrieve the payload containing your access token and refresh token. Each token's expiration can be found in the payload. See error examples here.

Example Payload

{
  "access_token": "a0b1c2d3f4g5h6i7j8k9l0m1n2o3p4q5"
  "token_type": "bearer"
  "expires_in": "300"
  "refresh_token": "a0b1c2d3f4g5h6i7j8k9l0m1n2o3p4q5"
  "refresh_expires_in": "604800"
  "scope": "military"
}

Parameters

Name Description
access_token

A credential that is used with every API call, so ID.me recognizes that you have authorization to make that request.

token_type

Represents how an access_token will be generated and presented for resource access calls.

expires_in

Describes the lifetime of the access token in seconds.

refresh_token

Refresh tokens contain the information required to obtain a new access token.

refresh_expires_in

Describes the lifetime of the refresh token in seconds.

scope

Defines the group affiliation you are requesting permission to access.


Client-side (Implicit) Flow

If you are building an app that does not have a server component, you’ll notice that it’s impossible to complete step three above to receive your access_token without also having to ship your client secret. You should never ship your client secret onto devices you don’t control. Then how do you get an access_token? Well the smart folks in charge of the OAuth 2.0 spec anticipated this problem and created the Implicit Authentication Flow.

Step 1. Direct users to the authorization endpoint

The only difference from the server-side flow is that the response_type is token.


The endpoint to be used for your app is available at the bottom of the app details page.

Endpoint

Authorization Endpoint
https://api.id.me/oauth/authorize

HTTP Request Method

GET

Parameters

Name Required Description
client_id

yes

The client identifier received during app registration. It is automatically generated and located in your application dashboard.

redirect_uri

yes

Where the user gets redirected after an authorizing an app. Set by the developer within the application dashboard.

response_type

yes

token

scope

yes

A parameter that defines the group affiliation you are requesting permission to access.


Possible values:
  • military
  • student
  • responder
  • government
  • teacher
Note: Your account must first be set up with policies to enable these scopes to be accepted.

Contact partnersupport@id.me if you are receiving errors regarding an invalid scope.

Example
https://api.id.me/oauth/authorize?client_id=ed455f0f4a05538bf53dedef0661446f&redirect_uri=http://example.com/callback&response_type=token&scope=military

Step 2. Receive the access token

Once the user has authenticated and authorized your app, we’ll redirect them to your redirect_uri with the access_token in the url fragment.


Redirect URI with access token
http://example.com/callback#access_token=da4ca0338450ae011a475bc105e0495c&token_type=bearer&expires_in=300

Simply grab the access_token off of the URL fragment and you’re good to go. If the user chooses not to grant access to your app, you will receive an error response. See error examples here.


Refresh Token Flow

Refresh tokens carry the information necessary to get a new access token. A common use case includes getting a new access token after an old one has expired. Refresh tokens can also expire but are rather long-lived.

Step 1. Exchange the Refresh Token

Token Endpoint
https://api.id.me/oauth/token

HTTP Request Method

POST

Response Content Type

application/json

Parameters

Name Description
refresh_token

The refresh_token you received in the Server-side (Explicit) Flow

client_id

The client identifier received during app registration. It is automatically generated and can be found in your application dashboard.

client_secret

A secret identifier received during app registration. It is automatically generated and can be found in your application dashboard.

redirect_uri

Where the user gets redirected after an authorizing an app. Set by the developer within the application dashboard.

grant_type

The required value for the Refresh Token Flow is refresh_token.

Example
curl -X POST -d "refresh_token=e7c77fe1fd5ece9aaccb129f6dd39431&client_id=CLIENT-ID&client_secret=da4ca0338450ae011a475bc105e0495c&redirect_uri=http://example.com/callback&grant_type=refresh_token" https://api.id.me/oauth/token

Step 2. Obtain the new Access Token and Refresh Token

Using the refresh token from the previous step, send a request to ID.me's servers to retrieve the payload to obtain a new access token and refresh token. Each token's expiration can be found in the payload. See error examples here.

Example Payload

{
  "access_token": "a0b1c2d3f4g5h6i7j8k9l0m1n2o3p4q5"
  "token_type": "bearer"
  "expires_in": "300"
  "refresh_token": "e7c77fe1fd5ece9aaccb129f6dd39431"
  "refresh_expires_in": "604800"
  "scope": "military"
}

Parameters

Name Description
access_token

A credential that is used with every API call, so ID.me recognizes that you have authorization to make that request.

token_type

Represents how an access_token will be generated and presented for resource access calls.

expires_in

Describes the lifetime of the access token in seconds.

refresh_token

Refresh tokens contain the information required to obtain a new access token.

refresh_expires_in

Describes the lifetime of the refresh token in seconds.

scope

Defines the group affiliation you are requesting permission to access.


OAuth PKCE

Proof Key for Code Exchange (PKCE) is a specification that adds additional parameters to OAuth 2.0 Authorization and Access Token Requests.


When implemenenting OAuth 2.0 on native applications Authorization Code Grants are susceptible to authorization code interception. Upon interception, malicous attackers have the ability to exchange the authorization code for an Access Token.


With every authroization request, PKCE allows the Client to create an encrypted secret key called code_verifier to be compared with the code_challenge associated with the request.

PKCE Protocol

  • 1. Client creates and records a secret key called code_verifier with every authorization request.
  • 2. The code_verifier is transformed and referred to as the code_challenge.
  • 3. Client sends the code_challenge along with the Authorization Request.
  • 4. Server returns the authorization_code.
  • 5. Client sends the authorization_code and the code_verifier to the Access Token Endpoint.
  • 6. Server verifies code_verifier before returning the tokens.

An attacker who intercepts the authorization code is unable to redeem it for an access token, as they are not in possession of the code_verifier.


Please contact us to enable PKCE support for your native integration.

Production Overview

When you create an application it will initially be in sandbox mode. In sandbox mode you will have access to test data to ensure you have integrated with the ID.me platform properly. Once you've verified your application is working in sandbox mode you can request production access from your application's edit page by clicking "Request Production Mode". See the video below:

Production Launch Checklist

Endpoints

V3
V2

Protected REST endpoints can be access by making HTTP requests with the access token for a given user. The ID.me server will validate the access token to ensure it has not expired and that its scope covers the requested resource.


After receiving a successful verification response from the API, you should apply business logic to unlock the benefit you are offering to the end user. From a user experience perspective, it is recommended that you store the verified status in the user's session to keep the experience consistent in case the page is refreshed, the back button is pressed, etc. By hiding or disabling the button that inititiates the API call, you can prevent duplicate calls being made.


If you're writing an AJAX application, require a JSONP response, and would like to wrap our response with a callback, all you have to do is specify a callback parameter with the API call.


URI Type
https://api.id.me/api/public/v3/attributes.json?access_token=ACCESS_TOKEN
JSON
https://api.id.me/api/public/v3/attributes.json?access_token=ACCESS_TOKEN&callback=callbackFunction
JSONP

HTTP Method

GET

Response Content Type

application/json

Response

V3
V2

The response from ID.me's REST API attributes endpoint is returned in JSON format.

Example

{
  "attributes":[
    {
      "handle": "fname",
      "name": "First Name",
      "value": "Test"
    },
    {
      "handle": "lname",
      "name": "Last Name",
      "value": "User"
    },
    {
      "handle": "email",
      "name": "Email",
      "value": "test.user@id.me"
    },
    {
      "handle": "uuid",
      "name": "Unique Identifier",
      "value": "d733a89e2e634f04ac2fe66c97f71612"
    },
    {
      "handle": "zip",
      "name": "Zip Code",
      "value": "22102"
    }
  ],
  "status":[
    {
      "group": "military",
      "subgroups": ["Service Member"],
      "verified": true
    }
  ]
}

Values

The JSON response contains the verification status and attributes for the user. The specific attributes returned depend on your application configuration and needs.


Attributes
Handle Name Value Description
uuid

Unique Identifier

ID randomly generated and unique to user

fname

First Name

First name set by user

lname

Last Name

Last name set by user

email

Email

Unique email set by user

zip

Zip Code

Zip code set by user

These are typical response values. The data passed back depends on your application configuration.

Status
Parameter Description and Value Range
uuid

User unique identifier

fname

First name set by user

lname

Last name set by user

email

Unique email set by user

zip

Zip code set by user

group

Troop ID - military

Responder ID - responder

Government ID - government

Student ID - student

Teacher ID - teacher

subgroups

Troop ID - Service Member, Military Family, Military Spouse, Veteran, Retiree

Responder ID - EMT, Firefighter, Police Officer

Government ID - Federal, State, Local

Student ID - null

Teacher ID - null

verified

true or false

Transactions

Transactional data can be passed back in the JSON response as well. If you are interested in learning more about the value of transactional data and how to add this data to the JSON response, please contact us.

Errors

If the user denies the access request or if the request is invalid, the client will be informed using the following parameters appended to the redirect uri:

Parameters

Name Description
error

A single error code as described below.

error_description

A human-readable text providing additional information, used to assist in the understanding and resolution of the error occurred.

error_uri

A URI identifying a human-readable web page with information about the error, used to provide the end-user with additional information about the error.

Codes

Code Description
invalid_request

The request is missing a required parameter, includes an unsupported parameter or parameter value, or is otherwise malformed.

invalid_client

The client identifier provided is invalid.

unauthorized_client

The client is not authorized to use the requested response type.

redirect_uri_mismatch

The redirection URI provided does not match a pre-registered value.

access_denied

The end-user or authorization server denied the request.

unsupported_response_type

The requested response type is not supported by the authorization server.

invalid_scope

The requested scope is invalid, unknown, or malformed.

Client Libraries

ID.me has developed the following e-commerce platform extensions and libraries to ease the integration process.

Magento (PHP)

The official ID.me Magento plugin.

http://www.magentocommerce.com/magento-connect/troop-id-connect-4719.html

Demandware Link Cartridge

The official ID.me Demandware Link Cartridge.

https://s3.amazonaws.com/idme/developer/IDmeLinkCartridge-1.1.zip

Spree Commerce

An extension allowing any Spree store owner to offer promotions to verified members of ID.me

https://github.com/IDme/spree_idme

OmniAuth (Ruby/Rails)

Ruby gem that works with applications using OmniAuth .

https://github.com/IDme/omniauth-idme

jQuery App

View the full sample project on Github

Step 1. Add dependency

<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.0.min.js"></script>

Step 2. Configure your button(s)

These buttons redirect the user to ID.me's Access Token Endpoint to verify and generate an access token.

<span id="idme-wallet-button"
  data-scope="military"
  data-client-id="[YOUR_CLIENT_ID]"
  data-redirect="[YOUR_REDIRECT_URI]"
  data-text="[YOUR_OFFER_DESCRIPTION]"
  data-response="token"
  data-op="signin"
  data-show-verify="true">
</span>
<script src="https://s3.amazonaws.com/idme/developer/idme-buttons/assets/js/idme-wallet-button.js"></script>

Step 3. Call ID.me's API

Create an object for the parameters

var token = window.location.hash.split("&")[0].match(/[^#access_token=]w+/)[0];

var parameters = {
  url      : "https://api.id.me/api/public/v3/attributes.json?access_token=" + token,
  dataType : "jsonp"
};

Make a $.get request and on .done, based on the verified attributes, display a message in console.log that the user is verified.

var payload = $.get(parameters).done(function(response) {
  payload = response;

  if (payload.status[0].verified) {
    console.log("User verified!")
  }
});

You can check the user's attributes and verification statuses from the payload["attributes"] and payload["status"] arrays.

PHP Web App

View the full sample project on Github

Step 1. Add dependencies

Add the oauth2-client dependency to your composer.json and install with php composer.phar install

{
    "require": {
      "league/oauth2-client": "^1.1"
    }
}

Step 2. Configure your client settings and secrets

$provider = new \league\oauth2\client\provider\genericprovider([
    'clientid'                => 'YOUR_CLIENT_ID',
    'clientsecret'            => 'YOUR_CLIENT_SECRET',
    'redirecturi'             => 'YOUR_REDIRECT_URI',
    'urlauthorize'            => 'https://api.id.me/oauth/authorize',
    'urlaccesstoken'          => 'https://api.id.me/oauth/token',
    'urlresourceownerdetails' => 'https://api.id.me/api/public/v2/attributes.json'
]);

Step 3. Redirect the user to ID.me's OAuth 2.0 server

Generate the authorization endpoint URL

$authorizationUrl = $provider->getAuthorizationUrl();

Redirect the user to $authorizationUrl

header('Location: ' . filter_var($authorizationUrl, FILTER_SANITIZE_URL));
exit;

Step 4. Exchange the code for an access token

Use the getAccessToken method to exchange the authorization code for an access token

$accessToken = $provider->getAccessToken('authorization_code', [
    'code' => $_GET['code'], 'scope' => 'military'
]);

Step 5. Call ID.me's API

Use the access token to call ID.me's API and retrieve the user's attributes

$payload = $provider->getResourceOwner($accessToken)->toArray();

You can check the user's attributes via $payload['verified'] and $payload['affiliation']

Python Web App

View the full sample project on Github

Step 1. Add dependencies

Add the requests-oauthlib dependency to your requirements.txt and run pip install -r requirements.txt

requests-oauthlib

Step 2. Configure your client settings and secrets

client_id              = 'YOUR_CLIENT_ID'
client_secret          = 'YOUR_CLIENT_SECRET'
redirect_uri           = 'YOUR_REDIRECT_URI'
authorization_base_url = 'https://api.id.me/oauth/authorize'
token_url              = 'https://api.id.me/oauth/token'
attributes_url         = 'https://api.id.me/api/public/v2/attributes.json'
scope                  = ['YOUR_SCOPE_VALUE']

Step 3. Redirect the user to ID.me's OAuth 2.0 server

Generate the authorization endpoint URL

idme = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url = idme.authorization_url(authorization_base_url)

Redirect the user to the authorization_url

redirect(authorization_url)

Step 4. Exchange the code for an access token

Use the fetch_token method to exchange the authorization code for an access token

token = idme.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url)

Step 5. Call ID.me's API

Use the access token to call ID.me's API and retrieve the user's attributes

idme = OAuth2Session(client_id, token=token)
payload = idme.get('attributes_url').json()

You can check the user's attributes via payload['verified'] and payload['affiliation']

Mobile SDKs

ID.me Web Verify (iOS)

A library that verifies a user's group affiliation through a modal UIWebView. Please contact us for access.

ID.me Web Verify (Android)

A library that verifies a user's group affiliation through a WebView activity. Please contact us for access.