Overview

This guide introduces the ID.me OAuth 2.0 implementation and explains how partners can use it to access user data securely.

ID.me uses OAuth 2.0 RFC 6749 to authorize access to its APIs. To retrieve a user’s community data, your application must obtain an access_token. This token is user-specific, should be stored securely, and expires 5 minutes after issuance.

ID.me supports both full-page redirects and popup windows for the authorization flow. Once you’ve registered your application, you’ll find sample code, documentation, and the option to upload your company logo on the application details page.

Prerequisites

You will need an ID.me developer account to obtain the following:

  • Client ID
  • Client Secret
  • Redirect URI

Direct users to authorization endpoint

To begin the OAuth flow, your client application must direct the user to the ID.me authorization endpoint. There, the user signs in to ID.me and is prompted to grant or deny access to your application.

Authorization endpoint

1https://api.id.me/oauth/authorize?client\_id=CLIENT\_ID&redirect\_uri=REDIRECT\_URI&response\_type=code&scope=SCOPE&state=optional&eid=FOO-bar-123
Important

Replace the CLIENT_ID, REDIRECT_URI, and SCOPE with your inputs

Parameters

NameDescriptionSupported values
client_idThe client identifier received during app registration. It is automatically generated and located in your application dashboard
scopeA parameter that defines the policy you are requesting permission to accessView full list
redirect_uriWhere the user gets redirected after authorizing an app. Set by the developer within the application dashboard.
response_typeDetermines the authorization typecode
stateAn 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.
opAn optional param that triggerssignin, signup
eidAn optional parameter to carry through any external identifiers you want returned in the payload response

Optional ID.me widget

1<span
2 id='idme-wallet-button'
3 data-scope='SCOPE'
4 data-client-id='CLIENT_ID'
5 data-redirect='REDIRECT_URI'
6 data-response='code'>
7</span>
8<script src='https://s3.amazonaws.com/idme/developer/idme-buttons/assets/js/idme-wallet-button.js'></script>

Receive the authorization code

Once the user completes the authorization process on ID.me, they will be redirected to your redirect_uri with the authorization code parameter appended.

Redirect URI with code example

1https://example.com/callback?code=488e864b

Exchange authorization code for access token

After the user authorizes your application, exchange the authorization code for an access_token and refresh_token by sending a request to ID.me’s token endpoint. The response payload includes both tokens and their expiration times.

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

  • Method: POST

  • Response type: application/JSON

Parameters

NameDescription
codeThe authorization code that you received in the previous step
client_idThe client identifier received during app registration. It is automatically generated and located in your application dashboard.
client_secretA secret identifier received during app registration. It is automatically generated and located in your application dashboard.
redirect_uriWhere the user is redirected after authorizing an app. Set by the developer within the application dashboard.
grant_typeThe only supported value is authorization_code

CURL example

1curl -X POST -d
2"code=488e864b&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=REDIRECT_URI&grant_type=authorization_code"
3https://api.id.me/oauth/token
Important

Replace the CLIENT_ID, REDIRECT_URI, and SCOPE with your inputs

Obtain access token

Parameters

NameDescription
access_tokenIncluded with every API request so that ID.me can verify your application’s authorization to access user data
token_typeRepresents how an access_token will be generated and presented for resource access calls
expires_inDescribes the lifetime of the access_token in seconds
refresh_tokenContains the information required to obtain a new access_token
refresh_expires_inDescribes the lifetime of the refresh_token in seconds
scopeDefines the policy you are requesting permission to access

Example payload

1{
2 "access_token" : "a0b1c2d3f4g5h6i7j8k9l0m1n2o3p4q5",
3 "token_type" : "bearer",
4 "expires_in" : "300",
5 "refresh_token" : "e7c77fe1fd5ece9aaccb129f6dd39431",
6 "refresh_expires_in" : "604800",
7 "scope" : "military"
8}

Exchange access token for user data

To retrieve user data, make an HTTP GET request to the protected endpoint below. Include the access_token in the request. ID.me will validate the token to ensure it’s valid and has the required scope.

  • Endpoint: https://api.id.me/api/public/v3/attributes.json

  • Method: GET

  • Response type: application/JSON

Parameters

NameDescription
access_tokenA token included with each API call that allows ID.me to verify your application’s authorization
callbackIf your AJAX application requires a JSON response, include a callback parameter in the API call to wrap the response

Example payload

1{
2 "attributes": [
3 {
4 "handle": "fname",
5 "name": "First Name",
6 "value": "Sean"
7 },
8 {
9 "handle": "lname",
10 "name": "Last Name",
11 "value": "Moen"
12 },
13 {
14 "handle": "email",
15 "name": "Email",
16 "value": "sean.moen@id.me"
17 },
18 {
19 "handle": "uuid",
20 "name": "Unique Identifier",
21 "value": "d733a89e2e634f04ac2fe66c97f71612"
22 },
23 {
24 "handle": "zip",
25 "name": "Zip Code",
26 "value": "44058-1478"
27 },
28 {
29 "handle": "eid",
30 "name": "External Identifier",
31 "value": "FOO-bar-123"
32 }
33 ],
34 "status": [
35 {
36 "group": "military",
37 "subgroups": [
38 "Service Member"
39 ],
40 "verified": true
41 }
42 ]
43}

Parse the JSON response

Properly parsing the JSON response is essential for building a scalable integration. How your application handles the response determines whether it can gracefully support future changes, such as the addition of new attributes, without breaking.

Best practice
  • Use object handles to index attribute values
  • Validate only attributes that are currently returned
  • Store raw JSON responses for auditing and debugging
  • Create a database table to store verification status, UUID, and authoritative data from the ID.me API
  • Use the uuid as a foreign key to link ID.me user activity across your application
  • Pre-fill form fields to streamline the post-verification user experience

Example data types

The attribute type determines what data type will be returned from ID.me’s REST API. The following data types are expected from ID.me’s REST API:

String
1{
2 "handle": "email",
3 "name": "Email",
4 "value": "testing@id.me"
5}
Integer
1{
2 "handle": "age",
3 "name": "Age",
4 "value": 21
5}
Array
1{
2 "handle": "covid_vaccine_records",
3 "name": "Covid Vaccine Records",
4 "value": [
5 {
6 "brand": "Pfizer",
7 "date": "2022-01-01T00:00:00-05:00",
8 "type": "primary"
9 },
10 {
11 "brand": "Pfizer",
12 "date": "2022-02-02T00:00:00-05:00",
13 "type": "primary"
14 }
15 ]
16}
Object
1{
2 "handle": "previous_addresses",
3 "name": "Previous address(es) if available",
4 "value": [
5 {
6 "normalized_street": "8281 Greensboro Drive",
7 "street1": "8281 Greensboro Drive",
8 "street2": "",
9 "city": "West McLean",
10 "state": "VA",
11 "province": "",
12 "zip": "22102",
13 "country": "US",
14 "normalized": "false",
15 "primary": "false"
16 },
17 {
18 "normalized_street": "6647 WILDFLOWER DR S",
19 "street1": "6647 WILDFLOWER DR S",
20 "street2": "",
21 "city": "COTTAGE GROVE",
22 "state": "MN",
23 "province": "",
24 "zip": "55016",
25 "country": "US",
26 "normalized": "false",
27 "primary": "false"
28 }
29 ]
30}
Important

Do NOT expect all attribute values to be a string