Send Cross-Border Payments
How do I create and execute a remittance plan?
Send funds from a Cybrid trading account to a foreign bank account using the remittance product.
Cross-border payments include automatic currency conversion and competitive exchange rates.
Enable remittanceContact Cybrid support to enable the remittance feature on your bank.
Overview
The remittance process involves four main steps:
- Create a remittance plan
- Wait for planning to complete
- Execute the plan
- Monitor execution completion
flowchart LR
%% Subgraph
subgraph RP["Remittance Process"]
direction LR
A("📝 Create Remittance Plan")
B("⏳ Planning In Progress")
C("⚙️ Execute Plan")
D("📊 Monitor Execution Completion")
A --> B --> C --> D
end
%% Styling
classDef step fill:#F5F7FF,stroke:#5B6CFF,stroke-width:1.5px,color:#1A1A1A;
classDef container fill:#EEF1FF,stroke:#3F51FF,stroke-width:2px,color:#1A1A1A;
class A,B,C,D step;
class RP container;
Prerequisites
Before you begin, ensure you have:
- A verified customer entity
- A verified counterparty entity (as the recipient)
- A trading account with sufficient funds
- An external bank account in
completedstate with raw routing details
The source trading account must:
- Be in
createdstate - Belong to a verified customer (not frozen, not rejected)
The destination external bank account must:
- Have
kind: raw_routing_details - Be in
completedstate - Meet KYC requirements for the destination country and currency
Country-specific guidesEach destination corridor has specific requirements for participant types, source accounts,
recipient KYC, and bank account routing. See the corridor-specific guides:
- Payouts to Mexico — MXN via SPEI
- Payouts to Colombia — COP via PSE
- Payouts to India — INR via IFSC
- Payouts to Pakistan — PKR via SBP
- Payouts to Bangladesh — BDT via BEFTN
Step 1: Create a remittance plan
Create a plan that calculates estimated amounts, fees, and exchange rates.
Request
POST /api/plans
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"type": "remittance",
"customer_guid": "customer_guid",
"source_account": {
"guid": "source_account_guid"
},
"destination_account": {
"guid": "destination_account_guid",
"amount": 10000
},
"purpose_of_transaction": "family_support",
"travel_rule_info": {
"ultimate_originating_party_guid": "originating_party_guid",
"ultimate_receiving_party_guid": "receiving_party_guid"
}
}Request fields
-
type (required) - Set to
remittancefor cross-border payments. -
customer_guid or bank_guid (required) - The owner of the plan. Use
customer_guidfor
customer-owned plans orbank_guidfor bank-owned plans. These fields are mutually exclusive. -
source_account (required) - The trading account funding the remittance.
guid- Required. The trading account identifier.amount- Optional. The amount to withdraw from the source account in base units.
-
destination_account (required) - The external bank account receiving the funds.
guid- Required. The external bank account identifier.amount- Optional. The amount to deposit in the destination account in base units.
Amount specificationYou must specify EITHER
source_account.amountORdestination_account.amount, but not both or
neither. When you specify the destination amount, the system calculates the required source amount
(including fees and exchange rates). When you specify the source amount, the system calculates the
resulting destination amount.
-
purpose_of_transaction (conditionally required) - Required for certain destination countries.
Example values include:family_support,education,gift,medical_treatment,salary_payment,
loan_payment, andother. See the API reference
for the full list of supported values. -
travel_rule_info (optional) - Required when the originator or receiver differs from the account
holders. Valid entity types for parties:customer,counterparty,bank.ultimate_originating_party_guid- Required when the funds originate from someone other than the
trading account holder (for example, a bank acting on behalf of a customer).ultimate_receiving_party_guid- Required when the final beneficiary differs from the external
bank account holder.
-
supporting_documents (optional) - Logical document declarations attached to the plan, for
corridors that require partner-supplied documentation. Each entry groups one or more pre-uploaded
file GUIDs under a declared type.type(required) - Document type. One ofinvoice,purchase_order,delivery_slip,
contract,bill_of_lading, orothers. Which types are required or accepted depends on the
destination corridor and participant type. See the corridor-specific guides.file_guids(required) - Array of file GUIDs incompletedstate. Files are uploaded via the
customer-scoped File Upload endpoint, so each
file_guidmust belong to a customer (the same customer that owns the plan, or — for
bank-owned plans — a customer linked to the plan's parties). Each file must be uploaded with a
typematching the documenttype(for example, aninvoicedocument references files
uploaded withtype: invoice). Allowed MIME types:application/pdf,image/jpeg,
image/png.document_reference_number(optional) - A reference number identifying the document, such as an
invoice number. Required for B2B payouts to certain corridors (for example, India and the
Dominican Republic), where exactly one supporting document must carry it.
Limits: up to 3 documents per plan and up to 3 files per document. Upload files via
File Upload and wait forstate: "completed"before
referencing them here. Non-remittance plan types reject this field withinvalid_parameter(422). -
labels (optional) - Array of strings to tag the plan. Use labels to track and filter plans
by your own workflow identifiers (for example, a payroll run or batch reconciliation job). Maximum
8 labels per plan, 64 characters each. When labels are set, thelabelsfield appears in the
plan response; the key is omitted for unlabeled plans.
Response
The plan returns in storing state while the system calculates rates and fees.
Step 2: Wait for planning to complete
Poll the plan endpoint until the state changes to completed, indicating it's ready for execution.
GET /api/plans/plan_guid
Authorization: Bearer YOUR_TOKEN{
"created_at": "2025-10-04T12:59:15.732645Z",
"updated_at": "2025-10-04T12:59:17.249897Z",
"expires_at": "2025-10-04T13:29:15.732645Z",
"guid": "plan_guid",
"state": "completed",
"type": "remittance",
"customer_guid": "customer_guid",
"failure_code": null,
"stages": [
{
"created_at": "2025-10-04T12:59:17.132720Z",
"updated_at": "2025-10-04T12:59:17.132720Z",
"guid": "stage_guid",
"type": "payout",
"failure_code": null,
"state": "planned",
"source_account": {
"guid": "source_account_guid",
"asset": "USDC",
"type": "trading",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": null,
"requested_amount": null,
"quoted_amount": 5531070,
"executed_amount": null
},
"destination_account": {
"guid": "destination_account_guid",
"asset": "MXN",
"type": "external_bank_account",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": "counterparty_guid",
"requested_amount": 10000,
"quoted_amount": 10000,
"executed_amount": null
},
"fees": [
{
"type": "bank",
"asset": "USDC",
"quoted_amount": 27518,
"executed_amount": null
},
{
"type": "platform",
"asset": "USDC",
"quoted_amount": 27518,
"executed_amount": null
},
{
"type": "network",
"asset": "ETH",
"quoted_amount": 100000000000,
"executed_amount": null
}
],
"identifiers": [],
"links": []
}
],
"supporting_documents": [],
"source_account": {
"guid": "source_account_guid",
"asset": "USDC",
"type": "trading",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": null,
"requested_amount": null,
"quoted_amount": 5531070,
"executed_amount": null
},
"destination_account": {
"guid": "destination_account_guid",
"asset": "MXN",
"type": "external_bank_account",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": "counterparty_guid",
"requested_amount": 10000,
"quoted_amount": 10000,
"executed_amount": null
},
"fees": [
{
"type": "bank",
"asset": "USDC",
"quoted_amount": 27518,
"executed_amount": null
},
{
"type": "platform",
"asset": "USDC",
"quoted_amount": 27518,
"executed_amount": null
},
{
"type": "network",
"asset": "ETH",
"quoted_amount": 100000000000,
"executed_amount": null
}
],
"travel_rule_info": {
"originating_party": {
"participant_guid": "customer_guid",
"type": "customer"
},
"receiving_party": {
"participant_guid": "counterparty_guid",
"type": "counterparty"
},
"ultimate_originating_party": {
"participant_guid": "bank_guid",
"type": "bank"
},
"ultimate_receiving_party": {
"participant_guid": "counterparty_guid",
"type": "counterparty"
}
}
}
Plan expirationPlans expire after a configured period (see the
expires_atfield in the response). An expired
plan cannot be executed and results in aplan_expirederror. Check the plan state before
execution.
Webhook support availableSubscribe to
plan.completedandplan.failedevents to receive real-time notifications
instead of polling. See the webhooks guide for setup.
Polling recommendationsPoll every 2-5 seconds for plan completion. Plans typically complete within 10-30 seconds.
Implement exponential backoff for longer-running operations.
Step 3: Execute the remittance plan
Execute the plan by creating an execution.
Currency conversion feesThe remittance process involves currency conversions to facilitate the cross-border payment. If
the final withdrawal to the destination bank account fails after conversions occur, any reversals
may incur fees.
Verify routing detailsPerform test deposits for new bank accounts and double-check all external bank account routing
details before execution. Common issues that cause withdrawal failures include:
- Incorrect CLABE numbers or routing codes
- Mismatched account holder names
- Invalid or closed bank accounts
- Incorrect bank identifiers
Automated retry guidance
Only remittance failures with error codes external_server_error and market_volatility are valid
for automated retries. Other error codes, such as invalid_destination_account, should not be
retried automatically and typically require manual review and correction of beneficiary or routing
details.
POST /api/executions
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"plan_guid": "plan_guid"
}Response
The execution returns in storing state while the platform processes the remittance.
Step 4: Monitor execution completion
Poll the execution endpoint until the state changes to completed.
Webhook support availableSubscribe to
execution.completedandexecution.failedevents to receive real-time
notifications instead of polling. See the webhooks guide
for setup.
Polling recommendationsPoll every 5-10 seconds for execution completion. Executions can take several minutes depending
on the destination country and payment rail. Implement exponential backoff for longer operations.
GET /api/executions/execution_guid
Authorization: Bearer YOUR_TOKEN{
"created_at": "2025-10-04T14:25:22.816775Z",
"updated_at": "2025-10-04T14:28:48.663787Z",
"guid": "execution_guid",
"state": "completed",
"type": "remittance",
"plan_guid": "plan_guid",
"customer_guid": "customer_guid",
"failure_code": null,
"stages": [
{
"created_at": "2025-10-04T14:24:55.865059Z",
"updated_at": "2025-10-04T14:28:48.562584Z",
"guid": "stage_guid",
"type": "payout",
"failure_code": null,
"state": "completed",
"source_account": {
"guid": "source_account_guid",
"asset": "USDC",
"type": "trading",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": null,
"requested_amount": null,
"quoted_amount": 5532205,
"executed_amount": 5532205
},
"destination_account": {
"guid": "destination_account_guid",
"asset": "MXN",
"type": "external_bank_account",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": "counterparty_guid",
"requested_amount": 10000,
"quoted_amount": 10000,
"executed_amount": 10000
},
"fees": [
{
"type": "bank",
"asset": "USDC",
"quoted_amount": 27524,
"executed_amount": 27524
},
{
"type": "platform",
"asset": "USDC",
"quoted_amount": 27524,
"executed_amount": 27524
},
{
"type": "network",
"asset": "ETH",
"quoted_amount": 100000000000,
"executed_amount": 100000000000
}
],
"identifiers": [],
"links": []
}
],
"source_account": {
"guid": "source_account_guid",
"asset": "USDC",
"type": "trading",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": null,
"requested_amount": null,
"quoted_amount": 5532205,
"executed_amount": null
},
"destination_account": {
"guid": "destination_account_guid",
"asset": "MXN",
"type": "external_bank_account",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"counterparty_guid": "counterparty_guid",
"requested_amount": 10000,
"quoted_amount": 10000,
"executed_amount": 10000
},
"fees": [
{
"type": "bank",
"asset": "USDC",
"quoted_amount": 27524,
"executed_amount": 27524
},
{
"type": "platform",
"asset": "USDC",
"quoted_amount": 27524,
"executed_amount": 27524
},
{
"type": "network",
"asset": "ETH",
"quoted_amount": 100000000000,
"executed_amount": 100000000000
}
],
"travel_rule_info": {
"originating_party": {
"participant_guid": "customer_guid",
"type": "customer"
},
"receiving_party": {
"participant_guid": "counterparty_guid",
"type": "counterparty"
},
"ultimate_originating_party": {
"participant_guid": "bank_guid",
"type": "bank"
},
"ultimate_receiving_party": {
"participant_guid": "counterparty_guid",
"type": "counterparty"
}
}
}Understand the response
Plan and execution responses share a common structure with the following key fields:
Source account
- quoted_amount - The cryptocurrency amount calculated at planning time
- executed_amount - The actual cryptocurrency amount withdrawn (populated after execution)
If you specified source_account.amount in the request, the quoted amount matches the requested
amount. For the remittance product, the executed amount matches the quoted amount.
Destination account
- quoted_amount - The destination currency amount calculated at planning time
- executed_amount - The actual amount deposited in the external bank account
If you specified destination_account.amount in the request, the quoted amount matches the
requested amount.
Fees
Remittance fees include platform fees, bank fees, and network fees:
- quoted_amount - The estimated fee at planning time
- executed_amount - The actual fee charged at execution time
Fee variabilityNetwork fees, especially for cryptocurrency conversions, may vary between quote and execution due
to blockchain network conditions. Theexecuted_amountreflects the actual fees charged.
Stages
Stages represent the individual steps of a plan. The remittance product uses a single payout stage
that transfers funds from the trading account to the external bank account.
Each stage includes two arrays for rail-issued reconciliation data:
- identifiers - Array of
{type, value}entries with rail-issued references (for example, the
utrreturned by India IMPS, NEFT, and RTGS). Always present; may be empty until the payout
settles. - links - Array of
{type, value}entries with rail-issued URLs (for example, receipt links).
Always present; may be empty.
Allowed type values vary by rail. Filter by type and ignore unknown entries to stay
forward-compatible. See the corridor-specific guides for the identifier and link types each rail
surfaces.
Supporting documents
The plan response echoes supporting_documents for partner-side reconciliation, with each entry
shaped as {guid, type, document_reference_number, files: [{guid, filename, content_type}]}.
document_reference_number appears only on the document that carries a reference number — for B2B
payouts to corridors that require one (for example, India and the Dominican Republic), exactly one
document in the array carries it. The array is empty when no documents are attached.
supporting_documents lives on the plan only — execution responses do not include it.
Error handling
Plan creation errors (HTTP 422)
| Error code | Description |
|---|---|
| unknown_bank_exception | Bank not found |
| no_customer_exception | Customer not found |
| frozen_customer_exception | Customer is frozen |
| rejected_customer_exception | Customer is rejected |
| unverified_customer_exception | Customer not verified |
| no_source_account_exception | Source account not found |
Execution creation errors
| Error Code | Description |
|---|---|
plan_expired | Plan has expired and cannot be executed |
invalid_parameter | Plan not in valid state or already executed |
List plans and executions
List plans
Retrieve plans filtered by customer, state, label, or other criteria.
GET /api/plans?customer_guid=customer_guid&state=completed
Authorization: Bearer YOUR_TOKENList executions
Retrieve executions for a specific plan or customer.
GET /api/executions?plan_guid=plan_guid
Authorization: Bearer YOUR_TOKENSee the Plans API reference and
Executions API reference for all available
filters.
Reference
For supported destination currencies, payment rails, upcoming corridors, and amount base unit
conventions, see Supported Corridors.
Plan states
| State | Description |
|---|---|
storing | Initial state while the system creates the plan |
planning | The system calculates rate quotes and fees |
completed | Plan is ready for execution |
failed | Planning failed (check failure_code) |
Execution states
| State | Description |
|---|---|
storing | Initial state while the system creates the execution |
executing | Remittance is in progress |
completed | Remittance completed successfully |
failed | Execution failed (check failure_code) |

