Overview

The Transfer API enables seamless conversion to and from fiat and crypto across various supported currencies and rails. At its core, the API is designed to abstract away the complexity of cross-rail and cross-currency money movement, supporting:
  • Fiat → Crypto
  • Crypto → Crypto
  • Crypto → Fiat
Transfers include both a source and a destination, each of which can represent fiat sources or blockchain-based wallets. The API is generalized, composable, and rails-agnostic, allowing for a variety of transfer flows that suit modern financial applications. Refer to supported currencies and rails below:

How transfers work

Depending on the source, Bridge either pulls funds (e.g. Bridge wallet, prefunded account) or generates deposit instructions when a third-party source (e.g. bank, external wallet) is specified. If the funds reside outside of Bridge, you will receive a source_deposit_instructions object in the response payload containing deposit bank details or blockchain addresses. Once your customer completes the deposit, Bridge will automatically detect and process the payment to the destination.

Key Concepts

  • source: Where the funds come from. This can be a Bridge-controlled wallet, a customer’s crypto wallet, or a fiat source like a bank account.
  • destination: Where the funds go. This can be any supported rail or chain.
  • on_behalf_of: Customer identifier. Required when sending/receiving on behalf of a user.
  • developer_fee or developer_fee_percent: Monetize transfers via fixed or percentage fees. Refer the Developer Fees section on how to set fees.
  • features: Optional settings to add flexibility (e.g. allow_any_from_address, flexible_amount).

High Level Flow

For one time transfers, the high level flow is:
  1. You, the developer, will create a transfer specifying the source and destination
    1. If the source is a pre-funded account or a bridge wallet, Bridge will pull funds directly from it and skip the above steps — there is no deposit required.
  2. Bridge will create a transfer object which will include source_deposit_instructions.
  3. You will instruct your customer to follow the source_deposit_instructions.
  4. Your customer will send a deposit following the source_deposit_instructions.
  5. Bridge will match your customer’s deposit to the transfer you created.
  6. Bridge sends money to the destination.

Create Transfer

Request
curl --location --request POST 'https://api.bridge.xyz/v0/transfers' \
--header 'Api-Key: <API Key>' \
--header 'Idempotency-Key: <Unique Idempotency Key>' \
--data-raw '{
  "amount": "10.0",
  "on_behalf_of": "cust_alice",
  "developer_fee": "0.5",
  # source object tells Bridge where to expect deposits from.
  # can be fiat or crypto
  "source": {
    "payment_rail": "ach_push",
    "currency": "usd",
  },
  # deposit object tells Bridge where to send funds to.
  # can also be fiat or crypto
  "destination": {
    "payment_rail": "ethereum",
    "currency": "usdc",
    "to_address": "0xdeadbeef",
  },
}'
Response
{
  "id": "transfer_123",
  "state": "awaiting_funds",
  "on_behalf_of": "cust_alice",
  "amount": "10.0",
  "developer_fee": "0.5",
  "source": {
    "payment_rail": "ach_push",
    "currency": "usd"
  },
  "destination": {
    "payment_rail": "polygon",
    "currency": "usdc",
    "to_address": "0xdeadbeef"
  },
  # Very important that your customer follows the source deposit instructions
  "source_deposit_instructions": {
    "bank_account_number": "123456789", # Bridge's bank account number to send deposits to
    "bank_routing_number": "101019644", # Bridge's bank account routing number
 		# if the transfer requires a specific amount, it's important your customer includes
    # the exact amount expected.
    "amount": "10.0", 
    "currency": "usd",
    "deposit_message": "BVI7depositmessage", # important that the deposit message is included
  },
  "receipt": {
    "initial_amount": "10.0",
    "developer_fee": "0.5",
    "exchange_fee": "0.0",
    "final_amount": "9.5",
    "destination_tx_hash": "0xc0ffee", // A destination tx hash will appear after the transfer is complete
  },
  "created_at": "2023-05-05T19:39:14.316Z",
  "updated_at": "2023-05-05T19:39:15.231Z"
}

Deposit Instructions

Fiat Deposits
{
  ...
"source_deposit_instructions": {
    "bank_account_number": "123456789", # Bridge's bank account number to send deposits to
    "bank_routing_number": "101019644", # Bridge's bank account routing number
 		# if the transfer requires a specific amount, it's important your customer includes
    # the exact amount expected.
    "amount": "10.0", 
    "currency": "usd",
    "deposit_message": "BVI7depositmessage", # important that the deposit message is included
  },
   ...
}
Unique Deposit MessageDue to the limitations of fiat rails, we will create a unique identifier for your customer to attach to the deposit they send to Bridge. We rely on that identifier to match customer deposits to your transfer.
Direct your customer to send funds to Bridge’s bank account, with the required amount and currency, and to include the deposit message (starting with BRG). Your customer can include the unique deposit message as the wire memo/message, ACH push description, SEPA reference, or SPEI memo. The deposit message is unique per transfer and including it with your transaction is required for Bridge to process. Crypto Deposits If you receive crypto deposits, remember to configure a crypto return policy! Refer Crypto Return Policies
{
  ...
  "source_deposit_instructions": {
    "payment_rail": "ethereum", # expected blockchain
    "amount": "10.0", # expected amount
    "currency": "usdc", # expected currency
    "from_address": "0xdeadbeef", # expected address for funds to originate from
    "to_address": "0xc0ffee" # Bridge's deposit address to send funds to
  },
   ...
}
In this instance, we need to request your customer to deposit funds to Bridge from their wallet. The source_deposit_instructions object in the response will contain Bridge’s deposit address. You can guide your user to use Metamask or an equivalent wallet to create a blockchain transfer to move funds from their wallet to our deposit address. Memo Based Blockchains
{
  ...
  "source_deposit_instructions": {
    "payment_rail": "stellar",
    "amount": "10.0",
    "currency": "usdc",
    "from_address": "GDUY7JALICESTELLARADDRESS",
    "to_address": "GDUY7JSBRIDGESTELLARDEPOSITADDRESS",
    "blockchain_memo": "123456",
  },
  ...
}
For memo-based blockchains, such as Stellar and Tron, a blockchain_memo will be provided as part of the source_deposit_instructions in the response.
This must be included in the crypto deposit memo. When you forget to include the memo, your off-ramp will experience signficant delays

Transfer Delivery

Once we receive the deposit for your transfer, we will move the funds to the destination. You can use the Transfers API to check the state of the transfer or listen to webhooks.