Withdraw USDC from the embedded wallet to an external address
Sends USDC out of the caller's embedded wallet ATA to an arbitrary on-curve Solana address. Uses Privy's session-signer delegation (set up via /v1/wallet/enable-trading) and Privy's native gas sponsorship — the user is not prompted to sign and never needs SOL.
Chained vault-tap: when the requested amount_usdc exceeds the caller's ATA-available balance, the handler first issues withdraw_from_vault (vault PDA → owner ATA) for the shortfall, waits for that TX to confirm, then issues the external SPL transfer. The vault_signature / vault_amount fields surface the intermediate TX when this happens. If the vault tap succeeds but the external transfer fails to construct or broadcast, the response is 502 with error.code: PARTIAL_VAULT_ONLY and the vault TX surfaced under error.details.vault_signature / error.details.vault_amount. The caller can retry with the same amount; the pre-flight will see the ATA is now sufficient and skip the vault tap. 502 (rather than 200) is deliberate: the idempotency middleware caches only 2xx, so same-key retries against a 502 re-enter the handler instead of replaying a cached partial response.
Idempotency-Key is honored: a duplicate request with the same key replays the cached 2xx response without re-issuing on-chain TXs.
Headers
Client-generated UUID. Successful (2xx) responses are cached for 24h and replayed on retry with the same key. The request body is not part of the cache key — use a fresh UUID whenever the payload differs (e.g. updated odds), otherwise the original response is replayed. Non-2xx responses are not cached.
Request body
Response
Withdrawal submitted. signature is the external SPL transfer signature. vault_signature and vault_amount are present only when the request required a vault → ATA hop.