> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.bridge.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating to OUSD

> A step-by-step guide for migrating balances and payment routes from an existing stablecoin to OUSD

<Note>
  **USDx** is a placeholder used throughout this guide. Wherever you see `usdx` or USDx, substitute the stablecoin you're actually migrating *from* (for example, USDB or USDC). OUSD always refers to the stablecoin you're migrating *to*.
</Note>

The precise technical steps vary depending on your desired migration path (same chain or cross chain) and your current model. Use the table below to determine your migration path.

| Migration path | Guidance |
| - | - |
| USDx to OUSD on the **same chain** | Standard migration path; use the guide below. |
| USDx to OUSD **across chains** | Mimics a new operational set-up; follow the standard integration path:<br />• Create new custodial wallet(s) / virtual account(s) on the network of your choice.<br />• Create new payment routes (liquidation addresses, static transfer templates) directing to your new wallets / accounts.<br />• Initiate a transfer from your existing wallet to your new wallet. |

## Overview

The standard migration involves six main steps. Bridge highly recommends executing them in order to ensure an issue-free migration.

1. **Halt payments temporarily (planned downtime)** — temporarily stop new activity that could increment or reduce your Bridge wallet balance (e.g. incoming deposits or outgoing withdrawals) to avoid customer payment disruption during the migration window.
2. **Update liquidation addresses** — change the destination currency from `usdx` to `ousd`.
3. **Update static transfer templates** — change the destination currency and close out any active transfers still awaiting USDx.
4. **Update virtual accounts** — change the destination currency from `usdx` to `ousd`.
5. **Migrate wallet balances** — transfer funds from USDx to OUSD by creating transfers per wallet.
6. **Resume operations** — resume new activity now that migration is complete.

## Prerequisites

Before starting the migration, ensure you have the following:

* Your Bridge API key
* A list of all your **liquidation address IDs** (per customer)
* A list of all your **static transfer template IDs** (if applicable)
* A list of all your **virtual account IDs** (per customer, if applicable)
* A list of all your **wallet IDs** and their associated chains
* No in-flight transfers or wallet funding in progress

<Warning>
  **Prefunded wallets:** Ensure you are on the updated [Bridge Wallet APIs](/platform/wallets/overview) before proceeding with the migration. If you are still on the deprecated Prefunded Account APIs, moving to Bridge Wallets is a hard prerequisite. See the [migration path](/platform/orchestration/prefunded-accounts-deprecated).
</Warning>

<Note>
  **Rate limits** apply throughout the migration:

  | Limit | QPS | Burst | Scope |
  | - | - | - | - |
  | Reads (GET/HEAD) | 50 qps | 60 | All API read endpoints |
  | Writes (POST/PUT/PATCH/DELETE) | 10 qps | 11 | All API write endpoints |
</Note>

<Steps>
  <Step title="Step 1: Halt active transactions" titleSize="h2">
    Before making any changes, stop all new activity:

    * **Stop initiating new transfers** (both on-ramp and off-ramp)
    * **Stop funding wallets** with new deposits
    * **Wait for any in-flight transfers to reach a terminal state** (`payment_processed`, `canceled`, etc.)

    This prevents race conditions where a USDx transaction lands mid-migration, causing balance discrepancies.
  </Step>

  <Step title="Step 2: Update liquidation addresses" titleSize="h2">
    For each customer, update every liquidation address to change the destination currency from `usdx` to `ousd`.

    **Step 2a: List your liquidation addresses**

    Retrieve all liquidation addresses for a customer to identify which ones use USDx.

    API Reference: [Get all liquidation addresses for a customer](/api-reference/liquidation-addresses/get-all-liquidation-addresses)

    ```bash Request theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/customers/{customer_id}/liquidation_addresses' \
    --header 'Api-Key: <API Key>'
    ```

    **Step 2b: Update each liquidation address**

    API Reference: [Update a liquidation address](/api-reference/liquidation-addresses/update-a-liquidation-address)

    ```bash Request theme={null}
    curl --location --request PUT 'https://api.bridge.xyz/v0/customers/{customer_id}/liquidation_addresses/{liquidation_address_id}' \
    --header 'Api-Key: <API Key>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "destination": {
        "currency": "ousd"
      }
    }'
    ```

    <Note>
      * You must iterate through **each liquidation address** for **each customer**. There is no bulk update endpoint.
      * Only the `destination.currency` field is being changed for a same-chain migration. The address and payment rail otherwise remain the same.
      * Verify the update was successful by checking that the response shows `"currency": "ousd"` in the destination.
    </Note>
  </Step>

  <Step title="Step 3: Update static transfer templates" titleSize="h2">
    If you use static transfer templates, update each template's destination currency from `usdx` to `ousd` and close out any active transfers still awaiting USDx funds.

    **Step 3a: List your static transfer templates**

    Retrieve all your static transfer templates to identify which ones use USDx.

    API Reference: [Get all transfers](/api-reference/transfers/get-all-transfers)

    ```bash Request (all templates) theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/transfers/static_templates' \
    --header 'Api-Key: <API Key>'
    ```

    ```bash Request (per customer) theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/customers/{customer_id}/transfers/static_templates' \
    --header 'Api-Key: <API Key>'
    ```

    **Step 3b: Update the destination currency**

    For each static transfer template that uses USDx as the destination currency, update it to OUSD.

    API Reference: [Update a transfer](/api-reference/transfers/update-a-transfer)

    ```bash Request theme={null}
    curl --location --request PUT 'https://api.bridge.xyz/v0/transfers/{transfer_id}' \
    --header 'Api-Key: <API Key>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "destination": {
        "currency": "ousd",
        "payment_rail": "ethereum"
      }
    }'
    ```

    Replace `payment_rail` with your preferred chain.

    <Note>
      * After updating the template, new transfers created from it will use `ousd` as the destination.
      * You must iterate through each static transfer template individually. There is no bulk update endpoint.
    </Note>

    **Step 3c: Close out active transfers awaiting USDx**

    Any active transfers created from a static template that are still in the `awaiting_funds` state and expecting USDx should be deleted, since they will no longer receive USDx deposits.

    API Reference: [Delete a transfer](/api-reference/transfers/delete-a-transfer)

    ```bash Request theme={null}
    curl --location --request DELETE 'https://api.bridge.xyz/v0/transfers/{transfer_id}' \
    --header 'Api-Key: <API Key>'
    ```

    <Note>
      Only transfers in the `awaiting_funds` state can be deleted. Transfers that have progressed past this state must settle naturally.
    </Note>
  </Step>

  <Step title="Step 4: Update virtual accounts" titleSize="h2">
    If you use virtual accounts, update each virtual account's destination currency from `usdx` to `ousd`.

    **Step 4a: List your virtual accounts**

    Retrieve all virtual accounts for a customer to identify which ones use USDx.

    API Reference: [List virtual accounts by customer](/api-reference/virtual-accounts/get-a-virtual-account)

    ```bash Request theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/customers/{customer_id}/virtual_accounts' \
    --header 'Api-Key: <API Key>'
    ```

    **Step 4b: Update each virtual account**

    API Reference: [Update a virtual account](/api-reference/virtual-accounts/update-a-virtual-account)

    ```bash Request theme={null}
    curl --location --request PUT 'https://api.bridge.xyz/v0/customers/{customer_id}/virtual_accounts/{virtual_account_id}' \
    --header 'Api-Key: <API Key>' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "destination": {
        "currency": "ousd"
      }
    }'
    ```

    <Note>
      * You must iterate through each virtual account for each customer. There is no bulk update endpoint.
      * Only the `destination.currency` field is being changed for a same-chain migration. Deposit instructions otherwise remain the same.
      * Verify the update was successful by checking that the response shows `"currency": "ousd"` in the destination.
    </Note>
  </Step>

  <Step title="Step 5: Migrate wallet balances" titleSize="h2">
    For each wallet, create a transfer that moves the full USDx balance into OUSD.

    **Step 5a: List your wallets**

    Retrieve all Bridge wallets for a customer to identify which ones hold a USDx balance.

    API Reference: [Get all Bridge wallets for a customer](/api-reference/bridge-wallets/get-all-bridge-wallets)

    ```bash Request theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/customers/{customer_id}/wallets' \
    --header 'Api-Key: <API Key>'
    ```

    **Step 5b: Get each wallet's USDx balance**

    API Reference: [Get a Bridge wallet](/api-reference/bridge-wallets/get-a-bridge-wallet)

    ```bash Request theme={null}
    curl --location --request GET 'https://api.bridge.xyz/v0/wallets/{wallet_id}' \
    --header 'Api-Key: <API Key>'
    ```

    In the response, find the entry in the `balances` array where `currency` is `"usdx"`. The `balance` field is the amount you will transfer.

    ```json Response (excerpt) theme={null}
    {
      "id": "wallet_123",
      "balances": [
        {
          "balance": "50000.00",
          "currency": "usdx",
          "chain": "ethereum"
        }
      ]
    }
    ```

    **Step 5c: Create the transfer**

    For each wallet with a USDx balance, create a transfer to convert the full balance from USDx to OUSD.

    API Reference: [Create a transfer](/api-reference/transfers/create-a-transfer)

    ```bash Request theme={null}
    curl --location --request POST 'https://api.bridge.xyz/v0/transfers' \
    --header 'Api-Key: <API Key>' \
    --header 'Content-Type: application/json' \
    --header 'Idempotency-Key: migration-wallet-123-usdx-to-ousd' \
    --data-raw '{
      "on_behalf_of": "customer_abc",
      "amount": "50000.00",
      "source": {
        "currency": "usdx",
        "payment_rail": "bridge_wallet",
        "bridge_wallet_id": "wallet_123"
      },
      "destination": {
        "currency": "ousd",
        "payment_rail": "ethereum",
        "to_address": "0xYourWalletAddress"
      }
    }'
    ```

    Replace `payment_rail` with the chain your wallet is on (e.g. `ethereum`, `solana`, `base`, `arbitrum`, `polygon`, etc.). For a same-chain migration, this must match the wallet's current chain.

    <Note>
      * Create **one transfer per wallet per customer**.
      * Use the **full balance** from the GET wallet response. Do not leave partial USDx balances.
      * Use a **unique `Idempotency-Key`** per transfer to safely retry on failure (e.g. `migration-{wallet_id}-usdx-to-ousd`).
      * Monitor the transfer state — wait for it to reach `payment_processed` before proceeding.
    </Note>
  </Step>

  <Step title="Step 6: Resume operations" titleSize="h2">
    Once liquidation addresses, static transfer templates, virtual accounts, and wallet balances have all been migrated:

    * **Resume initiating new transfers** using `ousd` as the currency (on the destination chain, for cross-chain migrations)
    * **Resume wallet funding**
    * **Resume initiating prefunded transfers**, if applicable — these will now use OUSD as the source currency
    * Verify your systems are reading `ousd` balances correctly
  </Step>
</Steps>

## Rollback

If you need to reverse the migration, follow the steps in reverse order:

1. **Halt transactions** again
2. **Create transfers** from OUSD back to USDx for each wallet (swap source and destination currencies)
3. **Update virtual accounts** back to `usdx`
4. **Update static transfer templates** back to `usdx`
5. **Update liquidation addresses** back to `usdx`
6. **Resume operations**

<Warning>
  **Pending USDx deposits:** Any USDx that arrives after the fact (e.g. from in-flight transactions that settle late) should be:

  * Excluded from your aggregated USD balance, or
  * Shown as a pending balance that is not yet available for transactions

  Any straggler USDx must be converted to OUSD (by creating a transfer as described in [Step 5](#step-5-migrate-wallet-balances)) before it can be included in your total USD balance and used for new transactions. Failing to account for this may result in your system showing an inflated balance that includes funds not yet available in OUSD.
</Warning>
