Quote, accept, move, then poll to settled.
{
"sourceAccountRef": "acc_8xK2",
"sourceEndpointRef": "ep_7Q4",
"sourceHoldingRef": "hld_USD",
"destination": {
"kind": "internal-endpoint",
"accountRef": "acc_2Kp9",
"endpointRef": "ep_2Kp"
},
"valueUnit": { "kind": "fiat", "currency": "USD" },
"amountMinorUnits": "240000",
"feeInstruction": {
"kind": "request_application_fee",
"bearer": "sender_pays",
"amountMinorUnits": "600"
}
}{
"quoteBasisTransferRef": "tr_3Vd7Q",
"amountMinorUnits": "240000",
"lines": [
{
"kind": "app_fee",
"amountMinorUnits": "600",
"applicability": "applicable"
},
{
"kind": "platform_fee",
"amountMinorUnits": "30",
"applicability": "applicable"
}
],
"totals": [
{ "amountMinorUnits": "650" }
],
"noFeeReason": null
}{
"sourceAccountRef": "acc_8xK2",
"sourceEndpointRef": "ep_7Q4",
"sourceHoldingRef": "hld_USD",
"destination": {
"kind": "internal-endpoint",
"accountRef": "acc_2Kp9",
"endpointRef": "ep_2Kp"
},
"valueUnit": { "kind": "fiat", "currency": "USD" },
"amountMinorUnits": "240000",
"feeInstruction": {
"kind": "request_application_fee",
"bearer": "sender_pays",
"amountMinorUnits": "600"
}
}{
"transferRef": "tr_3Vd7Q",
"stage": "reservation_pending",
"revision": 1,
"amountMinorUnits": "240000",
"valueUnit": { "kind": "fiat", "currency": "USD" },
"requestedBy": "key_7Q4"
}{
"transferRef": "tr_3Vd7Q",
"status": "completed",
"isTerminal": true,
"isSuccessful": true,
"fees": {
"status": "settled",
"lines": [
{ "kind": "app_fee", "amountMinorUnits": "600" },
{ "kind": "platform_fee", "amountMinorUnits": "30" }
]
}
}The reservation lifecycle.
The request is valid and admitted.
The reserve is being placed on the source: value held before it moves.
On its way to the provider rail.
Submitted; waiting on the provider's finality signal.
Final on the rail. The fee is collected and the reserve released.
Quote before you move
POST the same body to /v1/transfers/quote first. It returns every fee line, your application_fee and the platform_fee, and a total, so the cost is known before a single unit moves. A waiver (intrabank, policy, or no configured fee) comes back as a noFeeReason.
Accept the quote, exactly
Pass the quote back as acceptedQuote with a tolerance. The default, kind: "exact", refuses to move if the price has shifted by a unit. You can instead allow_increase_by_unit within stated limits. The price you saw is the price you pay.
Idempotent by header
Every write — create, lifecycle, sandbox credit — requires an Idempotency-Key. Retry the same key and you get the same transfer back, never a second one. The network can fail; the ledger will not double.
Reserved, then settled
The 201 returns the transfer at stage reservation_pending: the reserve is being placed on the source, value held before it moves. Finality comes from the provider rail; poll the status until isTerminal is true. Then the fee is collected and the reserve released.
