Skip to main content
A withdrawal requires authorization from the owner wallet. Stage 1 prepares the EIP-712 typed data. The user signs the data. Stage 2 sends the signature and starts the onchain transfer. Stage 2 returns 202 and an operationId. Poll the operation for onchain confirmation.
  • Scope: portfolios:withdraw on both stages.
  • Idempotency anchor: Stage 1 returns message.nonce. The response also shows this value as authorizationId.
  • Authorization TTL: 10 minutes from stage-1 response.
  • Request limit: One recipient on one chain. Use separate authorizations for multiple chains.

Sequence

Stage 1: Prepare the authorization

POST /v2/portfolios/{portfolioId}/withdraw/signature Glider validates the request and checks the live onchain balances. Then, it returns the EIP-712 typed data, a nonce, and a 10-minute expiry.
Response:

Exceptions to the B2B API conventions

EIP-712 requires two exceptions inside the signed envelope:
  • domain.verifyingContract is a bare EVM address. It is not a CAIP-10 identifier. The wallet shows this value during signing.
  • message.expiresAt is Unix seconds as a number, not an ISO-8601 string. Typed-data hashing is binary.
Do not use these exceptions outside the envelope. The data.expiresAt value is an ISO-8601 string.

Recipient rules

  • Use a chain-bound CAIP-10 value (eip155:<chainId>:<addr>). A chain-agnostic value returns API_211.
  • Make sure that the recipient chain matches each asset chain. A mismatch returns API_213.
  • Make sure that the portfolio has a smart account on the recipient chain. A missing account returns API_215.

Stage 2: Sign and submit

The user signs typedData with signTypedData in their wallet. Pass the full object to the wallet library. Viem, ethers, wagmi, and Privy accept this shape.
Send the signature and typedData.message to POST /v2/portfolios/{portfolioId}/withdraw. Send typedData.message unchanged as body.message.
Response:

Echo the inner message exactly

body.message must equal the full stage-1 typedData.message. Keep it byte-for-byte unchanged. These changes cause verification to fail:
  • Re-serializing amountRaw as a number instead of a string.
  • Changing nonce casing or stripping the 0x prefix.
  • Changing the order of assets[]. Array order is part of the hash.
  • Recomputing expiresAt as an ISO string instead of the original Unix seconds integer.
The API accepts EOA (ECDSA) and ERC-1271 signatures.

Stage 3: Poll for onchain confirmation

Stage 2 returns 202 and starts an asynchronous transfer. Poll the operation:
Poll every 2–5 seconds. Stop when the state is completed, failed, or cancelled.

Error handling

See Idempotency for the full 409 model.

Common errors

  • Do not omit message from stage 2. Send the full typedData.message.
  • Do not change the order of assets in stage 2. Array order changes the typed-data hash.
  • Do not wait more than 10 minutes between stages. An expired authorization returns API_216. Start again at stage 1.
  • Do not convert message.expiresAt to an ISO string. This field uses Unix seconds. Use data.expiresAt for an ISO-8601 display value.