Skip to main content
Bilt is the OpenID Connect (OIDC) identity provider (IdP) in this flow. You run the authorization code flow with PKCE, then send the resulting id_token to Bilt to create the link.

Before you begin

  • Get your two OAuth clients and the environment URLs. See Environments and credentials.
  • Register your redirect URIs with Bilt for staging and production.
  • Run the flow from your backend, as a confidential client.
  • Have a JSON Web Token (JWT) library that validates RS256 signatures.
  • Read endpoints and keys from <issuer>/.well-known/openid-configuration instead of hard-coding them. Environments and credentials lists each issuer.

How it works

Steps

1

Create the session values

For each sign-in, generate a random state and a code_verifier of 43 to 128 URL-safe characters. Store both in a server-side session. Compute code_challenge as BASE64URL(SHA256(code_verifier)).
2

Send the member to the IdP

Read authorization_endpoint from the discovery document and redirect the member there with these parameters:
  • client_id: your IdP client.
  • redirect_uri: an exact match of a registered URI.
  • response_type=code
  • scope=openid. Add email or profile only if you need them.
  • state
  • code_challenge and code_challenge_method=S256. The plain method is not accepted.
  • nonce (optional)
3

Handle the callback

Reject a state that does not match the stored value before you read anything else. The IdP does not enforce state.Then check for an error parameter. Do not retry access_denied: the member changed their mind. invalid_request, unauthorized_client, and server_error point to a setup or IdP problem.Otherwise, read the code. It is short-lived and single-use.
4

Exchange the code

From your backend, post the code to token_endpoint as form data:
Common failures are a wrong content type, a changed redirect_uri, and a used code. The IdP answers invalid_grant, invalid_client, invalid_request, or redirect_uri_mismatch. Start the flow again instead of retrying the code.
5

Validate the id_token

You only need the id_token from the response. Validate it before you send it:
  • The signature verifies against jwks_uri with RS256. Cache the key set, and refresh it when a key ID is unknown.
  • iss exactly matches the discovery issuer.
  • aud is your IdP client ID.
  • exp is in the future. Bilt allows 30 seconds of clock skew.
  • jti is present.
The sub claim is the Bilt member ID, a stable UUID. Key on sub, not on email.
6

Create the link

Send the token, unchanged and right away, to Create a link. Add your partnerUserId: a stable, opaque ID with no personal data in it. Store the linkId from the response.
Bilt never sees the member access token from the exchange. You can discard it.

Handle the id_token

  • Use each token once. The only reuse is resending an identical request whose response was lost.
  • Do not rewrite or re-sign the token. It can be up to 8,192 characters.
  • Do not log or store the token.
  • A staging token sent to production fails with INVALID_ID_TOKEN.

What can go wrong

Next steps