Skip to main content
In this flow, the member links from the Bilt app. Bilt calls endpoints you host with the member’s verified contact, and each link completes in one request. There is no redirect, callback, or polling.

Before you begin

  • Agree base URLs, credentials, and contacts with Bilt. See Environments and credentials.
  • Agree contact normalization: E.164 for phones, and a policy for email case and plus-addressing.

How it works

After a link succeeds, tell your customer through your own channel that their account was linked. Implement these endpoints on your server. Bilt calls them in this order.

Steps

1

Look up the contact

Bilt calls Look up a contact first. Return the partnerMemberId you find, or 200 with exists: false. Keep it read-only.
2

Link the account

Bilt calls Link an account. Run these checks in order:
  1. Validate the bearer token, and return 401 before you read the body.
  2. Return 403 unless contact.isVerified is true. A missing value is not true.
  3. Return 400 for an inconsistent body, such as a malformed contact or UUID.
  4. Resolve the account by exact match on the verified contact. Use partnerMemberId only to choose between matches. Return 404 when nothing matches.
Never create an account from this endpoint, and never use fuzzy matching.
3

Create and link, if you support it

Create and link an account is optional, enabled per partner. Bilt calls it only when a member with no account asks to open one. Run the link account checks.If you already hold an account for the contact, return 409 account_exists and write nothing. Bilt then links that account through link account with the same idempotencyKey. Use account_exists only for that case.
Lookup sends a flat contact and link account a nested one, so do not share a serializer. Bilt retries a timeout or 5xx with the same idempotencyKey. A retry must never leave a second link or account. Use one of these approaches:
  • Store the key, and tell Bilt how long you keep it.
  • Enforce one active link per account and per member, and answer a repeat with success.
You do not need to replay the original response byte for byte. A retried create and link arrives as link account after a fresh lookup. Answer it with 200 linked, and do not refuse the key as spent.
Neither approach stops a delayed retry after the link ends. A late retry carries the same verified contact as a fresh request, and a structural check silently relinks the account. Treat each key as single-use, and refuse it once its link has ended. Bilt rejects the mirror case on its side with a 409.

What can go wrong

  • The bearer token is missing or wrong. Answer 401 before you read the body.
  • The contact is not verified. Answer 403, and never link it.
  • You already hold an account on create and link. Answer 409 account_exists and write nothing.
  • A retry arrives after the link ended. Refuse the spent idempotencyKey, or the account is silently relinked.

Next steps