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

# Quickstart

> In this guide, you'll learn how to use the HIFI Sandbox API to simulate money movement. You'll create users, complete KYC, set up a virtual account, simulate a deposit to fund a wallet, and execute a transfer between wallets.

**⏱️ Time to complete:** 10-15 minutes

**🎯 What you'll build:** A complete setup flow where you create a user, complete KYC, set up a virtual account, simulate a deposit to fund the wallet, and execute a transfer between wallets.

## Sandbox Environment

This guide uses the **Sandbox API** where:

* ✅ All transactions are simulated - no real money moves
* ✅ KYC applications are typically automatically approved
* ✅ Transactions complete instantly for testing
* ✅ You can experiment freely without financial risk

The sandbox behaves identically to production, making it perfect for integration testing.

***

## Prerequisites

Before you start, make sure you have:

* **API keys** from the Dashboard ([Get API keys](/docs/api/authentication))
* **A tool for making API calls** (cURL, Postman, or similar)
* **Basic understanding of REST APIs**
* **Your sandbox endpoint:** `https://sandbox.hifibridge.com`

<Note>
  All examples in this guide use the sandbox environment. When you're ready for
  production, simply replace the sandbox URL with the production endpoint and
  use your production API keys.
</Note>

***

## What you'll build

Here's what we'll accomplish in this guide:

1. **User Creation** - Create a user and accept Terms of Service
2. **KYC Process** - Complete verification to unlock fiat rails
3. **Set Up Virtual Account** - Create a virtual account for receiving deposits
4. **Simulate Deposit** - Fund the wallet by simulating a deposit (onramp)
5. **Execute a Transfer** - Send stablecoins between wallets
6. **Create Offramp Account** - Register a bank account for receiving fiat
7. **Create an Offramp** - Convert stablecoins back to fiat currency

***

## Create a User

The **User** object represents an individual or business on HIFI. All transaction activity is associated with a user object.

Creating a user is a two-step process:

1. **Generate a Terms of Service link** for your end user to review and accept
2. **Create the user** once they've accepted the terms

Once created, users are automatically provisioned with cryptocurrency wallet addresses, enabling them to immediately send and receive digital assets.

<AccordionGroup>
  <Accordion title="Generate Terms of Service Link">
    Before creating a user, they must accept HIFI's Terms of Service. Generate a unique acceptance link using the [Generate Terms of Service Link](https://docs.hifi.com/v2/reference/post_v2-tos-link) endpoint.

    You'll provide an `idempotencyKey` (any [UUID](https://www.uuidgenerator.net/)), which will become your `signedAgreementId` after the user accepts the terms.

    **Request:**

    ```bash theme={null}
    curl --request POST \
         --url https://sandbox.hifibridge.com/v2/tos-link \
         --header 'accept: application/json' \
         --header 'authorization: Bearer YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "idempotencyKey": "8cb49537-bcf9-41b1-8d8c-c9c200d7341b"
    }
    '
    ```

    **Response:**

    ```json theme={null}
    {
      "url": "TERMS_OF_SERVICE_URL",
      "signedAgreementId": "8cb49537-bcf9-41b1-8d8c-c9c200d7341b"
    }
    ```

    **What to do with this response:**

    1. **Direct your user to the `url`** - Present this link to your end user (via email, in your app, etc.)
    2. **Save the `signedAgreementId`** - You'll need this to create the user in the next step
    3. **Wait for acceptance** - The `signedAgreementId` becomes valid only after the user clicks "Accept"

    <Note>
      **Real-time Notifications:** HIFI triggers the `TOS_LINK.UPDATE` webhook event
      when the user accepts the terms, allowing you to proceed with user creation
      immediately. [Learn about webhooks →](/docs/webhooks)
    </Note>
  </Accordion>

  <Accordion title="Create User">
    Once your user has accepted the Terms of Service (and you've received the webhook event or confirmed acceptance), create the user account with the [Create User](https://docs.hifi.com/api-reference/user/create-a-user) endpoint.

    **Request:**

    ```bash theme={null}
    curl --request POST \
         --url https://sandbox.hifibridge.com/v2/users \
         --header 'accept: application/json' \
         --header 'authorization: Bearer YOUR_API_KEY' \
         --header 'content-type: application/json' \
         --data '
    {
      "type": "individual",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john@hifibridge.com",
      "dateOfBirth": "1999-01-01",
      "address": {
        "addressLine1": "123 Main St",
        "city": "New York",
        "stateProvinceRegion": "NY",
        "postalCode": "10010",
        "country": "USA"
      },
      "signedAgreementId": "8cb49537-bcf9-41b1-8d8c-c9c200d7341b",
      "requestId": "705f1f8b-a080-467c-b683-174eca409928"
    }
    '
    ```

    **Response:**

    ```json theme={null}
    {
      "id": "32051b2f-0798-55a7-9c42-b08da4192c97",
      "type": "individual",
      "email": "john@hifibridge.com",
      "name": "John Doe",
      "wallets": {
        "INDIVIDUAL": {
          "POLYGON": {
            "address": "0x1b932E54e77Aeb698144550d5a493Ea99E20Daa7"
          },
          "ETHEREUM": {
            "address": "0xC1c767eaB34b3Cc2C33a354f6Ff2c20fCB98D3C9"
          }
        }
      }
    }
    ```

    ✅ **User created successfully!**

    **What you get:**

    * **User ID** (`32051b2f-0798-55a7-9c42-b08da4192c97`) - Save this for all future operations
    * **Wallet addresses** - Pre-provisioned on multiple blockchains, ready to use immediately

    <ResponseField name="wallets" type="object">
      <Expandable title="properties">
        <ResponseField name="INDIVIDUAL" type="object">
          <Expandable title="properties">
            <ResponseField name="POLYGON" type="object">
              <Expandable title="properties">
                <ResponseField name="address" type="string">
                  Wallet address on the Polygon network
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="ETHEREUM" type="object">
              <Expandable title="properties">
                <ResponseField name="address" type="string">
                  Wallet address on the Ethereum network
                </ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>

    * **Account status** - Active and ready for KYC verification

    <Info>
      **Automatic Wallet Provisioning:** Every user automatically receives wallet
      addresses on supported blockchain networks (Polygon, Ethereum, etc.). These
      wallets are fully functional immediately - no additional setup required.
    </Info>

    ### What's Next?

    Now that you have a user, the next step is to complete KYC verification to unlock the ability to move money between fiat and crypto. Continue to the [KYC section](#kyc-know-your-customer) below.
  </Accordion>
</AccordionGroup>

***

## Complete KYC

To move money between stablecoins and fiat currencies, users must complete KYC verification to unlock a **Rail**.

**What is a Rail?** A rail is a payment corridor that enables specific currency conversions. For example, the USD rail enables conversions between USD (fiat) and stablecoins like USDC.

In this quickstart, we'll complete KYC for the **USD rail**, which allows your user to:

* Deposit USD and receive USDC (onramp)
* Send USDC and receive USD (offramp)

<Note>
  **Rail-Specific Requirements:** Each rail has different KYC requirements based
  on regulatory needs. Visit our [Rails page](/docs/rails) to learn about
  available rails and their specific requirements.
</Note>

### Recommended: Use KYC Links

The easiest way to collect KYC information is using **KYC Links**, which provide a hosted, user-friendly flow. Generate a KYC link and redirect your user to complete verification.

**Request:**

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/kyc-link \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "userId": "32051b2f-0798-55a7-9c42-b08da4192c97",
  "rails": ["USD"],
  "redirectUrl": "https://yourapp.com/kyc-complete"
}
'
```

**Response:**

```json theme={null}
{
  "kycLinkUrl": "KYC_LINK_URL"
}
```

**What to do:**

1. **Redirect your user** to the `kycLinkUrl` - They'll complete KYC on HIFI's hosted page
2. **User completes KYC** - They fill out information and upload documents
3. **User is redirected back** - After completion, they're sent to your `redirectUrl` with `?userId=...`
4. **Monitor status** - Check KYC status via API or webhooks

<Info>
  **KYC Links Benefits:** KYC Links handle all the complexity of document
  uploads, validation, and submission automatically. This is the recommended
  approach for most integrations. [Learn more about KYC Links
  →](/docs/features/kyc-links)
</Info>

### Alternative: Use API

If you need full control over the KYC collection process, you can submit KYC programmatically using the API. This approach requires you to:

1. Retrieve KYC requirements
2. Update KYC information
3. Upload identity documents
4. Submit the KYC application
5. Monitor approval status

<Note>
  For detailed instructions on programmatic KYC submission, see our [Submit KYC
  Guide](/docs/guides/submit-kyc).
</Note>

### Check KYC Status

After your user completes KYC (via KYC Link or programmatic submission), check their status:

**Request:**

```bash theme={null}
curl --request GET \
     --url 'https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/kyc/status?rails=USD' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY'
```

**Response:**

```json theme={null}
{
  "status": "ACTIVE",
  "message": "",
  "reviewResult": {
    "reviewAnswer": "APPROVED",
    "reviewRejectType": "",
    "rejectReasons": [],
    "comment": ""
  }
}
```

✅ **KYC approved!** When status is `ACTIVE`, the USD rail is unlocked and the user can proceed with transfers.

<Note>
  **Sandbox Auto-Approval:** In the sandbox environment, KYC applications are
  typically automatically approved within minutes for testing purposes. In
  production, the review process typically takes 1-3 business days.
</Note>

You can monitor KYC status by:

1. **Polling** the [Retrieve KYC Status](https://docs.hifi.com/api-reference/kyc/retrieve-kyc-status) endpoint
2. **Listening** for `KYC.STATUS_UPDATE` [webhook events](/docs/webhooks/kyc-events)

***

## Create Virtual Account

Now that your user has passed KYC, you can add a **Virtual Account** to enable onramping (converting fiat deposits into stablecoins).

A **Virtual Account** is a bank account number automatically created by HIFI that your user can deposit money into. When fiat arrives, it's automatically converted to the specified stablecoin and sent to the user's wallet.

The parameters you specify determine the conversion:

* `sourceCurrency` - Fiat currency to deposit (e.g., `usd`)
* `destinationCurrency` - Stablecoin to receive (e.g., `usdc`)
* `destinationChain` - Blockchain network (e.g., `POLYGON`)

Let's create a virtual account that converts USD deposits into USDC on Polygon:

**Request:**

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/virtual-accounts \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "sourceCurrency": "usd",
  "destinationCurrency": "usdc",
  "destinationChain": "POLYGON"
}
'
```

**Response:**

```json theme={null}
{
  "message": "Virtual account created successfully",
  "accountInfo": {
    "id": "938e3b36-3be7-5535-ba12-8d89eb683e6b",
    "userId": "32051b2f-0798-55a7-9c42-b08da4192c97",
    "source": {
      "paymentRail": ["ach", "wire", "rtp"],
      "currency": "usd"
    },
    "destination": {
      "chain": "POLYGON",
      "currency": "usdc",
      "walletAddress": "0x1b932E54e77Aeb698144550d5a493Ea99E20Daa7",
      "externalWalletId": null
    },
    "status": "activated",
    "depositInstructions": {
      "bankName": "Cross River Bank",
      "bankAddress": "885 Teaneck Road, Teaneck, NJ 07666",
      "beneficiary": {
        "name": "John Doe",
        "address": "123 Main St, New York, NY, 10010, US"
      },
      "ach": {
        "routingNumber": "021214891",
        "accountNumber": "344176915009"
      },
      "wire": {
        "routingNumber": "021214891",
        "accountNumber": "344176915009"
      },
      "rtp": {
        "routingNumber": "021214891",
        "accountNumber": "344176915009"
      },
      "instruction": "Please deposit USD to the bank account provided. Ensure the beneficiary name matches the account holder name, or the payment may be rejected."
    }
  }
}
```

✅ **Virtual account created!** Your user can now deposit USD to onramp into USDC.

**Important Fields:**

<ResponseField name="accountInfo.id" type="string">
  The unique virtual account ID. **Save this** for retrieving account details
  and monitoring deposits.
</ResponseField>

<ResponseField name="accountInfo.depositInstructions" type="object">
  **Most Important:** Bank account details your user needs to send money to.
  Share these instructions with your user so they can deposit funds via their
  bank (wire transfer, ACH, or RTP).
</ResponseField>

<Info>
  **How to Use:** Provide these deposit instructions to your end user through
  your app/website. When they send money to this account via their bank, HIFI
  automatically detects the deposit, converts it to USDC, and sends it to their
  wallet.
</Info>

***

## Simulate Deposit

Before we can transfer funds, we need to fund the user's wallet. In sandbox, we'll simulate a deposit to the virtual account, which will trigger an onramp and deposit USDC into the user's wallet.

**What is an Onramp?** An onramp converts fiat money deposited into a virtual account into stablecoins and sends them to the user's wallet.

### How Onramps Work

In production, onramping happens automatically when your user sends money from their bank to the virtual account. HIFI detects the deposit and automatically triggers the conversion.

In sandbox, we use a simulation endpoint to mimic an incoming deposit without requiring real bank transfers.

### Simulate Deposit (Sandbox)

Since we're in sandbox, use the simulate endpoint to create a test deposit:

**Request:**

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/virtual-accounts/938e3b36-3be7-5535-ba12-8d89eb683e6b/simulate-deposit \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "paymentRail": "wire",
  "source": {
    "routingNumber": "021000021",
    "accountNumber": "516843515316",
    "name": "Jane Doe",
    "bankName": "JP Morgan Chase"
  },
  "amount": "2",
  "requestId": "32639f89-5fcc-4e31-8abe-0e710ba2e4a1",
  "reference": "This is a test deposit"
}
'
```

**Request Fields:**

<ResponseField name="paymentRail" type="string" required>
  How the money is being sent: `wire`, `ach`, or `rtp`
</ResponseField>

<ResponseField name="source" type="object" required>
  Simulates the sender's bank information. This represents the bank account
  sending money TO the virtual account.

  <Expandable title="properties">
    <ResponseField name="routingNumber" type="string">
      Sender's bank routing number
    </ResponseField>

    <ResponseField name="accountNumber" type="string">
      Sender's bank account number
    </ResponseField>

    <ResponseField name="name" type="string">
      Sender's name
    </ResponseField>

    <ResponseField name="bankName" type="string">
      Sender's bank name
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="amount" type="string" required>
  Amount of USD being deposited (will convert to equivalent USDC).
</ResponseField>

<ResponseField name="requestId" type="string" required>
  Unique identifier for this deposit simulation (UUID).
</ResponseField>

**Response:**

```json theme={null}
{
  "message": "Sandbox deposit triggered"
}
```

✅ **Deposit simulated!** HIFI will process the deposit and create an onramp transaction.

### Monitor Onramp Status

HIFI creates an onramp transaction when a deposit is detected. You'll receive a `ONRAMP.CREATE` webhook event with transaction details.

**Onramp Status Progression:**

1. `FIAT_PENDING` - Waiting for fiat to settle
2. `CRYPTO_PENDING` - Converting and sending crypto
3. `COMPLETE` - USDC delivered to wallet

**Monitor via:**

* **Webhooks:** Subscribe to `ONRAMP.UPDATE` events for real-time notifications
* **Polling:** Call [Retrieve an onramp](https://docs.hifi.com/api-reference/onramp/retrieve-an-onramp) with the transaction ID

<Info>
  **Learn More:** For detailed information about receiving money, see the
  [Receive Money Guide](/docs/guides/receive-money).
</Info>

<Note>
  **Wait for Completion:** Wait for the onramp status to reach `COMPLETE` before
  proceeding with the transfer. This ensures the user's wallet has funds
  available.
</Note>

***

## Execute a Transfer

Now that your user has funds in their wallet, you can execute a **transfer** - sending stablecoins directly between user wallets on the blockchain.

**What is a Transfer?** A transfer sends stablecoins from one user's wallet to another user's wallet. No fiat conversion occurs - this is pure crypto-to-crypto movement.

### Create Transfer

Send stablecoins from one user to another using the [Create a crypto transfer](https://docs.hifi.com/api-reference/crypto-transfer/create-a-crypto-transfer) endpoint.

**Request:**

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/wallets/transfers \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "source": {
    "userId": "32051b2f-0798-55a7-9c42-b08da4192c97"
  },
  "destination": {
    "userId": "30669fcc-b15e-4137-b4fc-9e8f7f659a87"
  },
  "requestId": "a40ea2aa-7937-4be9-bb1f-b75f1489bcc6",
  "amount": 1,
  "currency": "usdc",
  "chain": "POLYGON"
}
'
```

**Request Fields:**

<ResponseField name="requestId" type="string" required>
  Unique identifier (UUID) for this transfer request. Ensures idempotency -
  retrying with the same ID won't create duplicate transfers.
</ResponseField>

<ResponseField name="source" type="object" required>
  Source of the transfer.

  <Expandable title="properties">
    <ResponseField name="userId" type="string" required>
      The user sending the crypto.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="destination" type="object" required>
  Destination of the transfer.

  <Expandable title="properties">
    <ResponseField name="userId" type="string" required>
      The user receiving the crypto.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="amount" type="number" required>
  Amount of stablecoins to transfer.
</ResponseField>

<ResponseField name="currency" type="string" required>
  Stablecoin to transfer (e.g., `usdc`, `usdt`).
</ResponseField>

<ResponseField name="chain" type="string" required>
  Blockchain network for the transfer (e.g., `POLYGON`, `ETHEREUM`).
</ResponseField>

**Response:**

```json theme={null}
{
  "transferType": "WALLET.TRANSFER",
  "transferDetails": {
    "id": "1a1ad1dd-ad72-4f3f-910b-c45dcf09875f",
    "requestId": "a40ea2aa-7937-4be9-bb1f-b75f1489bcc6",
    "createdAt": "2025-09-26T03:04:11.092Z",
    "updatedAt": "2025-09-26T03:04:11.092Z",
    "chain": "POLYGON",
    "currency": "usdc",
    "contractAddress": "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582",
    "status": "CREATED",
    "failedReason": null,
    "source": {
      "userId": "32051b2f-0798-55a7-9c42-b08da4192c97",
      "walletAddress": "0x1b932E54e77Aeb698144550d5a493Ea99E20Daa7",
      "walletType": "INDIVIDUAL",
      "user": {
        "email": "john@hifibridge.com",
        "lastName": "Doe",
        "firstName": "John",
        "businessName": null
      }
    },
    "destination": {
      "userId": "30669fcc-b15e-4137-b4fc-9e8f7f659a87",
      "walletAddress": "0x1b932E54e77Aeb688144550d5a493Ea99E20Daa7",
      "user": {
        "email": "Jane@hifibridge.com",
        "lastName": "Doe",
        "firstName": "Jane",
        "businessName": null
      }
    },
    "amount": 1,
    "amountIncludeDeveloperFee": 1,
    "receipt": {
      "transactionHash": null,
      "userOpHash": null
    }
  }
}
```

✅ **Transfer created!**

**Important Fields:**

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

<ResponseField name="transferDetails.status" type="string">
  Transfer status. Starts as `CREATED`, then progresses through: - `CREATED` -
  Transfer initiated - `PENDING` - Being processed on blockchain - `COMPLETE` -
  Successfully delivered - `FAILED` - Transfer failed (see failedReason)
</ResponseField>

### Monitor Transfer Status

**Transfer Status Progression:**

1. `CREATED` - Transfer initiated
2. `PENDING` - Being processed on blockchain
3. `COMPLETE` - Successfully delivered
4. `FAILED` - Transfer failed (see `failedReason`)

**Monitor via:**

* **Webhooks:** Subscribe to `WALLET.TRANSFER.UPDATE` events for real-time notifications
* **Polling:** Call [Retrieve a crypto transfer](https://docs.hifi.com/api-reference/crypto-transfer/retrieve-a-crypto-transfer) with the transfer ID

<Info>
  **Learn More:** For detailed information about other transaction types, see: -
  [Receive Money](/docs/guides/receive-money) - Convert fiat to stablecoins -
  [Send Money](/docs/guides/send-money) - Convert stablecoins to fiat
</Info>

<Note>
  **Sandbox Simulation:** No real money moves in sandbox. All transfers are
  simulated, but the API requests and responses are identical to production.
</Note>

***

## Create an Offramp

Now let's convert stablecoins back to USD using an **offramp**. An offramp converts USDC to USD and sends it to a user's bank account.

### Create Offramp Account

Before creating an offramp, users need to register their bank account as an **offramp account**. This account will receive fiat currency when stablecoins are converted.

Create an offramp account using the [Create Account](https://docs.hifi.com/api-reference/account/create-an-account) endpoint:

<Tabs>
  <Tab title="USD (US Bank Account)">
    ```bash theme={null}
    curl -X POST "https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/accounts" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "rail": "offramp",
        "type": "us",
        "accountHolder": {
          "type": "individual",
          "name": "John Doe",
          "phone": "+18573491112",
          "email": "john@hifibridge.com",
          "address": {
            "addressLine1": "123 Main St",
            "city": "New York",
            "stateProvinceRegion": "NY",
            "postalCode": "10010",
            "country": "USA"
          }
        },
        "us": {
          "transferType": "wire",
          "accountType": "checking",
          "accountNumber": "99485843",
          "routingNumber": "011002877",
          "bankName": "HIFI Bank",
          "currency": "usd"
        }
      }'
    ```

    **Response:**

    ```json theme={null}
    {
      "status": "ACTIVE",
      "id": "583eb259-e78b-4f0c-a4b5-a8957876fa6f",
      "message": "Account created successfully"
    }
    ```

    ✅ **Account created!** Save the `id` - you'll need it when creating offramps.
  </Tab>

  <Tab title="Mexico (MXN - SPEI)">
    ```bash theme={null}
    curl -X POST "https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/accounts" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "rail": "offramp",
        "type": "mexicoGlobalNetwork",
        "accountHolder": {
          "type": "individual",
          "name": "John Doe",
          "dateOfBirth": "1990-01-01",
          "idNumber": "ABCD123456EFGH78",
          "nationality": "MEX",
          "address": {
            "addressLine1": "123 Main Street",
            "city": "Mexico City",
            "stateProvinceRegion": "CDMX",
            "postalCode": "01000",
            "country": "MEX"
          }
        },
        "mexicoGlobalNetwork": {
          "bankName": "Banco Nacional de México",
          "accountNumber": "1234567890",
          "clabe": "012345678901234567",
          "currency": "mxn"
        }
      }'
    ```
  </Tab>

  <Tab title="Brazil (BRL - PIX)">
    ```bash theme={null}
    curl -X POST "https://sandbox.hifibridge.com/v2/users/32051b2f-0798-55a7-9c42-b08da4192c97/accounts" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "rail": "offramp",
        "type": "brazilGlobalNetwork",
        "accountHolder": {
          "type": "individual",
          "name": "John Doe",
          "dateOfBirth": "1990-01-01",
          "idNumber": "12345678901",
          "nationality": "BRA",
          "address": {
            "addressLine1": "123 Main Street",
            "city": "São Paulo",
            "stateProvinceRegion": "SP",
            "postalCode": "01310-100",
            "country": "BRA"
          }
        },
        "brazilGlobalNetwork": {
          "bankName": "Banco do Brasil",
          "accountNumber": "12345-6",
          "branchNumber": "1234",
          "currency": "brl"
        }
      }'
    ```
  </Tab>
</Tabs>

**Monitor Account Status:**

Account status indicates whether the account is ready to use:

* `ACTIVE` - Account is validated and ready for offramps
* `PENDING` - Account is being validated (wait for activation)
* `REJECTED` - Validation failed (check `invalidFields` for details)

Monitor via webhooks (`ACCOUNT.UPDATE`) or by polling the [Retrieve an account](https://docs.hifi.com/api-reference/account/retrieve-an-account) endpoint.

<Info>
  **More Account Types:** For additional regions and currencies (China, Hong
  Kong, Nigeria, and more), see the [Offramp Accounts
  Guide](/docs/accounts/offramp-accounts).
</Info>

### Create Offramp Request

Create an offramp request to get a quote for converting USDC to USD:

**Request:**

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/offramps \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "requestId": "c5f8a2b1-3d4e-5f6a-7b8c-9d0e1f2a3b4c",
  "source": {
    "userId": "32051b2f-0798-55a7-9c42-b08da4192c97",
    "currency": "usdc",
    "chain": "POLYGON",
    "amount": 1
  },
  "destination": {
    "userId": "32051b2f-0798-55a7-9c42-b08da4192c97",
    "currency": "usd",
    "accountId": "583eb259-e78b-4f0c-a4b5-a8957876fa6f"
  }
}
'
```

**Response:**

```json theme={null}
{
  "transferType": "OFFRAMP",
  "transferDetails": {
    "id": "b838908b-95d0-4ebb-a2c6-8f0c142bcdd7",
    "status": "OPEN_QUOTE",
    "quoteInformation": {
      "exchangeRate": "0.99",
      "expiresAt": "2025-09-26T03:20:00.000Z"
    }
  }
}
```

Accept the quote to execute the conversion:

```bash theme={null}
curl --request POST \
     --url https://sandbox.hifibridge.com/v2/offramps/b838908b-95d0-4ebb-a2c6-8f0c142bcdd7/quote/accept \
     --header 'accept: application/json' \
     --header 'authorization: Bearer YOUR_API_KEY'
```

✅ **Offramp initiated!** Monitor status via webhooks (`OFFRAMP.UPDATE`) or by polling the [Retrieve an offramp](https://docs.hifi.com/api-reference/offramp/retrieve-an-offramp) endpoint.

<Info>
  **Learn More:** For detailed offramp information, see the [Send Money
  Guide](/docs/guides/send-money) and [Offramp
  Guide](/docs/transactions/offramps).
</Info>

***

## 🎉 Congratulations!

You've successfully completed the HIFI API quickstart! By following the steps above, you can now:

* ✅ Create users and handle Terms of Service acceptance
* ✅ Complete the KYC process to unlock fiat rails
* ✅ Set up virtual accounts for receiving deposits
* ✅ Simulate deposits to fund wallets
* ✅ Execute transfers between wallets
* ✅ Create offramp accounts for receiving fiat
* ✅ Create offramps to convert stablecoins to fiat

### Next Steps

Ready to build your integration? Here's what to explore next:

* **[Receive Money](/docs/guides/receive-money)** - Convert fiat to stablecoins
* **[Send Money](/docs/guides/send-money)** - Convert stablecoins to fiat
* **[Webhooks](/docs/webhooks)** - Set up real-time event notifications for transaction updates
* **[Rails Overview](/docs/rails)** - Learn about additional currency rails
* **[Error Handling](/docs/api/errors)** - Understand error codes and how to handle failures
* **[API Reference](https://docs.hifi.com/api-reference)** - Explore all available endpoints and parameters
