Withdraw fiat from a curated vault
Redeems vault shares held in your vault sub-account back to fiat. The amount is asset-denominated — ask for a sum of fiat, exactly as on a deposit. An idempotency key is MANDATORY: send it as the Idempotency-Key header or as the idempotencyKey body field. Replaying a key returns the original result without re-executing; reusing one with different parameters is rejected with IDEMPOTENCY_KEY_REUSED. Settlement rounds DOWN to the currency precision the banking leg accepts: the response reports settledAmount and precisionResidue separately, and the residue stays in your vault sub-account wallet — it is not a fee. Every response carries the pilot disclosure: the environment is a testnet and the yield is simulated, not earned.
Redeems vault shares held in your vault sub-account back to fiat. The amount is asset-denominated — ask for a sum of fiat, exactly as on a deposit. An idempotency key is MANDATORY: send it as the Idempotency-Key header or as the idempotencyKey body field. Replaying a key returns the original result without re-executing; reusing one with different parameters is rejected with IDEMPOTENCY_KEY_REUSED. Settlement rounds DOWN to the currency precision the banking leg accepts: the response reports settledAmount and precisionResidue separately, and the residue stays in your vault sub-account wallet — it is not a fee. Every response carries the pilot disclosure: the environment is a testnet and the yield is simulated, not earned.
Authorization
bearer In: header
Header Parameters
Your own key for this request, 1-100 characters. Required, here or as the idempotencyKey body field; sending both is allowed only if they match. Replaying a key returns the first result without executing anything a second time, and sets replayed to true where the response carries that field. Sending the same key with different parameters is refused with 409 IDEMPOTENCY_KEY_REUSED — use a new key for a different request. While the first call is still running, a second call with the same key answers 409 IDEMPOTENT_REQUEST_IN_PROGRESS. The key is remembered permanently: it is recorded against the movement it created, so a replay years later still resolves to that one movement.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Fiat to redeem out of the curated vault for that currency, and the account to credit.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/api/partner/v1/withdrawals" \ -H "Content-Type: application/json" \ -d '{ "amount": "250.00", "currency": "USD", "destinationAccountId": "1b9d4f07-6c23-4a8e-b510-9f2c7d3e5a68", "idempotencyKey": "acme-withdrawal-2026-08-30-0001", "subAccountId": "5d3b8e10-2f47-4c9a-b6e8-0a71d4c2f395" }'{ "data": { "amount": "250", "createdAt": "2026-09-02T10:15:28.000Z", "currency": "USD", "custody": { "mode": "TCB_SUBACCOUNT", "walletAddress": "0x3B9aC4f27D18E056b1C4a9F30d2E85c7A6b1F094" }, "disclosure": { "items": [ "ENVIRONMENT_IS_TESTNET: The environment is a testnet (Arbitrum Sepolia). No mainnet deployment exists.", "YIELD_IS_SIMULATED: The vault rate is set administratively and the interest it produces is minted as fresh underlying, not earned. It does not represent a return generated by deployed capital.", "FIAT_RAILS_ARE_MOCKED: No real fiat movement occurs. Balances are ledger entries against a sandbox provider.", "CONVERSION_RATES_ARE_MARKET_QUOTED_OR_REFUSED: A conversion is priced only by an external venue that quotes independently of TCB. When no such venue can price the pair, the conversion is refused rather than priced from an internal table. Read rate.pricingModel on every conversion: MARKET is a venue quote; any other value is not a market rate and must not be presented as one.", "CONTRACTS_ARE_UNAUDITED: No audit has been performed. Mainnet is gated on a two-firm audit that has not been commissioned.", "CUSTODY_IS_TCB_SUBACCOUNT: Everything held for the client — its vault shares, and the tcbUSD it holds between the steps of the tokenised deposit chain — is held in TCB custody, in the one TCB wallet assigned to the client. The client holds no keys and moves those tokens only through this API; each sub-account's shares and tcbUSD are book entries against what that wallet holds.", "INTEGRATION_AGREEMENT_ONLY: Fees as published on the rate card; no yield share, no return commitment." ], "summary": "This is a pilot integration on a testnet. Nothing in this system earns anything: the yield is simulated and the fiat rails are mocked.", "version": "2026-10-27" }, "idempotencyKey": "acme-withdrawal-2026-08-30-0001", "onchain": { "burnTxHash": "0xb31d0f6a29c85e470132d9af6058c7be24913f5d7ea0c86241b09fd35c7a1e64", "withdrawTxHash": "0x6c58e2af017d94b3182fa0e7c53d69b148027ea5f31c8d60947b25e0fa1c3d78" }, "precisionResidue": "0.004821", "replayed": false, "settledAmount": "250", "settledAt": "2026-09-02T10:15:41.000Z", "shares": { "balance": "774.518330000000000000000000" }, "status": "SETTLED", "vault": { "address": "0x7a2fD3c8e91B4A5d06E7c1F2b38A9d4C5e6f0B12", "chain": "ARBITRUM" }, "withdrawalId": "8c1e7b25-4a93-4f06-b83d-2e5c9017a4f6" }, "success": true, "timestamp": "2026-09-02T10:15:30.000Z"}List your vault withdrawals GET
Your vault withdrawals, newest first, each with its status on the one savings status vocabulary (QUEUED, PROCESSING, CREDIT_PENDING, COMPLETED, FAILED, REFUNDED, CANCELLED). Filter by status. Fetch one in full with GET /withdrawals/{id}.
Fetch one withdrawal by id GET
The withdrawal in its CURRENT state, whatever that is — including a terminal failure, reported here as the object rather than as an error. This is the fetch half of the thin webhook payloads (a *.settled / *.failed event carries only a resource pointer) and the poll surface the money errors point at.