Skip to main content
POST https://glide.co/api/partner/treasury/transfers/batch One call moves USD from your prefunded Glide treasury into your users’ personal Glide balances. The whole batch is a single synchronous database transaction. There is no queue, no provider call inside the transaction, and no partial success.

The treasury model

Glide binds your partner record to exactly one business entity, one accounting owner, one entity-scoped USD balance, one external payer UUID and one reserve account. That binding is immutable once made. It does not create a business, approve it, or supply funds. You prefund the treasury by settling real USD into the bound reserve account, then a Glide operator records the settlement against evidence. Funding is an operator attestation of already-settled external money, not a deposit API you can call. Settlement through this endpoint means spendable personal Glide USD credit. It does not mean a bank withdrawal or an on-chain transfer. Both sides of each payout are completed transfer records with zero fee: a debit on your treasury and a credit on the user. The user’s copy shows as incoming and is labelled Payout from partner in their transaction history.

Requirements

This endpoint adds no verification, wallet, receiving-account or webhook gate of its own. A recipient with no verification can still be paid. Your token does not also need the read or receive scopes to call this endpoint, though you do need them to read the results back.

Request

Headers:
UUIDs are canonicalized to lowercase. Individual amounts and the request total must each be at most 9007199254740991. The streamed body limit is 64 KiB, which comfortably fits 50 items. The same user may appear more than once in a batch, as long as each entry is a distinct obligation with its own execution_id and payout_id.

Choosing ids

execution_id identifies one attempt to move a specific amount to a specific user. Generate it once, store it next to the obligation in your database, and reuse it on every retry. payout_id identifies the obligation itself. Neither is generated by Glide, and neither should be regenerated because a call failed.
Never mint a fresh execution_id to “retry” a payment. A new id is a new payment. Retrying with the ids you already stored is what makes a lost response safe.

Response

HTTP 200, including on replay, with one result per requested item in request order.
transfer_id is the correlation key for everything downstream. It appears in GET /api/partner/users/:id/transfers and in the transfer.settled webhook.

Atomicity

The executor locks your partner mapping, treasury, relationship receipts, users and grant rows, validates the entity and balance binding, then credits recipients in a deterministic order. A revocation, suspension or configuration change either lands before execution or waits until the already-authorized transaction commits. The success audit, batch response, receipts, treasury debit, user credits, paired transactions, activity entry and webhook outbox all commit together. If the audit or the outbox fails, the entire new batch rolls back. You will never receive a successful subset.

Caps and policy

Under the treasury lock, Glide enforces the caps an operator configured with you: Only new transfers consume amount or count allowance, so replays are free. Hitting a cap exactly is allowed. A cap error names the limit it violated without revealing how much allowance you have left. Caps must increase from per item through per batch and rolling 24 hours to lifetime. If a step-up amount is configured and an item exceeds it, this release denies the batch with policy_denied. There is no approval token that bypasses it. Ask Glide to raise the cap instead. New executions additionally require an active treasury, an unexpired mandate, accepted owner membership in the active business entity, and verified funding. The debit itself is guarded by available_balance >= new_total, so an underfunded batch fails rather than overdrawing.

Idempotency and replay

An unconfirmed call is not a failed call. On a timeout, a dropped connection, a 5xx or an unparseable response, resend the identical body with the identical Idempotency-Key. A replayed 200 reconciles you against the transfers that already exist.
Replay still requires current partner authentication, receipt membership, active users and both current consents. Treasury suspension or an expired mandate stops new money movement while leaving an authorized replay available. A batch made entirely of reused items needs no new mandate and consumes no policy allowance. Revoking a user’s access can stop you reading a historical receipt. It does not reverse the payment. A later failure of the user’s own bank withdrawal cannot change your completed treasury transfer either.

Errors

Rate limit is 10 requests per minute per partner, with Retry-After: 60 on a 429.
See Errors for what to do about each one.

After settlement

The user’s credit lands in their personal Glide USD balance immediately, visible under Glide balance in the Glide app. From there the user, not you, drives the cash-out:
  1. Convert USD to USDC in Glide, reviewing the quoted fees. This step requires approved verification.
  2. Continue to a bank withdrawal from the conversion receipt, or open the bank flow directly against available USDC.
Held balances are unchanged by your payout. A withdrawal that later fails restores the user’s own funds and never touches your completed payout receipt.

Treasury operations

These are Glide-side operations. Ask Glide to perform them; they are not partner-callable. Binding cannot silently adopt existing funds, and funding receipts are immutable. Corrections need an explicit accounting operation rather than an edit. Treasury suspension leaves your reads and webhook delivery working and only stops new payouts. Partner suspension stops everything.