Welcome to ID.me for developers! If you are interested in integrating ID.me, you are in the right place. Here we will cover how to get started implementing ID.me.

OpenID Connect Integration

ID.me uses OpenID Connect (OIDC) to provide authorized access to its API. We currently use OAuth 2 draft-22. OpenID Connect is an open authentication protocol that works on top of the OAuth 2 framework. This section describes how you can use OpenID Connect to gain access to a user's data. Requests to retrieve user data require an access_token along with an id_token which are used to query ID.me's REST API. These tokens are unique to a user and should be stored securely. An access_token expires 5 minutes after being issued.

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 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.

Authorization Endpoint

<div id="idme-verification">
  <a href="https://api.id.me/oauth/authorize?client_id=[YOUR_CLIENT_ID]&redirect_uri=[YOUR_REDIRECT_URI]&response_type=code&scope=openid http://idmanagement.gov/ns/assurance/ial/2/aal/2/erx&state=488e864b&nonce=123456">
    <img src="https://s3.amazonaws.com/idme/developer/idme-buttons/assets/img/signin.svg" height="50"/>
  </a>
  <p>
    ID.me is our trusted technology partner in helping to keep your personal information safe. They specialize in digital identity protection and help
    us make sure you're you—and not someone pretending to be you—before we give you access to your information.
    <a href="https://www.id.me/about">Learn more about ID.me</a>.
  </p>
</div>

Authorization Endpoint

The api.id.me/oauth/authorize endpoint is used begin an authorization to allow a user to authenticate and allow an organization get access to a user's verification credential.

Parameters

Name Description
client_id The client identifier received during app registration. It is automatically generated and located in your application dashboard.
scope A parameter that defines the policy you are requesting permission to access.
Supported values include:
  • openid
  • redirect_uri Where the user gets redirected after an authorizing an app. Set by the developer within the application dashboard.
    response_type Determines the authorization type.
    Supported values include:
  • code
  • token
  • id_token
  • code id_token
  • code token
  • id_token token
  • code id_token token
  • state 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.
    op An optional parameter that triggers sign in or sign up once redirected to ID.me.
    Supported values include:
  • signin
  • signup
  • nonce An optional parameter value needs to include per-session state and be unguessable to attackers. One method to achieve this for Web Server Clients is to store a cryptographically random value as an HttpOnly session cookie and use a cryptographic hash of the value as the nonce parameter. In that case, once in the returned ID Token is compared to the hash of the session cookie to detect ID Token replay by third parties. A related method applicable to JavaScript Clients is to store the cryptographically random value in HTML5 local storage and use a cryptographic hash of this value.

    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.

    Redirect URI with code example

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

    Step 3: Exchange Authorization Code For Token Payload

    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.

    CURL Example

    curl -X POST -d "code=488e864b&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=REDIRECT_URI&grant_type=authorization_code" https://api.id.me/oauth/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 Payload

    {
      "access_token": "a0b1c2d3f4g5h6i7j8k9l0m1n2o3p4q5",
      "token_type": "bearer",
      "expires_in": "300",
      "refresh_token": "e7c77fe1fd5ece9aaccb129f6dd39431",
      "refresh_expires_in": "604800",
      "scope": "kba_replacement",
      "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IktBTGVzSUpVVTRuQ0FjLVJTdTJkS0xkYkgtQmFrdXRnekE1VjdoQm9RUm8ifQ.eyJpc3MiO\niJodHRwczovL2FwaS5pZG1lbGFicy5jb20vb2lkYyIsInN1YiI6ImYxNjljMzRkMDA3YjQ1MTBhNzNiYTc5OThjMDgxZWEwIiwiYXVkIjoiZTE3OWUzNT\nc3NTAzMjBlMmU2NTJjODBiNjFjNGRjMDIiLCJleHAiOjE2MjU1MTI3ODQsImlhdCI6MTYyNTQ5NDc4NCwiZW1haWwiOiJ0ZXN0aW5nQGlkLm1lIiwiZm5\nhbWUiOiJURVNUIiwibG5hbWUiOiJVU0VSIiwiemlwIjoiMjIxMDIiLCJ1dWlkIjoiZjE2OWMzNGQwMDdiNDUxMGE3M2JhNzk5OGMwODFlYTAifQ.Qwdnb\nAn6kbnzSvASa8qEMTJO-T-jzkJAfJdLViX188N2ny1DLBjn1AxgsydXmnzeyCtfv9Mn-rjLFtsEAPXMbWoA5maU0Lqt03hbSEbvevksr6xzD0j9mzQdWb\n3YXHkSS-A3dKkl4KM5TiO7BY8W5Xmhp0YivtcW2_C24xdxukYBgR1Y6lmjaKS3SGQRkjO31mj8_qxlAP4RuC9U2cmHx-w2HYVJfwpyauzmM8uo6CD3Ql3\nqCP88bcyJtF2O9cEpvW9E47CcaueGLjBF9_Qe0u1IWzcX77rCTnxMounfjmYDn7Md0JAl6-Q6E23yu-Zibg8CFytmDDm4pGbEA7g8BA"
    }

    Key Descriptions

    Name Description
    id_token A JSON Web Token(JWT)
    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 policy you are requesting permission to access

    Step 4: Validate the ID Token

    Now, we need to validate that the ID Token sent was from the correct place by validating the JWT's signature.

    Example JSON Web Token (JWT)

    eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IktBTGVzSUpVVTRuQ0FjLVJTdTJkS0xkYkgtQmFrdXRnekE1VjdoQm9RUm8ifQ.eyJpc3MiO
    iJodHRwczovL2FwaS5pZG1lbGFicy5jb20vb2lkYyIsInN1YiI6ImYxNjljMzRkMDA3YjQ1MTBhNzNiYTc5OThjMDgxZWEwIiwiYXVkIjoiZTE3OWUzNT
    c3NTAzMjBlMmU2NTJjODBiNjFjNGRjMDIiLCJleHAiOjE2MjU1MTI3ODQsImlhdCI6MTYyNTQ5NDc4NCwiZW1haWwiOiJ0ZXN0aW5nQGlkLm1lIiwiZm5
    hbWUiOiJURVNUIiwibG5hbWUiOiJVU0VSIiwiemlwIjoiMjIxMDIiLCJ1dWlkIjoiZjE2OWMzNGQwMDdiNDUxMGE3M2JhNzk5OGMwODFlYTAifQ.Qwdnb
    An6kbnzSvASa8qEMTJO-T-jzkJAfJdLViX188N2ny1DLBjn1AxgsydXmnzeyCtfv9Mn-rjLFtsEAPXMbWoA5maU0Lqt03hbSEbvevksr6xzD0j9mzQdWb
    3YXHkSS-A3dKkl4KM5TiO7BY8W5Xmhp0YivtcW2_C24xdxukYBgR1Y6lmjaKS3SGQRkjO31mj8_qxlAP4RuC9U2cmHx-w2HYVJfwpyauzmM8uo6CD3Ql3
    qCP88bcyJtF2O9cEpvW9E47CcaueGLjBF9_Qe0u1IWzcX77rCTnxMounfjmYDn7Md0JAl6-Q6E23yu-Zibg8CFytmDDm4pGbEA7g8BA

    This token is cryptographically signed with the RS256 algorithim. We'll use the public key of the OpenID Connect server to validate it. In order to do that, we'll fetch the public key from https://api.idmelabs.com/oidc/.well-known/jwks, which is found in the discovery document or configuration menu options.

    Step 5: Decode ID Token For User Payload

    The ID token contains information about a user and their authentication status. The following steps will describe how to decode the ID token , available in JSON Web Token (JWT) format , to get the required information about the user:

    Python Example

    import base64
    
    encoded_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IktBTGVzSUpVVTRuQ0FjLVJTdTJkS0xkYkgtQmFrdXRnekE1VjdoQm9RUm
                    8ifQ.eyJpc3MiOiJodHRwczovL2FwaS5pZG1lbGFicy5jb20vb2lkYyIsInN1YiI6ImYxNjljMzRkMDA3YjQ1MTBhNzNiYTc5OThjMD
                    gxZWEwIiwiYXVkIjoiZTE3OWUzNTc3NTAzMjBlMmU2NTJjODBiNjFjNGRjMDIiLCJleHAiOjE2MjU1MTI3ODQsImlhdCI6MTYyNTQ5N
                    Dc4NCwiZW1haWwiOiJ0ZXN0aW5nQGlkLm1lIiwiZm5hbWUiOiJWRVJPTklDQSIsImxuYW1lIjoiUEVSU0lOR0VSIiwiemlwIjoiMjIx
                    MDIiLCJ1dWlkIjoiZjE2OWMzNGQwMDdiNDUxMGE3M2JhNzk5OGMwODFlYTAifQ.QwdnbAn6kbnzSvASa8qEMTJO-T-jzkJAfJdLViX1
                    88N2ny1DLBjn1AxgsydXmnzeyCtfv9Mn-rjLFtsEAPXMbWoA5maU0Lqt03hbSEbvevksr6xzD0j9mzQdWb3YXHkSS-A3dKkl4KM5TiO
                    7BY8W5Xmhp0YivtcW2_C24xdxukYBgR1Y6lmjaKS3SGQRkjO31mj8_qxlAP4RuC9U2cmHx-w2HYVJfwpyauzmM8uo6CD3Ql3qCP88bc
                    yJtF2O9cEpvW9E47CcaueGLjBF9_Qe0u1IWzcX77rCTnxMounfjmYDn7Md0JAl6-Q6E23yu-Zibg8CFytmDDm4pGbEA7g8BA=="
    
    split_token = encoded_token.split(".")
    
    encoded_header = split_token[0]
    encoded_payload = split_token[1]
    
    decoded_payload = base64.b64decode(encoded_payload)
    
    print(decoded_payload)

    Decoded Header Payload Example

    {
      "typ": "JWT",
      "alg": "RS256",
      "kid": "KALesIJUU4nCAc-RSu2dKLdbH-BakutgzA5V7hBoQRo"
    }

    Key Description

    Name Description
    typ The Type Header Parameter is used by JWT applications to declare the media type of this complete JWT.
    alg The Algorithm Header Parameter is used by JWT applications to declare the algorithm type of this complete JWT.
    kid An optional header claim which holds a key identifier, particularly useful when you have multiple keys to sign the tokens and you need to look up the right one to verify the signature.

    Decode ID Token Payload Example

    {
      "iss": "https://api.idmelabs.com/oidc",
      "sub": "f169c34d007b4510a73ba7998c081ea0",
      "aud": "8749d197447c364b219afbd4b613ebd0",
      "exp": 1616364069,
      "iat": 1616346069,
      "email": "ricky.cruickshank@id.me",
      "fname": "Ricky",
      "lname": "Cruickshank",
      "street": "9594 John Spur",
      "city": "Ricefort",
      "state": "New York",
      "zip": "10630-6978",
      "birthdate": "1974-01-25",
      "uuid": "d733a89e2e634f04ac2fe66c97f71612"
    }

    Key Descriptions

    Name Description
    iss The Type Header Parameter is used by JWT applications to declare the media type of this complete JWT.
    sub The Algorithm Header Parameter is used by JWT applications to declare the algorithm type of this complete JWT.
    aud An optional header claim which holds a key identifier, particularly useful when you have multiple keys to sign the tokens and you need to look up the right one to verify the signature.
    exp An optional header claim which holds a key identifier, particularly useful when you have multiple keys to sign the tokens and you need to look up the right one to verify the signature.
    iat An optional header claim which holds a key identifier, particularly useful when you have multiple keys to sign the tokens and you need to look up the right one to verify the signature.
    uuid An optional header claim which holds a key identifier, particularly useful when you have multiple keys to sign the tokens and you need to look up the right one to verify the signature.

    Step 6: Exchange Access Token For ID Token (OPTIONAL)

    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.

    CURL Example

    curl -X GET -d "access_token=488e864b" https://api.id.me/api/public/v3/userinfo
    Endpoint
    https://api.id.me/api/public/v3/userinfo
    HTTP Request Method
    GET

    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.
    callback 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.
    Production Requirements

    Please follow the two steps outlined below. Note that you are responsible for ensuring that all implementations of the ID.me brand assets comply with accessibility requirements (example: Section 508 minimum color contrast requirements & WCAG guidelines). Visit https://webaim.org for more information.

    Step 1

    Verify your integration meets ID.me brand requirements and guidelines. For reference, please visit https://developers.id.me/brand-assets.

    Step 2

    Verify your integration makes an API request upon retrieving the access_token from ID.me.

    Step 3

    Verify all test credentials provided are generating the expected results based on configuration.

    Step 4

    Verify your platform digests and maps the verification data to the appropriate user and presents success messaging.

    Step 5

    Verify your ID.me application is in production mode and does not display "Sandbox Mode" to users.

    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.
    invalid_redirect_uri 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.