Individual Access Services (IAS)

A guide on integrating OIDC in compliance with Carequality and TEFCA specifications

This integration is tailored for healthcare exchanges, ensuring compliance with the TEFCA and Carequality specification for interoperability.

Overview

The following health data specifications have been adopted to achieve the goal of establishing a common set of principles and guidelines that enable qualified health information networks (QHINs) to securely and efficiently share patient data.

Carequality acts as a nationwide interoperability framework that connects healthcare organizations, allowing them to exchange health information seamlessly. In contrast,TEFCA is a policy initiative designed to create a standardized approach for data sharing across the entire healthcare ecosystem. It aims to unify various networks under a single framework, facilitating broader interoperability and enhancing the security and privacy of health information.

Adhering to these standards is crucial for secure and compliant data sharing. By aligning with Carequality and TEFCA, healthcare organizations can ensure they are meeting regulatory requirements, protecting patient privacy, and fostering trust in their data exchange processes. These standards not only enhance the security of data transactions but also promote a more integrated and efficient healthcare system.

Implementation

Setting up a Client for use with QHINs

Before getting started, ensure you have communicated with your CLEAR representative that you intend to use the Individual Access token. You will be required to have a registered oid before a production client can be created.

  • oid (Registered with HL7)

IAS providers must have an HL7 OID registered with their participating network (TEFCA / Carequality).

If the IAS Provider is functioning as a channel partner to a downstream client the OID must either (a) be owned by the client AND registered within the participating network or (b) be owned by the IAS provider or (c) registered as a sub-participant of the IAS provider.

Updates to the OID

Changing the OID will require end user re-verification. Refresh tokens are NOT transferable to a different OID even if that OID is within the same organization. Refresh tokens are coupled to the OID, not the organization.

Setting up and IAL2 project

An IAL2 level project will be created to define the user flow as a lower level assurance user flow will not be acceptable. To set up an IAL2 flow with our IAL2 specifications, simply apply the IAL2 template when making a project.

Once these details are finalized, we will supply you with the following credentials to complete your integration.

To set up your client, first navigate to the CLEAR1 Admin Console.

  1. Access the ‘Integrations’ page from the left sidebar.
  2. Go to the ‘OpenID Connect’ tab on the top-center of the Integrations page.
  3. Click the ‘Add Client ID & Secret’ button on the top right.
  4. For a integrations requiring a Carequality or TEFCA token, click ‘Carequality or TEFCA’
  5. Select the project that you would like to apply your integration to
  6. Enter your Object Identifier (OID)
  7. Select which type of token you would like to configure; either TEFCA or Carequality
  8. Copy and paste your Client Secret. Please keep your secret in a secure place as it is only visible at the point of creation.
  9. Enter the URIs to be added to your URI allowlist.
  10. Once you’re done creating your Client - Secret pair, you will see the Client in your OpenID Connect list.

Authorization Code

To initiate the OAuth flow, direct the user to the following URL, which includes the client ID, redirect URI, scope, and a state parameter:

https://verified.clearme.com/integrations/oauth2/auth?response_type=code&client_id=urn%3Aoid%3A1.11.222.2.333333.4.4444.5.5.55555.6&state=teststate&redirect_uri=https%3A%2F%2Fwww.your-redirect.com&scope=offline%20openid%20offline_access&code_challenge={{code_challenge}}&code_challenge_method=S256

Upon completion of the verification flow, the user will be redirected with an authorization code. This code must be parsed from the URL and used to perform the token exchange.

Token Request

KeyExample Value
client_idurn:oid:1.11.222.2.333333.4.4444.5.5.55555.6
client_secretxxxxxxxuuuuuuuYYYYYYY
scopeoffline openid offline_access
redirect_urihttps://www.your-redirect.com
grant_type["authorization_code", "refresh_token"]
code_challengexxxxxxxuuuuzzzYYYYYYY

code_verifier is optional . For more information refer to PKCE support detailed below.

curl --location 'https://verified.clearme.com/integrations/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: ' \
--data-urlencode 'client_id={{client_id}}' \
--data-urlencode 'client_secret={{client_secret}}' \
--data-urlencode 'scope=offline openid offline_access' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri={{redirect_uri}}' \
--data-urlencode 'code={{code}}'

The response from this exchange will include both an access token and an identity token as base64-encoded JSON Web Tokens (JWT). Below is an example of a decoded access and identity token.

The aud claim is CLEAR’s OID or object identifier. The other claims represent the verified user’s demographic information. The identity token should be decoded to parse the member attribute claims.

The core difference between the TEFCA and Carequality tokens is how the individual’s date of birth is presented. TEFCA lists the date of birth as birthdate whereas Carequality lists it as date_of_birth


Sample decoded access token

{
  "aud": [],
  "client_id": "57e32725-3d13-4856-8f60-c3e15ace5ece",
  "com": {
    "clearme": {
      "partner_scoped_user_id": "MuI6y9LrsROKX1NOWy2wXtZeV03YguxBPaixhECRCO"
    }
  },
  "exp": 1770234595,
  "iat": 1770230994,
  "iss": "https://verified.clearme.com/integrations",
  "jti": "7ec5f606-7c58-4fdc-8f0b-ee0f0e0fcfa8",
  "scp": [
    "offline",
    "openid",
    "offline_access"
  ],
  "sub": "MuI6y9LrsROKX1NOWy2wXtZeV03YguxBPaixhECRCO",
  "verification_completed_at": "2026-02-04T18:49:28",
  "verification_id": "verify_vZqN5rmDTn5R0LETdYHyvwkTQb0zjL8l",
  "verification_is_sandbox": true,
  "verification_status": "success"
}

Sample decoded TEFCA identity token

{
  "address": {
    "country": "US",
    "formatted": "3268 WEST JOHNSON ST., APT 117, GARLAND, TX 75043 US",
    "locality": "GARLAND",
    "postal_code": "75043",
    "region": "TX",
    "street_address": "3268 WEST JOHNSON ST., APT 117"
  },
  "at_hash": "dArDDmXxxyFMvauvrB7Bww",
  "aud": ["urn:oid:1.11.111.1.111111.1.1111"],
  "auth_time": 1757103061,
  "birthdate": "1987-09-12",
  "email": "[email protected]",
  "exp": 1757106679,
  "family_name": "LOPEZ",
  "gender": "F",
  "given_name": "CAMILA",
  "historical_address": [
    {
      "formatted": "458 STREICH STREET, LUNENBURG, MA 01462",
      "locality": "LUNENBURG",
      "postal_code": "01462",
      "region": "MA",
      "street_address": "458 STREICH STREET"
    },
    {
      "formatted": "3268 WEST JOHNSON STREET, APT 117, GARLAND, TX 75043",
      "locality": "GARLAND",
      "postal_code": "75043",
      "region": "TX",
      "street_address": "3268 WEST JOHNSON STREET, APT 117"
    },
    {
      "formatted": "7324 ROOSEVELT AVE, INDIANAPOLIS, IN 46201",
      "locality": "INDIANAPOLIS",
      "postal_code": "46201",
      "region": "IN",
      "street_address": "7324 ROOSEVELT AVE"
    }
  ],
  "iat": 1757103079,
  "iss": "https://verified.clearme.com/integrations",
  "jti": "9be1a686-7200-4592-9d74-a6b2acbabf74",
  "middle_initial": "M",
  "middle_name": "MARIA",
  "nickname": "Unknown",
  "phone_number": "+14694694321",
  "phone_number_verified": true,
  "rat": 1757103020,
  "sid": "adad163c-a8e0-4114-93f8-2590f5fe4ab7",
  "sub": "LbRV8ruRc7S9qzFeZzlKfgy78ImucDAnhfs8niXprW"
}

Sample decoded Carequality identity token

{
  "address": {
    "country": "USA",
    "formatted": "123 Test St, Apt. A, Test City, NY 12345 USA",
    "locality": "Test City",
    "postal_code": "12345",
    "region": "NY",
    "street_address": "123 Test St, Apt. A"
  },
  "at_hash": "edQsjDAXbATGDMiGzWl0Og",
  "aud": [
    "oidccarequality051325"
  ],
  "auth_time": 1747159339,
  "date_of_birth": "1990-01-01",
  "email": "[email protected]",
  "exp": 1747162949,
  "family_name": "Doe",
  "given_name": "John",
  "iat": 1747159349,
  "iss": "https://verified.clearme.com",
  "jti": "3f658aa3-8f3a-4937-a938-0939e081a6ba",
  "phone_number": "+14082222222",
  "rat": 1741109878,
  "sex": "M",
  "sid": "8ea33d63-4aad-44a3-b200-17ab494de757",
  "sub": "AI3H0LE6dsU78fpHhPWOlNzy98vYoNKZ0M73EhbxFN"
}


Validating the Tokens

This token can be transmitted to health exchanges to query patient information. The receiving party must validate the token to ensure its integrity. To perform this validation, they should call the following endpoint:

HTTP GET 
https://verified.clearme.com/integrations/.well-known/jwks.json

This endpoint returns the public key associated with the private key used to sign the token. You can use an open-source JWT library to verify the token with the exposed public key.

Verification Result

Successful verification: A successful verification will return an access_token and an identity_token in the response. CLEAR will only ever return an identity_token if the demographics within the identity_token have been validated. The access_token can then be used to make a request to the Get Verification Session endpoint to understand the details of the successful verification session

Unsuccessful verification: An unsuccessful verification will return an access_token only, as the user demographics could not be verified. The access_token can then be used to make a request to the Get Verification Session endpoint to understand the details of the failed verification session.

Cancelled verification: A cancelled verification will return an access_token only, as the user demographics were not collected to completion and/or validated. In the event an access_token is returned the only path a user could have taken to cancel the verification session would have been to decline consent.

Abandoned verification: An abandoned verification will not return any token, as the user has abandoned the workflow so no redirect can take place for the auth code to be passed.


Example of canceled verification access token

{
  "aud": [],
  "client_id": "57e32725-3d13-4856-8f60-c3e15ace5ece",
  "com": {
    "clearme": {
      "partner_scoped_user_id": null
    }
  },
  "exp": 1765494295,
  "iat": 1765490695,
  "iss": "https://verified.clearme.com/integrations",
  "jti": "f36c9dff-63cb-432d-bf8a-5abe1c2b7b02",
  "scp": [
    "offline",
    "offline_access"
  ],
  "sub": "unknown",
  "verification_completed_at": null,
  "verification_id": "verify_uHYO9fF38uoVHorEEF50d44WUBxAs0Zq",
  "verification_is_sandbox": true,
  "verification_status": "canceled"
}

Historical Addresses

To enable historical addresses, as shown in in the TEFCA token above, please contact your CLEAR representative. Historical addresses can be returned with any integration pattern to improve patient matching with QHINs and health systems.


Authorization with PKCE

PKCE (Proof Key for Code Exchange) is an added security measure build on top of the existing authorization code flow. Incorporating PKCE adds a client-generated secret called the code_verifier, which is later used by the authorization server to validate the token exchange.

A derived value, known as the code_challenge, is sent in the authorization request, and the original code_verifier is later used by the authorization server to validate the token exchange.

To add PKCE, append:

Authorization URL

  • code_challenge= {{code_challenge}}
  • code_challenge_method= S256

Token Request

  • code_verifier = {{code_verifier}}

SHA-256 is the recommended algorithm for code challenge generation. For best practices refer to RFC-7636 Section-4.1

Using the Get Verification Session API

Once the token exchange has completed the access_token and the verification_id (a claim within the access_token) can be utilized to pull the session details.

Whether the verification was successful or unsuccessful any session can be retrieved to gain more information about the user and session to aid identity proofing decisioning and user support.

curl https://verified.clearme.com/v1/verification_sessions/{{verification_id}}?reveal_sensitive_data=true \
  -H 'Authorization: Bearer {{access_token}}'

Example Response

{
    "id": "verify_5oooo22ddXXEL3YvvsXS1111dFccc3vv",
    "object_name": "verification_session",
    "activated_authentication_methods": [],
    "authenticated": true,
    "authentication_methods": [
        "sms"
    ],
    "check_metadata": [],
    "checks": [
        {
            "name": "Age on Gov ID is 18 or over",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID back is not suspicious",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID captured image is acceptable",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID country is not blocklisted",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID front is not suspicious",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID full name was extracted",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID is likely authentic",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID is not expired",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID last name matches phone number",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID type is an eligible document type",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Gov ID was processed",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Selfie matches portrait on Gov ID",
            "value": true,
            "status": "completed"
        },
        {
            "name": "Selfie passes liveness check",
            "value": true,
            "status": "completed"
        }
    ],
    "collected_traits": null,
    "completed_at": 1761677082,
    "created_at": 1761677036,
    "custom_fields": {
        "test_id": null
    },
    "email": "[email protected]",
    "expires_at": 1762541036,
    "fields_to_collect": [],
    "idv_status": "success",
    "ip": [
        "55.00.177.111"
    ],
    "is_data_granted": null,
    "phone": "+12171233608",
    "project_id": "project_XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "redirect_url": "https://verified.clearme.com/verify/oauth2/callback",
    "report_id": null,
    "sessions": [
        {
            "location": {
                "country": "United States",
                "country_iso": "US",
                "subdivision": null,
                "subdivision_type": null,
                "city": "Ashburn",
                "lat": "39.04372",
                "lon": "-77.48749",
                "ip": "52.70.177.110"
            },
            "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
            "created_at": 1761677037,
            "ip": "55.00.177.111",
            "locale": "en-US",
            "zoneinfo": "America/New_York"
        }
    ],
    "status": "success",
    "token": "verify_5oooo22ddXXEL3YvvsXS1111dFccc3vv",
    "traits": {
        "address": {
            "line1": "742 Evergreen Terrace",
            "line2": null,
            "city": "Madison",
            "state": "WI",
            "postal_code": "53711",
            "country": "US"
        },
        "email": "[email protected]",
        "phone": "+12171233608",
        "document": {
            "document_type": "drivers_license",
            "issuing_country": "USA",
            "issuing_subdivision": "NJ",
            "document_number": "1537331",
            "date_of_expiry": {
                "day": 24,
                "month": 12,
                "year": 2031
            },
            "gender": "M",
            "address": {
                "line1": "742 EVERGREEN TERRACE",
                "line2": null,
                "city": "MADISON",
                "state": "WI",
                "postal_code": "53711",
                "country": "US"
            },
            "date_of_birth": {
                "day": 9,
                "month": 2,
                "year": 1975
            },
            "first_name": "HOMER",
            "last_name": "SIMPSON",
            "middle_name": "J"
        },
        "document_front": "",
        "parsed_fields": [
            "name",
            "dob",
            "address"
        ],
        "face_scan_preview": "",
    },
    "updated_at": 1761677082,
    "user_agent": [
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
    ],
    "user_created": true,
    "user_id": "T100000000000000000000000000000000000"
}

Security Considerations

When extracting claims from a token, it's essential to follow best practices to ensure security, reliability, and proper handling of user data. Here are some key best practices:

Validate the Token

Always validate the token before extracting claims. Check the token's signature to ensure it was issued by CLEAR and hasn't been tampered with. Verify the token's expiration (exp) and issued-at (iat) claims to ensure it is still valid.

Check the Audience (aud)

Confirm that the token's aud claim matches your client ID. This ensures the token is intended for your application.

Verify the Issuer (iss)

Ensure the iss claim matches CLEAR's domain, https://verified.clearme.com, confirming the token's origin.

Handle Claims Securely

Extract only the claims necessary for your application's functionality to minimize data exposure.
Be cautious with sensitive data, such as email addresses and phone numbers, and ensure compliance with privacy regulations.

Logging and Monitoring

Log token validation attempts and monitor for unusual activity, such as repeated validation failures, which may indicate attempted attacks.

Employ the State Parameter

Utilize the state parameter in OAuth flows to prevent cross-site request forgery (CSRF) attacks. This parameter should contain a unique value for each session and be validated upon return to ensure the response is from a legitimate source.

By adhering to these best practices, you can enhance the security of your integration and effectively use claims from tokens while maintaining a secure and reliable application environment.

Additional Resources


Implementation

Continue to the Implementation Guides for next steps in building your CLEAR integration:



Did this page help you?