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

# Swaps

> Swaps let you exchange one stablecoin for another within HIFI wallets. All swaps follow a two-step process: create the swap request, then accept it to execute the exchange.

## Overview

<Steps>
  <Step title="Create swap request">
    Specify source currency, destination currency, and amount to exchange. The
    swap is created with `OPEN_QUOTE` status.
  </Step>

  <Step title="Accept the swap">
    Accept the swap using the [Accept
    Swap](https://docs.hifi.com/api-reference/swap/accept-a-swap) endpoint
    to execute the exchange.
  </Step>

  <Step title="Completion">
    Receive the swapped currency in the destination wallet once the swap is
    accepted and executed.
  </Step>
</Steps>

## Supported Pairs

| Source              | Destination                                                      |
| ------------------- | ---------------------------------------------------------------- |
| **Polygon - USDC**  | Polygon (USDT), Ethereum (USDT, USDG), Solana (USDT, USDG)       |
| **Polygon - USDT**  | Polygon (USDC), Ethereum (USDC, USDG), Solana (USDC, USDG)       |
| **Ethereum - USDC** | Polygon (USDT), Ethereum (USDT, USDG), Solana (USDT, USDG)       |
| **Ethereum - USDT** | Polygon (USDC), Ethereum (USDC, USDG), Solana (USDC, USDG)       |
| **Ethereum - USDG** | Polygon (USDC, USDT), Ethereum (USDC, USDT), Solana (USDC, USDT) |
| **Solana - USDC**   | Polygon (USDT), Ethereum (USDT, USDG), Solana (USDT, USDG)       |
| **Solana - USDT**   | Polygon (USDC), Ethereum (USDC, USDG), Solana (USDC, USDG)       |
| **Solana - USDG**   | Polygon (USDC, USDT), Ethereum (USDC, USDT), Solana (USDC, USDT) |

<Info>
  USDG swapping is available upon request. Please contact support to get access.
</Info>

## Fees

The Swap endpoint uses a two-part billing model:

* **Market quote fees**: Fees are included in the swap quote response. Check the `quoteInformation` fields (`sendNet`, `receiveNet`) to see the amounts after market fees are applied.
* **Gas fees**: Network gas fees are charged separately on your invoice and are not included in the quote response.

## Creating Swaps

Use the [Create Swap](https://docs.hifi.com/api-reference/swap/create-a-swap) endpoint to exchange currencies on the same chain.

<CodeGroup>
  ```bash Swap with Source Amount theme={null}
  curl -X POST "https://sandbox.hifibridge.com/v2/wallets/swaps" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
      "source": {
        "userId": "usr_abc123",
        "chain": "POLYGON",
        "currency": "usdc",
        "amount": "100"
      },
      "destination": {
        "userId": "usr_abc123",
        "chain": "POLYGON",
        "currency": "usdt"
      }
    }'
  ```

  ```bash Swap with Destination Amount theme={null}
  curl -X POST "https://sandbox.hifibridge.com/v2/wallets/swaps" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
      "source": {
        "userId": "usr_abc123",
        "chain": "POLYGON",
        "currency": "usdc"
      },
      "destination": {
        "userId": "usr_abc123",
        "chain": "POLYGON",
        "currency": "usdt",
        "amount": "100"
      }
    }'
  ```
</CodeGroup>

The response contains the swap details. Swaps are created in `PENDING` status and require acceptance:

<Accordion title="Response">
  ```json theme={null}
  {
    "transferType": "WALLET.SWAP",
    "transferDetails": {
      "id": "swp_abc123",
      "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
      "status": "OPEN_QUOTE",
      "createdAt": "2025-08-20T03:55:29.437108+00:00",
      "updatedAt": "2025-08-20T03:55:31.837+00:00",
      "source": {
        "currency": "usdc",
        "amount": 100,
        "chain": "POLYGON",
        "userId": "usr_abc123"
      },
      "destination": {
        "currency": "usdt",
        "userId": "usr_abc123",
        "amount": 100,
        "chain": "POLYGON",
        "walletAddress": "0xe5727a4B1d93A26D6A7Adfaae145EFa41ED7f204"
      },
      "quoteInformation": {
        "sendGross": {
          "amount": "100",
          "currency": "usdc"
        },
        "sendNet": {
          "amount": "100",
          "currency": "usdc"
        },
        "receiveGross": {
          "amount": "100",
          "currency": "usdt"
        },
        "receiveNet": {
          "amount": "100",
          "currency": "usdt"
        },
        "rate": "1",
        "expiresAt": "2025-08-20T03:55:59.539+00:00"
      },
      "error": null,
      "errorDetails": null
    }
  }
  ```
</Accordion>

<ResponseField name="transferDetails.id" type="string">
  Unique swap ID. Use this to check status using the [Retrieve
  Swap](https://docs.hifi.com/api-reference/token-swap/retrieve-a-swap)
  endpoint.
</ResponseField>

<ResponseField name="transferDetails.status" type="string">
  Swap status. Swaps are created with `OPEN_QUOTE` status and must be accepted
  before execution. See [Transaction Status](#transaction-status) for details.
</ResponseField>

<ResponseField name="transferDetails.source" type="object">
  Source wallet details including currency, amount, chain, and user information.
</ResponseField>

<ResponseField name="transferDetails.destination" type="object">
  Destination wallet details including currency, amount received, chain, and
  user information.
</ResponseField>

<ResponseField name="transferDetails.quoteInformation" type="object">
  Swap quote details including exchange rate, amounts sent and received.

  <Expandable title="properties">
    <ResponseField name="sendGross" type="object">
      Total source currency amount sent.
    </ResponseField>

    <ResponseField name="sendNet" type="object">
      Net source currency amount after fees (if any).
    </ResponseField>

    <ResponseField name="receiveGross" type="object">
      Total destination currency amount received before fees.
    </ResponseField>

    <ResponseField name="receiveNet" type="object">
      Actual destination currency amount received. This is the amount that will be in your destination wallet.
    </ResponseField>

    <ResponseField name="rate" type="string">
      Exchange rate between source and destination currencies.
    </ResponseField>

    <ResponseField name="expiresAt" type="string">
      Quote expiration timestamp (if applicable).
    </ResponseField>
  </Expandable>
</ResponseField>

<Info>
  For detailed field documentation, see the [Create
  Swap](https://docs.hifi.com/api-reference/token-swap/create-a-swap) API
  reference.
</Info>

## Accepting Swaps

All swaps are created in `PENDING` status and require explicit acceptance before execution. Use the [Accept Swap](https://docs.hifi.com/api-reference/swap/accept-a-swap) endpoint to accept and execute a swap.

**Request:**

```bash theme={null}
curl -X POST "https://sandbox.hifibridge.com/v2/wallets/swaps/swp_abc123/accept" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The accept endpoint returns the same swap details structure as the create endpoint, with updated status:

<Accordion title="Response">
  ```json theme={null}
  {
    "transferType": "WALLET.SWAP",
    "transferDetails": {
      "id": "swp_abc123",
      "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
      "status": "CRAETED",
      "createdAt": "2025-08-20T03:55:29.437108+00:00",
      "updatedAt": "2025-08-20T04:08:10.837+00:00",
      "source": {
        "currency": "usdc",
        "amount": 100,
        "chain": "POLYGON",
        "userId": "usr_abc123"
      },
      "destination": {
        "currency": "usdt",
        "userId": "usr_abc123",
        "amount": 100,
        "chain": "POLYGON",
        "walletAddress": "0xe5727a4B1d93A26D6A7Adfaae145EFa41ED7f204"
      },
      "quoteInformation": {
        "sendGross": {
          "amount": "100",
          "currency": "usdc"
        },
        "sendNet": {
          "amount": "100",
          "currency": "usdc"
        },
        "receiveGross": {
          "amount": "100",
          "currency": "usdt"
        },
        "receiveNet": {
          "amount": "100",
          "currency": "usdt"
        },
        "rate": "1",
        "expiresAt": "2025-08-20T03:55:59.539+00:00"
      },
      "error": null,
      "errorDetails": null
    }
  }
  ```
</Accordion>

<ResponseField name="transferDetails.status" type="string">
  Swap status after acceptance. Transitions from `PENDING` to `COMPLETED` upon
  successful acceptance. See [Transaction Status](#transaction-status) for
  details.
</ResponseField>

<Note>
  **Required Step:** All swaps must be accepted before execution. After creating
  a swap, always call the accept endpoint to execute the exchange.
</Note>

## Transaction Status

Swaps progress through the following statuses:

| Status            | Description                                                  |
| :---------------- | :----------------------------------------------------------- |
| **OPEN\_QUOTE**   | Swap quote requested and waiting for acceptance              |
| **CREATED**       | Swap request accepted                                        |
| **PENDING**       | Swap processing                                              |
| **COMPLETED**     | Swap successfully executed                                   |
| **FAILED**        | Swap failed (check `error` and `errorDetails` for specifics) |
| **QUOTE\_FAILED** | Swap quote is expired or invalid                             |

<Note>
  **Status Updates:** Subscribe to `SWAP.TRANSACTION.CREATE` and `SWAP.STATUS.*`
  webhook events to receive real-time status notifications. See
  [Webhooks](/docs/webhooks) for setup instructions.
</Note>

## Tracking Swaps

Monitor swap status using the [Retrieve Swap](https://docs.hifi.com/api-reference/token-swap/retrieve-a-swap) endpoint.

**Request:**

```bash theme={null}
curl -X GET "https://sandbox.hifibridge.com/v2/wallets/swaps/swp_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The retrieve response includes current swap status:

<Accordion title="Response">
  ```json theme={null}
  {
    "transferType": "WALLET.SWAP",
    "transferDetails": {
      "id": "swp_abc123",
      "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
      "status": "COMPLETED",
      "createdAt": "2025-08-20T03:55:29.437108+00:00",
      "updatedAt": "2025-08-20T03:55:31.837+00:00",
      "source": {
        "currency": "usdc",
        "amount": 100,
        "chain": "POLYGON",
        "userId": "usr_abc123"
      },
      "destination": {
        "currency": "usdt",
        "userId": "usr_abc123",
        "amount": 100,
        "chain": "POLYGON",
        "walletAddress": "0xe5727a4B1d93A26D6A7Adfaae145EFa41ED7f204"
      },
      "quoteInformation": {
        "sendGross": {
          "amount": "100",
          "currency": "usdc"
        },
        "sendNet": {
          "amount": "100",
          "currency": "usdc"
        },
        "receiveGross": {
          "amount": "100",
          "currency": "usdt"
        },
        "receiveNet": {
          "amount": "100",
          "currency": "usdt"
        },
        "rate": "1",
        "expiresAt": "2025-08-20T03:55:59.539+00:00"
      },
      "error": null,
      "errorDetails": null
    }
  }
  ```
</Accordion>

<ResponseField name="transferDetails.status" type="string">
  Current swap status. See [Transaction Status](#transaction-status) for all
  possible statuses.
</ResponseField>

## Listing Swaps

Retrieve a list of all swaps associated with users under your organization using the [List Swaps](https://docs.hifi.com/api-reference/token-swap/list-all-swaps) endpoint. Swaps are returned sorted by creation date, with the most recent swaps appearing first.

**Request:**

```bash theme={null}
curl -X GET "https://sandbox.hifibridge.com/v2/wallets/swaps?userId=usr_abc123&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Query Parameters:**

<ResponseField name="userId" type="string" required="false">
  Filter swaps by a specific user ID. If omitted, returns swaps for all users
  under your organization.
</ResponseField>

<ResponseField name="limit" type="string" required="false">
  Number of swaps to return. Defaults to 10, maximum is 100.
</ResponseField>

<ResponseField name="createdBefore" type="string" required="false">
  Filter swaps created before this date. ISO format: YYYY-MM-DD.
</ResponseField>

<ResponseField name="createdAfter" type="string" required="false">
  Filter swaps created after this date. ISO format: YYYY-MM-DD.
</ResponseField>

**Response:**

<Accordion title="Response">
  ```json theme={null}
  {
    "count": 2,
    "data": [
      {
        "transferType": "WALLET.SWAP",
        "transferDetails": {
          "id": "swp_abc123",
          "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
          "status": "COMPLETED",
          "createdAt": "2025-08-20T03:55:29.437108+00:00",
          "updatedAt": "2025-08-20T04:08:10.837+00:00",
          "source": {
            "currency": "usdc",
            "amount": 100,
            "chain": "POLYGON",
            "userId": "usr_abc123"
          },
          "destination": {
            "currency": "usdt",
            "userId": "usr_abc123",
            "amount": 100,
            "chain": "POLYGON",
            "walletAddress": "0xe5727a4B1d93A26D6A7Adfaae145EFa41ED7f204"
          },
          "quoteInformation": {
            "sendGross": {
              "amount": "100",
              "currency": "usdc"
            },
            "sendNet": {
              "amount": "100",
              "currency": "usdc"
            },
            "receiveGross": {
              "amount": "100",
              "currency": "usdt"
            },
            "receiveNet": {
              "amount": "100",
              "currency": "usdt"
            },
            "rate": "1",
            "expiresAt": "2025-08-20T03:55:59.539+00:00"
          },
          "error": null,
          "errorDetails": null
        }
      },
      {
        "transferType": "WALLET.SWAP",
        "transferDetails": {
          "id": "swp_def456",
          "requestId": "2cd4f7f1-5940-5ecf-9ad4-c17e0756bf97",
          "status": "PENDING",
          "createdAt": "2025-08-20T02:30:15.123456+00:00",
          "updatedAt": "2025-08-20T02:30:15.123456+00:00",
          "source": {
            "currency": "usdt",
            "amount": 50,
            "chain": "POLYGON",
            "userId": "usr_abc123"
          },
          "destination": {
            "currency": "usdc",
            "userId": "usr_abc123",
            "chain": "POLYGON",
            "walletAddress": "0xe5727a4B1d93A26D6A7Adfaae145EFa41ED7f204"
          },
          "quoteInformation": {
            "sendGross": {
              "amount": "50",
              "currency": "usdt"
            },
            "sendNet": {
              "amount": "50",
              "currency": "usdt"
            },
            "receiveGross": {
              "amount": "50",
              "currency": "usdc"
            },
            "receiveNet": {
              "amount": "50",
              "currency": "usdc"
            },
            "rate": "1",
            "expiresAt": "2025-08-20T02:35:15.123456+00:00"
          },
          "error": null,
          "errorDetails": null
        }
      }
    ],
    "nextCursor": "2025-08-20T02:30:15.123456+00:00"
  }
  ```
</Accordion>

<ResponseField name="count" type="integer">
  Total number of swaps returned in this response.
</ResponseField>

<ResponseField name="data" type="array">
  Array of swap objects. Each object follows the same structure as the swap
  details returned by the retrieve endpoint.
</ResponseField>

<ResponseField name="nextCursor" type="string">
  Timestamp cursor for pagination. Use this value with `createdBefore` parameter
  to fetch the next page of results.
</ResponseField>

<Note>
  **Pagination:** To fetch more swaps, use the `nextCursor` value as the
  `createdBefore` parameter in your next request. Continue until `count` is less
  than your `limit`, indicating you've reached the end.
</Note>

## Key Concepts

<AccordionGroup>
  <Accordion title="Amount Specification">
    You can specify the amount in either source or destination:

    **Source amount** (you send exactly 100 USDC):

    ```json theme={null}
    {
      "source": {
        "currency": "usdc",
        "amount": "100"
      },
      "destination": {
        "currency": "usdt"
      }
    }
    ```

    **Destination amount** (you receive exactly 100 USDT):

    ```json theme={null}
    {
      "source": {
        "currency": "usdc"
      },
      "destination": {
        "currency": "usdt",
        "amount": "100"
      }
    }
    ```

    Provide amount in only one side - the system calculates the other based on the current rate.
  </Accordion>

  <Accordion title="Exchange Rates">
    The `quoteInformation.rate` shows the exchange rate between currencies. Rates may vary slightly based on liquidity Always verify `receiveNet` to see the exact amount you'll receive after any fees.
  </Accordion>

  <Accordion title="External Wallet Swaps">
    Swap to external wallets (not managed by HIFI) by providing `externalWalletId` or `walletAddress`:

    ```json theme={null}
    {
      "destination": {
        "chain": "POLYGON",
        "currency": "usdt",
        "walletAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
      }
    }
    ```

    Or use a registered external wallet:

    ```json theme={null}
    {
      "destination": {
        "chain": "POLYGON",
        "currency": "usdt",
        "externalWalletId": "ext_xyz789"
      }
    }
    ```
  </Accordion>

  <Accordion title="Swap vs Bridge vs Transfer">
    Understanding the differences:

    **Swaps**: Exchange different currencies on the same/across chain (USDC → USDT)

    **Bridges**: Move same currency across chains (USDC on Polygon → USDC on Ethereum)

    **Transfers**: Move same currency to another wallet on same chain (USDC wallet A → USDC wallet B on Polygon)
  </Accordion>
</AccordionGroup>

## Sample Code

### Basic swap flow

<Steps>
  <Step title="Create swap">
    ```bash theme={null}
    curl -X POST "https://sandbox.hifibridge.com/v2/wallets/swaps" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "requestId": "1ab3e6e0-4839-4dbe-89c3-b06d9645ae86",
        "source": {
          "userId": "usr_abc123",
          "chain": "POLYGON",
          "currency": "usdc",
          "amount": "100"
        },
        "destination": {
          "userId": "usr_abc123",
          "chain": "POLYGON",
          "currency": "usdt"
        }
      }'
    ```

    The response will show status `OPEN_QUOTE`. Save the swap `id` from the response.
  </Step>

  <Step title="Accept the swap">
    Accept the swap to execute the exchange:

    ```bash theme={null}
    curl -X POST "https://sandbox.hifibridge.com/v2/wallets/swaps/swp_abc123/accept" \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    The response will show status `CRAETED` for successful swap request acceptance.
  </Step>

  <Step title="Verify completion">
    Review the swap details to confirm:

    * **Status** – should be `COMPLETED`
    * **Destination Amount** – the amount received
  </Step>

  <Step title="Handle errors">
    If status is `FAILED`:

    * Check `error` field for error type
    * Review `errorDetails` for specific failure reason
    * Common issues: insufficient balance, unsupported pair, not enough liquidity
  </Step>
</Steps>

## Getting Help

* 📧 **Email:** [support@hifi.com](mailto:support@hifi.com)
* 💬 **Slack:** Message us in our shared Slack channel

## Related Resources

* [Wallet Transfers](/docs/transactions/transfer) - Same-chain transfers without currency exchange
* [Bridging](/docs/transactions/bridging) - Cross-chain asset movement
* [Wallets](/docs/wallets) - Understand wallet addresses and balances
* [Webhooks](/docs/webhooks) - Real-time swap status notifications
* [API Reference](https://docs.hifi.com/api-reference/token-swap/create-a-swap) - Complete endpoint documentation
