Prerequisites
You also need:- A platform configured with
USDBin its supported currencies. In sandbox, USDB is enabled by default alongsideUSDandUSDC. - Sandbox or production API credentials with access to the
Embedded Wallet AuthandInternal Accountsendpoints.
Walkthrough
The walkthrough below is the happy path: create a customer, find the auto-provisioned account, register a passkey, fund it, and withdraw to a bank account. Each step shows the HTTP request your integrator backend makes on behalf of the client.1. Create a customer
Create the customer record. A Global Account is provisioned automatically whenever a customer is created on a platform that hasUSDB in its supported currencies — you don’t need to pass it on the customer.
201 Created with the new Customer:... id. In sandbox, the customer is KYC-approved immediately; in production you would now run them through the KYC / KYB flow before any funds can move.
2. Find the Global Account
When a customer is created on a USDB-enabled platform, Grid automatically provisions a Global Account alongside their other internal accounts. Fetch it by filtering the customer’s internal accounts bytype=EMBEDDED_WALLET.
InternalAccount:... id — every auth credential is scoped to it.
3. Register a passkey credential
Global Accounts support three authentication credential types: passkey, OAuth (OIDC), and email OTP. A passkey is a user-friendly default: biometric, phishing-resistant, and usable across the user’s devices. Registration only binds the passkey to the account — it doesn’t issue a session. Sessions are created on-demand, when the customer initiates an action that needs a signature (step 7). The full flow with sequence diagram is documented in Authentication; the condensed version:1
Your backend issues a WebAuthn challenge
Generate a random base64url
challenge, store it short-lived in your session store, and return it to the client.2
Client runs `navigator.credentials.create()` / platform equivalent
The browser or OS prompts the user for a biometric, returns an
attestation. The client posts the attestation back to your backend.3
Your backend calls Grid
201 with the new AuthMethod:... id plus the first-authentication challenge, requestId, and expiresAt. Persist the auth method id against the customer — you’ll pass it to /challenge and /verify whenever the customer needs to sign.4. Fund the Account
Global Accounts behave like any other internal account on the way in — incoming funds do not need the customer’s signature. In sandbox, use the sandbox funding endpoint to skip straight to a funded state:amount is in the smallest unit of the account’s currency. USDB has 6 decimals, so 1000000000 is 1,000.00 USDB.
You will receive an INCOMING_PAYMENT webhook when the balance updates. The account now holds 1,000.00 USDB.
5. Add an external bank account
Add the destination the customer wants to withdraw to. This is a standard external account — nothing Global Account-specific.201 Created with the new ExternalAccount:... id.
6. Create a withdrawal quote
Create a quote with the Global Account as the source. Grid returns apayloadToSign in the quote’s payment instructions — this is what the client will sign to authorize the transfer.
lockedCurrencyAmount is in the smallest unit of the locked side’s currency. Here the sending currency is USDB (6 decimals), so 10000000 is 10.00 USDB.
Response:
7. Authenticate and sign
The customer has an outstanding quote with apayloadToSign. Now we need a session signing key to sign it with — this is when the passkey actually gets used. The flow is keypair → challenge → assertion → verify → decrypt → sign.
1
Your backend requests a fresh challenge sealed to the client public key
The client generates a fresh P-256 client key pair and posts the public key (uncompressed hex) to your backend, which forwards it to Grid. Grid bakes the public key into the session-creation payload so the resulting session signing key is sealed to that device.Response (200):Return
challenge and requestId to the client.2
Client runs the WebAuthn assertion against the Grid-issued challenge
Prompt the authenticator with the Post the assertion (and the
challenge returned in the previous step:requestId from the previous step) back to your backend.3
Your backend verifies the assertion with Grid to mint a session
clientPublicKey is no longer required here — Grid already has it from the /challenge call. The Request-Id header ties this verify to that earlier challenge.Response (200):encryptedSessionSigningKey and expiresAt to the client.4
Client decrypts the session signing key and signs the payload
The client decrypts
encryptedSessionSigningKey with the matching client private key, then signs the quote’s payloadToSign with the resulting session signing key. Return the base64 signature to your backend./challenge + /verify round-trip.
8. Execute the quote
Call/execute with the signature in the Grid-Wallet-Signature header.
OUTGOING_PAYMENT) as it settles — see Transaction lifecycle.
Where to next
Client keys & signing
Generate the P-256 key pair, decrypt the session signing key, and sign payloads on Web, iOS, and Android.
Authentication
OAuth and Email OTP flows, passkey reauthentication, and the full WebAuthn parameter mapping.
Sessions
List active sessions and revoke a session (sign-out).
Exporting a wallet
Let a customer take their wallet seed off Grid.