The Agents API must be enabled for your platform; until it is, agent endpoints answer
403. To enable it, book a demo or reach out to your Lightspark contact.Funded by your platform
A Global Account is an internal account, so every way you already fund internal accounts works. Create a quote with the Global Account’sInternalAccount id as the destination, from any source currency your platform supports, and Grid converts into the wallet’s currency on execute. A real-time funding source returns paymentInstructions the customer follows to pay in.
See Fund the account in the Global Accounts walkthrough for the request.
Bank transfers to the customer’s account details
Once a customer is verified, their USD internal account carries a US account and routing number: theUSD_ACCOUNT entry in its fundingPaymentInstructions, which lists the payment rails it accepts (for example ACH and WIRE). Anyone can pay it, not only the customer: clients, employers and other people send an ordinary bank transfer on one of those rails, and the customer or your platform can share the details with any payer. The account number is unique to that account, so payers need no reference.
Deposits the agent creates
With theRECEIVE_FUNDS permission, the agent can create a deposit target for the customer’s account with POST /agents/me/deposits. Idempotency-Key is required: a retry with the same key returns the same deposit.
destinationInternalAccountId must belong to the agent’s customer and be allowed by the agent’s policy.
To pull from the customer’s own bank account or debit card instead, see Pull from the customer’s bank account and Pull from the customer’s debit card.
201 Created
Lightning deposits
The customer pays exactlyamount in USD; deposit fees are deducted before the destination is credited, and estimatedReceiveAmount shows the estimate. The invoice must be paid by expiresAt. paymentLinks.cashApp opens the invoice in Cash App, and paymentLinks.shortUrl is a shortened link when one is available.
Chain deposits
A chain request returns a standing address that does not expire. Grid counts the first payment the address receives from that network in that currency within 24 hours of the request. While that window is open with nothing paid, a second request for the same account, network and currency is refused with409; the error gives the time the window closes.
Where Grid funds a chain deposit through a quote instead, the address is the quote’s, the deposit carries the quote’s expiresAt, and quoteId names the quote. A payment that arrives after it expired is not converted: the deposit stays EXPIRED, paidAfterExpiry becomes true, and Lightspark recovers the funds by hand. Do not send it again.
Tracking a deposit
Read a deposit withGET /agents/me/deposits/{depositId}. status is PENDING, PROCESSING, COMPLETED, EXPIRED, FAILED or REFUNDED. The transaction that pays a deposit carries the deposit’s quoteId, so you can match them, and your platform receives the usual INCOMING_PAYMENT webhook. Except for bank pulls, a deposit reported FAILED or EXPIRED can still become COMPLETED when funds arrive late; you then receive INCOMING_PAYMENT for its transaction again, now COMPLETED.
A 503 means the deposit provider is unavailable or holding the order for review. Retry with the same Idempotency-Key.
Pull from the customer’s bank account
Where your platform enables external-account pulls, the agent can ask to pull USD from one of the customer’s own US bank accounts into their USDB Global Account withsourceNetwork: ACH_PULL. Until then, the request is refused with 403 (ACH_PULL_NOT_ENABLED).
- Your backend validates the customer’s bank account through Plaid and records it with
POST /agents/{agentId}/external-accounts/{externalAccountId}/ach-validations. A pull needs anACTIVEUSD external account of the agent’s customer with a recorded validation. - The agent creates the deposit with
POST /agents/me/deposits, givingsourceCurrency: USD,amountin cents,sourceExternalAccountId, and the customer’s USDBEMBEDDED_WALLETasdestinationInternalAccountId. This moves no money. The deposit isPENDINGand carriesachPull.authorization.text, the debit authorization the customer must accept, andachPull.limits, how much more the customer can pull. - Your product shows that text verbatim to the signed-in customer (for a business, an admin). When they accept, your backend calls
POST /agents/{agentId}/deposits/{depositId}/authorize-debitwith platform credentials, sending the text’stextVersionandtextSha256.
PROCESSING, and the amount is credited to the Global Account at once. It becomes COMPLETED when the debit settles, or FAILED if Grid refuses it or the bank returns it (achPull.returnCode). A deposit that is not authorized within 30 minutes becomes EXPIRED. The agent can never authorize a debit itself.
Pull from the customer’s debit card
Where your platform enables card pulls, the agent can ask to pull USD from one of the customer’s own debit cards into their USDB Global Account withsourceNetwork: DEBIT_CARD_PULL. It works like the bank pull above, with a stored card in place of a bank account. Grid stores the card encrypted, so your platform never handles the card number. Until card pulls are enabled, the request is refused with 403 (DEBIT_CARD_PULL_NOT_ENABLED).
- The customer’s debit card is stored with
POST /customers/{customerId}/stored-cards, as in Cards. A pull needs anACTIVEstored card that is a debit card, belongs to the agent’s customer, and is shared with the agent. - The agent creates the deposit with
POST /agents/me/deposits, givingsourceCurrency: USD,amountin cents,sourceStoredCardId, and the customer’s USDBEMBEDDED_WALLETasdestinationInternalAccountId. This moves no money. The deposit isPENDINGand carriesdebitCardPull.authorization.text, the debit authorization the customer must accept, anddebitCardPull.limits, how much more the customer can pull. - Your product shows that text verbatim to the signed-in customer and confirms their decision with a fresh step-up, such as a passkey or an emailed code. When they accept, your backend calls
POST /agents/{agentId}/deposits/{depositId}/authorize-debitwith platform credentials, sending the text’stextVersionandtextSha256.
PROCESSING, and the amount is credited to the Global Account at once. It becomes COMPLETED when the charge settles, or FAILED if Grid refuses it or the card issuer declines or reverses it (debitCardPull.returnCode). A deposit that is not authorized within 30 minutes becomes EXPIRED. The agent can never authorize a debit itself. Track the deposit and its INCOMING_PAYMENT webhooks as in Tracking a deposit.
Limits before verification
Until a business customer’s KYB status isAPPROVED, its agents’ sends and deposits are held to the same limits as an unverified individual’s, counted across the whole business. With MANAGE_IDENTITY, an agent can help an individual customer finish verification: read and update identity details (GET/PATCH /agents/me/customer), submit for KYC (POST /agents/me/verifications), or generate a single-use hosted KYC link (POST /agents/me/kyc-link).
Funding in sandbox
In sandbox, credit any internal account instantly withPOST /sandbox/internal-accounts/{accountId}/fund. See Sandbox testing.