Migrate to Plans and Executions
How do I move deposits, withdrawals, and remittances from quotes, transfers, and trades to plans and executions?
Plans and executions replace quotes, transfers, and trades for fiat deposits, withdrawals, and remittances. A plan prices the whole movement up front, and one execution runs it as a series of stages. A remittance that took a funding transfer, a trade, and a payout now takes a deposit plan and a remittance plan.
Required in CanadaCanadian money movement must use plans and executions to adhere to newly approved regulatory flows. See the CA Remittance Integration Guide for the complete Canadian flow.
Prerequisites
- Add the
plans:read,plans:execute,executions:read, andexecutions:executescopes to your API credentials.
Map concepts
| Quotes, transfers, and trades | Plans and executions |
|---|---|
POST /api/quotes | POST /api/plans. The plan carries the price and an expires_at. |
POST /api/transfers, POST /api/trades | POST /api/executions with the plan_guid. |
| One transfer or trade per step | One execution with ordered stages (for example deposit, trade, payout, withdrawal). Each stage has its own state. |
deliver_amount or receive_amount on the quote | amount on source_account or destination_account. |
external_bank_account_guid on the transfer | Account guid on source_account and destination_account. |
| Participants on the transfer | customer_guid or bank_guid on the plan. |
payment_rail on the transfer | payment_rail on the external bank account side: source_account for a deposit, destination_account for a withdrawal. |
security_question and security_answer on the transfer | security_question and security_answer on destination_account. |
identifiers on the transfer (for example gateway_url) | links and identifiers on each stage in stages. |
Transfer or trade failure_code | Plan and execution failure_code, with per-stage failure_code. |
transfer.* and trade.* webhooks | plan.* and execution.* webhooks. Stages have no webhook events. |
Map operations
| Operation | Before | After: plan type | Stages |
|---|---|---|---|
| Deposit fiat | Funding quote (side: deposit) + funding transfer | deposit | deposit |
| Withdraw fiat | Funding quote (side: withdrawal) + funding transfer | withdrawal | withdrawal |
| Remit from a fiat balance | Trading quote + trade, then a remittance plan from the trading account | remittance from the fiat account | trade, payout |
Migrate a deposit
Before, a funding quote and a funding transfer:
POST /api/quotes
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"product_type": "funding",
"customer_guid": "customer_guid",
"asset": "CAD",
"side": "deposit",
"deliver_amount": 10000
}
POST /api/transfers
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"quote_guid": "quote_guid",
"transfer_type": "funding",
"payment_rail": "etransfer",
"source_participants": [
{"type": "customer", "guid": "customer_guid", "amount": 10000}
],
"destination_participants": [
{"type": "customer", "guid": "customer_guid", "amount": 10000}
]
}POST /api/plans
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"type": "deposit",
"customer_guid": "customer_guid",
"source_account": {
"guid": "external_bank_account_guid",
"amount": 10000,
"payment_rail": "etransfer"
},
"destination_account": {
"guid": "fiat_account_guid"
}
}
POST /api/executions
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"plan_guid": "plan_guid"
}Poll GET /api/plans/{plan_guid} until state is completed or failed. Create the execution only for a completed plan, before expires_at.
The deposit before this change used the e-Transfer gateway without an external bank account. A deposit plan needs an external bank account as its source. See Update Canadian e-Transfer flows.
Migrate a remittance
Before, CAD was traded to USDC_SOL with a quote and a trade, and the remittance plan used the trading account as its source. After, the remittance plan uses the fiat account as its source and runs the trade as its first stage.
POST /api/plans
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"type": "remittance",
"customer_guid": "customer_guid",
"source_account": {
"guid": "trading_account_usdc_sol_guid",
"amount": 72000000
},
"destination_account": {
"guid": "recipient_external_bank_account_guid"
},
"purpose_of_transaction": "family_support"
}POST /api/plans
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"type": "remittance",
"customer_guid": "customer_guid",
"source_account": {
"guid": "fiat_account_guid",
"amount": 10000
},
"destination_account": {
"guid": "recipient_external_bank_account_guid"
},
"purpose_of_transaction": "family_support"
}
Intermediate accountsThe customer still needs a trading account for the
tradestage; Cybrid selects it when only one is eligible. Passintermediate_accountsonly when the customer has more than one eligible account of the same asset for a stage.
Read stage links
Provider links such as the Interac e-Transfer gateway_url move from the transfer's identifiers to the stage's links. Poll GET /api/executions/{execution_guid} and read the link from the matching stage:
{
"guid": "execution_guid",
"type": "deposit",
"state": "executing",
"stages": [
{
"guid": "stage_guid",
"type": "deposit",
"state": "executing",
"links": [
{
"type": "gateway_url",
"value": "gateway_url"
}
]
}
]
}Update webhooks and failure handling
- Subscribe to
plan.planning,plan.completed,plan.failed,execution.executing,execution.completed, andexecution.failed. See Webhooks. - Read plan failures from the plan
failure_code. - Read execution failures from the execution
failure_code, and from the stagefailure_codeto see which stage failed. Interac e-Transfer codes such aspayment_request_expired,recipient_cancelled, andinvalid_security_questionare reported on the execution. - Plans expire. Executing a plan after
expires_atreturns422withplan_expired; create a new plan.
Update Canadian e-Transfer flows
- Deposits need a customer-owned account. A deposit plan's source is the customer's Interac e-Transfer external bank account. See Use a customer-owned Interac e-Transfer account.
- Deposit bank account required. Creating an execution for a deposit to a fiat account without a
maindeposit bank account is rejected withno_deposit_bank_account. See Deposit Bank Account Requirement. - Withdrawals carry the security pair on the destination. Send
security_questionandsecurity_answerondestination_accountwithpayment_railset toetransfer.
Next steps
Updated about 13 hours ago

