Keys and tokens
There are only three credentials in the system, and each one has exactly one place it goes.
The pattern to remember: your org credential stays on your server. The wallet link is the only thing that travels to the user. The connection token comes back when a user verifies, and your server keeps it.
Authenticate your server
Exchange your credentials for a bearer token. The request is form-encoded, per OAuth:access_token with an expires_in. Cache it and refresh when it expires. Whether it’s a sandbox or production token follows the credential, not the URL.
Connect a user
Send the user a one-time code, on email or phone:external_user_id is optional. It’s your own id for the user, and it comes back on webhooks so you can match them up.
Verify the code the user gives you. In sandbox the code is always 111111:
user_id, an access_token (the connection token), and a refresh_token. Store all three. The connection.created webhook fires here.
Then record the user’s authorization once:
Create wallet links
With a connected, consented user, your server can create wallet links whenever the wallet should open:url. That link opens the user’s wallet on any platform: the web embed, the iOS sheet, a text message, or the hosted page. Links are short-lived; create a fresh one each time rather than storing them.
Keep the session alive
Connection tokens expire. Rotate them with the refresh token:Webhooks you will receive
connection.createdwhen a user verifies, with yourexternal_user_idon it
When it fails
- An auth error usually means the wrong credential for the call. Check the table at the top.
user_info_requiredon wallet links means consent was never recorded for that user. Call/connect/consent.subscription_requiredin production means your organization hasn’t subscribed yet. Sandbox never requires one.invalid_refresh_tokenmeans the refresh token was already used or expired. Reconnect the user.
Sandbox behavior
Sandbox never sends a real email or SMS, and the code is always111111. Sandbox users are isolated: connecting anyone@example.com in sandbox can never touch a real account with that email.
Next: Webhooks