Skip to main content
A Global Account is what we consider a programmable, self-custodial account for holding and moving money. Under the hood, it is an embedded Spark wallet that Lightspark provisions for your customer. It can hold different stablecoins, including those denominated in local currencies, as well as other digital assets such as Bitcoin. In the API, a Global Account is an internal account with type: "EMBEDDED_WALLET". It uses the same customer, quote, transaction, and webhook primitives as other accounts. Receiving funds works the same way, too. To move money out, the customer must authorize the transfer on their device, which signs the payment with a session signing key.

Why a Global Account?

  • Self-custodial. Neither Lightspark nor your platform can move funds unilaterally. Outbound transfers require authorization from the customer’s device.
  • Stablecoin-denominated. Balances can be held in stablecoins like Brale-issued USDB. You can also issue your own stablecoin and request enablement in Grid. Use the /quotes API to convert from fiat or withdraw through supported payment rails.
  • Native. Reuse the customer, internal-account, quote, transaction, and webhook primitives you already use for payouts or P2P. Global Accounts add authentication and signing at the account level.

Payment flow

Global Accounts use the same /quotes and /quotes/{id}/execute pattern as other payments. Outbound transfers also require a client signature.
  • Incoming funds. Funding an account works like any other internal account. Create a quote with the Global Account as the destination, execute it, and Grid converts the source currency into USDB and credits the account. Incoming funds do not require customer approval.
  • Outgoing funds. Withdrawals and transfers out require the customer to authorize them on their device. Grid returns a payloadToSign in the quote’s paymentInstructions; the client signs those bytes with its session signing key and passes the base64 signature as the Grid-Wallet-Signature header on /quotes/{id}/execute. Only then does Grid release the funds.
Sessions are short-lived (15 minutes by default) and bound to a specific device via the client key pair, so a stolen signature can’t be replayed from a different device or after the session expires. Standard transaction webhooks fire throughout the lifecycle. See Transaction lifecycle.

Architecture

Three parties participate in every signed action: The client never talks to Grid directly. Every request flows client → integrator backend → Grid.

Auth credentials, client keys, and session signing keys

Three distinct pieces of crypto collaborate to authorize actions on the Global Account (withdrawals, credential changes, session revocations, wallet exports, and wallet privacy updates): The flow is always the same: verify an auth credential → receive a short-lived session signing key → build a Grid wallet signature over the payloadToSign bytes on the client → pass that signature as the Grid-Wallet-Signature header on the request that actually moves funds or changes account state. This applies to withdrawals, adding or removing credentials, refreshing or revoking sessions, exporting the wallet seed, updating customer email for tied email OTP credentials, and updating wallet privacy.

Prerequisites

Customers who hold a Global Account must be KYC/KYB verified before any account funds can move from or to fiat rails. This quickstart picks up after KYC is complete.In sandbox, customers are automatically KYC approved on creation so you can skip straight to account setup.
You also need:
  • A platform configured with USDB in its supported currencies. In sandbox, USDB is enabled by default alongside USD and USDC.
  • Sandbox or production API credentials with access to the Embedded Wallet Auth and Internal Accounts endpoints.

Walkthrough

The walkthrough below is the happy path: create a customer, find the auto-provisioned account and its default email OTP credential, 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 has USDB in its supported currencies — you don’t need to pass it on the customer.
Response: 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 by type=EMBEDDED_WALLET.
Response:
Hold onto the InternalAccount:... id — every auth credential is scoped to it.

3. Find the default email OTP credential

Global Accounts are initialized with an EMAIL_OTP credential tied to the customer email on file. Fetch the auth methods for the account and keep the AuthMethod:... id for the signing step later in this walkthrough.
Response:
You can add passkeys or OAuth credentials later, but adding credentials is itself a signed action. Start with the default email OTP credential to mint the first session signing key.

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.
To fund from another currency (USD ACH, USDC on-chain, etc.), create a quote with destination.destinationType: "ACCOUNT" pointing at the Global Account’s InternalAccount id. The quote’s sourceCurrency can be any supported platform currency; Grid will convert into USDB on execute.

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.
Response: 201 Created with the new ExternalAccount:... id.

6. Create a withdrawal quote

Create a quote with the Global Account as the source. Grid returns a payloadToSign 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 a payloadToSign. Now we need a session signing key to sign it with. With EMAIL_OTP, the client generates a TEK (Target Encryption Key) pair, HPKE-encrypts the OTP code, and uses the TEK private key both to complete login and to sign the quote payload.
1

Your backend requests a fresh OTP

Ask Grid to send a fresh OTP email for the default EMAIL_OTP credential. The response includes otpEncryptionTargetBundle for the secure OTP flow.
Response (200):
Return otpEncryptionTargetBundle to the client.
2

Client encrypts the OTP and verifies

The client generates a fresh P-256 key pair (the TEK), HPKE-encrypts {otp_code, public_key} under otpEncryptionTargetBundle, and sends the encrypted bundle to your backend. public_key must be the compressed public key (02 or 03 prefix). In sandbox, use OTP code 000000.Your backend calls verify with the encrypted bundle:
Response (202):
Return payloadToSign and requestId to the client.
3

Client signs the verification token and completes login

The client stamps payloadToSign with the TEK private key and sends the stamp back to your backend.Your backend retries the same request with the stamp:
Response (200):
The TEK public key is now the session API key. The TEK private key is the session signing key — the client already has it.
4

Client stamps the quote payload

The client signs the quote’s payloadToSign with the same TEK private key. Return the full Grid wallet signature to your backend.
Stamp the payloadToSign bytes exactly as Grid returned them. Do not parse, re-serialize, trim, or normalize the JSON — the stamp must cover the same bytes Grid’s verifier hashes.
The session signing key is now valid for 15 minutes, so subsequent account actions within that window (for example, a second withdrawal) can reuse it without another /challenge + /verify round-trip.

8. Execute the quote

Call /execute with the stamp in the Grid-Wallet-Signature header.
Response:
The transaction is on its way. You’ll receive standard transaction webhooks (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, refresh, and revoke active sessions.

Exporting a wallet

Let a customer take their wallet seed off Grid.