FlexpaFlexpa
Developer PortalGet a DemoTry it yourself

Guides

  • Home
  • Quickstart
  • Claims data guide
  • Financial data guide
  • Parsing FHIR data

Agents

  • Health records for agents
  • Health tools for agentsNew

Network

  • Network guide
  • Endpoint directory
  • CHPL directory

Consent

  • OAuth
  • Patient linking
  • Usage patterns
  • Patient access

Records

  • FHIR API
  • Webhooks
  • DestinationsNew
  • Data Sheet
  • Node SDK
  • SMART Health Links API
  • SMART Health Check-inNew
  • Terminology
  • Claims to clinical

Misc

  • ChangelogNew
  • Support
  • Flexpa OS
  • We're hiring

Bring Your Own Identity

Not yet available — preview specification. Bring Your Own Identity (BYOI) is an early-access capability that has not shipped yet. The POST /link/par endpoint described below is not currently live, and this page is a preview specification subject to change. The endpoint, request shape, and supported credential service providers may change before general availability. To register interest or get notified when BYOI launches, contact partnerships@flexpa.com.

Bring Your Own Identity lets partners that already operate IAL2 identity-proofing infrastructure — for example CLEAR, ID.me, or Persona — reuse that work when launching Flexpa Consent. Instead of redirecting the patient through Flexpa's own identity step, your backend submits the credential service provider's signed ID token to Flexpa over a server-to-server Pushed Authorization Request (RFC 9126) and receives a one-shot request_uri it can launch Consent with. The patient lands inside the flow already identity-proofed and proceeds directly to facility selection.

BYOI is available for TEFCA / IAL2 flows only. Payer and provider flows continue to use the standard OAuth authorization endpoint.


#How it works

  1. Your backend proofs the patient with your credential service provider (CSP) and receives an IAL2 ID token. This step is out of scope for Flexpa.
  2. Your backend POSTs the OAuth parameters and the CSP-issued ID token to /link/par.
  3. Flexpa verifies the token signature against the CSP's JWKS, checks the IAL2 claims, and stores the authorization parameters under a single-use request_uri.
  4. Your application redirects the patient's browser to /oauth/authorize with the request_uri returned by Flexpa.
  5. Flexpa consumes the request_uri, skips its own identity step, and starts the consent workflow with the patient's verified demographics already populated.
  6. The patient proceeds through TEFCA discovery, selects a facility, and is redirected back to your redirect_uri with an authorization code.
  7. Your backend exchanges the code at /oauth/token for a Patient Access Token — the same exchange used by any other Consent flow.

The CSP is selected automatically by Flexpa from the iss claim of the submitted ID token. There is no separate idp parameter — submitting a token from a CSP that is not on the server-side allowlist is rejected with invalid_token.


#What you need

  • A pair of API Keys from the Flexpa Portal with BYOI enabled on the application. BYOI is gated per-application; contact partnerships@flexpa.com to enable it.
  • A TEFCA license on your application.
  • An existing relationship with a supported credential service provider — CLEAR, ID.me, or Persona — that can issue an IAL2 ID token for the patient.
  • A redirect_uri registered in the Flexpa Portal.

#The CSP-issued ID token

The ID token your CSP issues for the patient must be a signed JWT and must carry the claims Flexpa needs to assert IAL2 identity proofing. Flexpa runs the same validation here as it does on the standard CLEAR, ID.me, and Persona callbacks.

Required claims

issstringRequired

The CSP's issuer URL. Used to select the JWKS for signature verification and to route the request. Must be on Flexpa's server-side allowlist.

substringRequired

The CSP's stable identifier for the patient.

audstringRequired

The audience the CSP issued the token for. Must equal the healthcare identifier (HCID) assigned to your application by Flexpa.

acrstringRequired

The Authentication Context Class Reference asserting IAL2. Must contain ial/2.

auth_timenumberRequired

Unix time at which the patient was authenticated by the CSP. Tokens older than the configured freshness window (30 minutes by default) are rejected.

given_namestringRequired

The patient's given (first) name.

family_namestringRequired

The patient's family (last) name.

birthdatestringRequired

The patient's date of birth in YYYY-MM-DD format.

jtistring

Unique token identifier. Used by Flexpa for replay protection.

Flexpa accepts the CSP-issued ID token via the standard OpenID Connect id_token_hint parameter. Token signatures are verified against the CSP's published JWKS using RS256 or ES256.

Decoded ID token (example)

{
  "iss": "https://idp.clearme.com",
  "sub": "auth0|68d2…",
  "aud": "hcid_flexpa_application_id",
  "acr": "urn:clear:ial/2",
  "auth_time": 1719240000,
  "jti": "c4f9a1e2-7c4d-4d6e-8f3a-1b2c3d4e5f60",
  "given_name": "Jane",
  "family_name": "Doe",
  "birthdate": "1985-04-12",
  "iat": 1719240000,
  "exp": 1719243600
}

#Supported credential service providers

Flexpa routes incoming tokens by the iss claim against a server-side allowlist. At launch, BYOI supports the same three CSPs the standard Flexpa Consent identity step uses:

IssuerProviderJWKS
https://idp.clearme.comCLEARhttps://idp.clearme.com/.well-known/jwks.json
https://api.id.meID.mehttps://api.id.me/oidc/.well-known/jwks
https://withpersona.comPersonahttps://withpersona.com/.well-known/jwks.json

If you operate your own IAL2 proofing pipeline and would like to assert identity with a partner-signed token, contact partnerships@flexpa.com.


#Pushed Authorization Request

Submit the OAuth authorization parameters along with the CSP-issued ID token. Flexpa verifies the token, stores the parameters, and returns a one-shot request_uri you can launch Flexpa Consent with.

The request body is application/x-www-form-urlencoded and follows RFC 9126.

Request headers

AuthorizationstringRequired

HTTP Basic credentials — your publishable key (pk_*) and secret key (sk_*) concatenated with a colon and base64-encoded. The key pair must belong to the application BYOI is enabled on.

Content-TypestringRequired

Must be application/x-www-form-urlencoded.

Request body

client_idstringRequired

Your publishable key. Must match the key used in the Authorization header.

response_typestringRequired

Must be code for the authorization code flow.

redirect_uristringRequired

Where Flexpa will redirect the patient after authorization. Must be registered in the Flexpa Portal.

scopestringRequired

Space-separated OAuth scopes. Must include launch/patient. Add offline_access for MULTIPLE usage.

code_challengestringRequired

The PKCE code challenge (BASE64URL(SHA256(verifier))) generated by your client. See Generate PKCE.

code_challenge_methodstringRequired

Must be S256.

id_token_hintstringRequired

The signed IAL2 ID token issued by your credential service provider. See The CSP-issued ID token.

flexpa_external_idstringRequired

Your application's user identifier for this patient. Used for tracking and correlating authorizations across your system.

statestring

Opaque value echoed back on the final redirect. Recommended for CSRF protection.

Response fields

request_uristring

Single-use authorization handle. Pass this to /oauth/authorize to start the consent flow. Format: urn:ietf:params:oauth:request_uri:<id>.

expires_innumber

Lifetime of the request_uri in seconds. Defaults to 90 seconds.

The request_uri is single-use and short-lived. Launch the patient promptly — typically within seconds of receiving the response. Re-launching after consumption requires a new PAR call with a fresh ID token.

Pushed Authorization Request

POST
/link/par
PUBLIC_KEY=pk_live_...
SECRET_KEY=sk_live_...
ID_TOKEN=eyJhbGciOiJSUzI1NiIs...

# Base64 encode the credentials
CREDENTIALS=$(echo -n "${PUBLIC_KEY}:${SECRET_KEY}" | base64)

curl -X POST https://api.flexpa.com/link/par \
  -H "Authorization: Basic ${CREDENTIALS}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=${PUBLIC_KEY}" \
  --data-urlencode "response_type=code" \
  --data-urlencode "redirect_uri=https://example.com/callback" \
  --data-urlencode "scope=launch/patient" \
  --data-urlencode "code_challenge=${CODE_CHALLENGE}" \
  --data-urlencode "code_challenge_method=S256" \
  --data-urlencode "state=opaque-csrf" \
  --data-urlencode "flexpa_external_id=usr_1234" \
  --data-urlencode "id_token_hint=${ID_TOKEN}"

Response — 201 Created

{
  "request_uri": "urn:ietf:params:oauth:request_uri:4c7f0f56-2bb4-4b9b-9d6e-9b1a8a7f2d10",
  "expires_in": 90
}

#Launch with a request_uri

Once you have a request_uri, redirect the patient's browser to Flexpa Consent's authorization endpoint with request_uri and client_id query parameters. Flexpa consumes the stashed parameters atomically — the same request_uri cannot be reused.

Query parameters

client_idstringRequired

Your publishable key. Must match the key the request_uri was issued for.

request_uristringRequired

The request_uri returned from /link/par.

Because the OAuth parameters were already pushed to Flexpa, you do not need to repeat redirect_uri, scope, code_challenge, or state on this redirect. They are read from the stashed PAR record.

The request_uri is consumed on first use. If the patient closes the tab or you need to re-launch, your backend must issue a fresh PAR with a new ID token.

URL

https://api.flexpa.com/oauth/authorize
  ?client_id=pk_live_...
  &request_uri=urn:ietf:params:oauth:request_uri:4c7f0f56-...

JavaScript

const params = new URLSearchParams({
  client_id: 'pk_live_...',
  request_uri: requestUri,
});

window.location = `https://api.flexpa.com/oauth/authorize?${params}`;

#Errors

Errors on /link/par follow the OAuth 2.0 error response format (RFC 6749 §5.2). The HTTP status code and error field together identify the failure mode; error_description carries a human-readable detail.

Error responses

invalid_client401

Missing or invalid HTTP Basic credentials, or the keys do not match a known application. Also returned when a test-mode key is paired with a live-mode redirect URI (or vice versa).

unauthorized_client403

The application exists but does not have BYOI enabled, or does not hold a TEFCA license. Contact partnerships@flexpa.com.

invalid_request400

One or more OAuth parameters are missing, malformed, or unsupported — for example an unregistered redirect_uri, a missing code_challenge, or a code_challenge_method other than S256.

invalid_token400

The id_token_hint failed validation. Common causes include an invalid signature, an iss claim that is not on the allowlist, an aud that does not match your application's HCID, an acr that does not assert IAL2, an auth_time older than the freshness window, an expired token, or a payload missing required demographics (given_name, family_name, birthdate).

Issuer not allowlisted

{
  "error": "invalid_token",
  "error_description": "issuer not allowlisted"
}

Stale auth_time

{
  "error": "invalid_token",
  "error_description": "auth_time too old"
}

BYOI not enabled

{
  "error": "unauthorized_client",
  "error_description": "application is not enabled for BYOI"
}

#Sequence diagram

Partner backend      Flexpa /link/par        Flexpa /oauth/authorize  Patient browser
       │                    │                        │                        │
       │ (1) proof patient with CSP, receive ID token │                        │
       │                    │                        │                        │
       │ (2) POST OAuth + id_token_hint               │                        │
       ├───────────────────►│                        │                        │
       │                    │ verify JWKS sig,       │                        │
       │                    │ check IAL2 claims,     │                        │
       │                    │ stash params           │                        │
       │ (3) { request_uri, expires_in: 90 }          │                        │
       │◄───────────────────┤                        │                        │
       │                                             │                        │
       │ (4) hand request_uri to your frontend       │                        │
       │─────────────────────────────────────────────────────────────────────►│
       │                                             │ (5) GET /oauth/authorize?request_uri=…
       │                                             │◄───────────────────────┤
       │                                             │ consume PAR record,    │
       │                                             │ skip identity step,    │
       │                                             │ start TEFCA discovery  │
       │                                             │                        │
       │                                             │ (6) redirect to redirect_uri?code=…
       │◄─────────────────────────────────────────────────────────────────────│
       │                                                                      │
       │ (7) POST /oauth/token (authorization_code grant)                     │
       │ → Patient Access Token                                               │

#How BYOI differs from the standard flow

AspectStandard ConsentBring Your Own Identity
Identity proofingPatient redirected to a CSP from inside the Flexpa flowPerformed by the partner before launching Flexpa
Authorization launchBrowser redirect to /oauth/authorize with query parametersServer-to-server POST to /link/par, then browser redirect to /oauth/authorize?request_uri=…
AuthenticationPublic client — client_id onlyConfidential client — HTTP Basic with pk_*/sk_*
Patient identity stepAlways shownSkipped
Supported networksPayer, provider, and TEFCA (IAL2)TEFCA (IAL2) only at launch
Token usageONE_TIME or MULTIPLE (with offline_access)ONE_TIME or MULTIPLE (with offline_access)

#Next steps

  • Review the OAuth Reference for the rest of the SMART on FHIR flow — exchange, refresh, revoke, and introspection are unchanged.
  • See the Network guide for an overview of TEFCA and the nationwide exchanges BYOI is scoped to.
  • Contact partnerships@flexpa.com to enable Bring Your Own Identity on your application.
Status TwitterGitHub

© 2026 Flexpa. All rights reserved.

FHIR® is the registered trademark of Health Level Seven International and its use does not constitute endorsement by HL7.

On this page
  • How it works
  • What you need
  • The CSP-issued ID token
  • Supported credential service providers
  • Pushed Authorization Request
  • Launch with a request_uri
  • Errors
  • Sequence diagram
  • How BYOI differs from the standard flow
  • Next steps