Sending Cross-Border Payments

How do I send cross-border payments?

This guide walks you through sending 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 remittance

Contact Cybrid support to enable the remittance feature on your bank.

Overview

The remittance process involves four main steps:

  1. Create a remittance plan
  2. Wait for planning to complete
  3. Execute the plan
  4. 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:

The source trading account must:

  • Be in created state
  • Belong to a verified customer (not frozen, not rejected)

The destination external bank account must:

  • Have kind: raw_routing_details
  • Be in completed state
  • Meet KYC requirements for the destination country and currency

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 remittance for cross-border payments.

  • customer_guid or bank_guid (required) - The owner of the plan. Use customer_guid for customer-owned plans or bank_guid for 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 specification

You must specify EITHER source_account.amount OR destination_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, and other. See the API reference for the complete list of 30+ options.

  • 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.

Response

Initially, 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",
  "guid": "4384639658a5970ca442030d4d1eae98",
  "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": "05a518360c38ea017eb8fb539665fdc6",
      "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
        }
      ]
    }
  ],
  "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 expiration

Plans expire after a configured period (see the expires_at field in the response). An expired plan cannot be executed and results in a plan_expired error. Check the plan state before execution.

ℹ️

Polling recommendations

Poll every 2-5 seconds for plan completion. Plans typically complete within 10-30 seconds. Implement exponential backoff for longer-running operations. The platform does not currently support webhook events for plans.

Step 3: Execute the remittance plan

Execute the plan by creating an execution.

❗️

Currency conversion fees

The 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 details

Perform 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
POST /api/executions
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "plan_guid": "plan_guid"
}

Response

The response returns a storing state while the platform executes the remittance.

Step 4: Monitor execution completion

Poll the execution endpoint until the state changes to completed.

ℹ️

Polling recommendations

Poll 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. The platform does not currently support webhook events for executions.

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
        }
      ]
    }
  ],
  "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"
    }
  }
}

Understanding 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 variability

Network fees, especially for cryptocurrency conversions, may vary between quote and execution due to blockchain network conditions. The executed_amount reflects the actual fees charged.

Stages

Stages provide a view into the lifecycle of a plan. For the remittance product, there is only one stage payout where the funds transfer from the trading account to the external bank account.

Error handling

Plan creation errors (HTTP 422)

Error codeDescription
unknown_bank_exceptionBank not found
no_customer_exceptionCustomer not found
frozen_customer_exceptionCustomer is frozen
rejected_customer_exceptionCustomer is rejected
unverified_customer_exceptionCustomer not verified
no_source_account_exceptionSource account not found

Execution creation errors

Error CodeDescription
plan_expiredPlan has expired and cannot be executed
invalid_parameterPlan not in valid state or already executed

List plans and executions

List plans

Retrieve plans filtered by customer, state, or other criteria.

GET /api/plans?customer_guid=customer_guid&state=completed
Authorization: Bearer YOUR_TOKEN

List executions

Retrieve executions for a specific plan or customer.

GET /api/executions?plan_guid=plan_guid
Authorization: Bearer YOUR_TOKEN

See the Plans API reference and Executions API reference for all available filters.

Reference

Supported corridors

Cybrid supports the following destination currencies and payment rails:

CurrencyCountryPayment RailRouting Details
MXNMexicoSPEICLABE
ARSArgentinaCOELSACVU/CBU
COPColombiaPSEPSE (requires account_type)
BRLBrazilPIXPIX key (phone, email, CPF, CNPJ, random)
INRIndiaIFSCIFSC code + account number

For details on creating external bank accounts with these routing details, see Foreign Fiat External Bank Accounts.

⚠️

Country-specific requirements

Some corridors have country-specific requirements (KYC fields, purpose restrictions, participant types). See the corridor-specific guides:

Upcoming corridors

CountryStatusCurrency
BangladeshComing soonBDT
GhanaComing soonGHS
KenyaComing soonKES
NigeriaComing soonNGN
PakistanComing soonPKR

Amount base units

The API specifies all amounts in base units (the smallest denomination of the currency):

CurrencyDecimalsExample
USDC61 USDC = 1,000,000 base units
MXN21 MXN = 100 centavos
BRL21 BRL = 100 centavos
INR21 INR = 100 paise
ARS21 ARS = 100 centavos
COP21 COP = 100 centavos

To send 100 MXN, specify amount: 10000 (100 × 100 centavos).

Plan states

StateDescription
storingInitial state while the system creates the plan
planningThe system calculates rate quotes and fees
completedPlan is ready for execution
failedPlanning failed (check failure_code)

Execution states

StateDescription
storingInitial state while the system creates the execution
executingRemittance is in progress
completedRemittance completed successfully
failedExecution failed (check failure_code)