Conversion
Central offramp entity. Represents the operation from quote accept to Pix settlement. Full state list.
The conversion is the central entity of the offramp. It exists from the quote accept and traverses the full lifecycle to either Pix settlement or an alternative terminal outcome. It is the resource you read (GET /v1/conversions/:id) and act on (/cancel, /liquidate).
Why conversion is separate from quote
Quote and conversion answer different questions:
- Quote answers: "what is the rate now?". A frozen, disposable price with no side effect.
- Conversion answers: "what operation is in flight, in what state, with how much received?". The executable operation, with deposit address, window, limit reservation, and state machine.
Separating them keeps discarded quotes from polluting the history of real operations and keeps the conversion state machine compact.
State diagram
States, one by one
| State | Meaning | What you are waiting for | Available actions |
|---|---|---|---|
awaiting_deposit | Conversion created, deposit address issued, 15-minute window running | The end customer to deposit USDT | cancel |
funded | On-chain deposit confirmed at the exact amount within the window | Pix settlement to advance automatically | (none) |
standby | Divergent deposit, window expired with a deposit, or both. Conversion does not advance automatically | Your decision between liquidate or support | liquidate |
liquidated | Manual liquidation triggered via /liquidate; new rate applied | Pix settlement to advance automatically | (none) |
completed | Pix delivered to the recipient. Terminal | (terminal) | (none) |
failed | Irrecoverable error after funded or liquidated. See failure_reason. Terminal | (terminal) | (none) |
expired | Window passed with no deposit. Reserve released. Terminal | (terminal) | (none) |
canceled | You canceled in awaiting_deposit. Reserve released. Terminal | (terminal) | (none) |
abandoned | 7 days in standby with no action. Manual off-platform resolution. Terminal | Contact BlendFi support | (none) |
`partially_funded` is internal
The schema reserves the partially_funded status for a transient case which, under the current policy, resolves immediately to standby with standby_reason='under_funded'. You never observe partially_funded on the wire. Documented here for completeness.
Key fields
The conversion exposes (among others):
id,quote_id,liquidation_quote_id,status,transaction_type(pix_offramp).expected_source_amount(the USDT expected, fixed at accept) andreceived_amount(the sum actually received on-chain).deposit_address,deposit_address_network,deposit_window_expires_at.standby_at,standby_expires_at,standby_reason(when applicable).- Execution fields populated after settlement: end-to-end Pix identifiers, USDT transaction hash, timestamps,
failure_reason.
The complete field list lands in the API reference once published.
Webhooks per transition
| Transition | Event |
|---|---|
(creation) → awaiting_deposit | conversion.created |
awaiting_deposit → standby | conversion.standby |
awaiting_deposit → expired | conversion.expired |
awaiting_deposit → canceled | conversion.canceled |
funded → completed, liquidated → completed | conversion.completed |
funded → failed, liquidated → failed | conversion.failed |
standby → abandoned | conversion.abandoned |
There is no intermediate webhook for funded or liquidated: the event of interest is the outcome (completed, failed, standby, expired, canceled, abandoned). Manual liquidation is synchronous and the subsequent outcome arrives via conversion.completed.
Next steps
- Per-user, per-type lock: the rule of one open conversion per end customer.
- Standby and manual liquidation: the most operationally sensitive operation in the lifecycle.
