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

# Quickstart

> From a sandbox API key to your first order: register payment accounts, quote, order, and get webhooks.

Create and fund a sandbox onramp with this guide. First, create an API key under **Account, then Manage Accounts** in the [sandbox dashboard](https://sandbox.etherfuse.com/account/manage). See [Initial Setup](/v2/initial-setup) for account setup and base URLs.

Every request below uses the sandbox base URL `https://api.sand.etherfuse.com` and sends your key in the `Authorization` header, **with no `Bearer` prefix** (see [Authentication](/v2/authentication)).

<Steps>
  <Step title="Make your first call">
    Get your organization's `id`. Payment account, quote and order routes take it as `{organizationId}`:

    ```bash theme={null}
    curl https://api.sand.etherfuse.com/me \
      -H "Authorization: <your_sandbox_api_key>"
    ```

    ```json theme={null}
    { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "displayName": "Acme Inc", "approvedAt": "2026-04-15T12:00:00Z", "partnerFeeDefaultBps": 100 }
    ```

    This guide acts for your own organization. To act for a customer, use the customer organization's id instead. See [Organizations in the route](/v2/overview#organizations-in-the-route).

    List the organization's payment accounts. A new organization has none yet:

    ```bash theme={null}
    curl https://api.sand.etherfuse.com/organization/<organization_id>/payment_accounts \
      -H "Authorization: <your_sandbox_api_key>"
    ```

    ```json theme={null}
    { "items": [], "totalItems": 0, "pageSize": 30, "pageNumber": 0, "totalPages": 0 }
    ```

    A `401` with `type` ending in `unauthorized` means the key or the header is wrong. See [Authentication](/v2/authentication#troubleshooting).
  </Step>

  <Step title="Subscribe to order updates">
    Register the URL we send order events to. Store the `secret` from the response; we return it only once, and you need it to [verify each delivery](/v2/guides/verifying-webhooks).

    ```bash theme={null}
    curl -X POST https://api.sand.etherfuse.com/webhook_subscription \
      -H "Authorization: <your_sandbox_api_key>" \
      -H "Content-Type: application/json" \
      -d '{ "url": "https://example.com/etherfuse/webhooks", "eventType": "orderUpdated" }'
    ```

    Webhook subscriptions do not take an organization id. One subscription covers your organization and every customer organization. Add a `paymentAccountUpdated` subscription the same way to hear when an account becomes ready. See [Webhooks](/v2/webhooks).
  </Step>

  <Step title="Register a bank account and a wallet">
    Register the bank account the money comes from:

    ```bash theme={null}
    curl -X POST https://api.sand.etherfuse.com/organization/<organization_id>/payment_account \
      -H "Authorization: <your_sandbox_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "kind": "bank",
        "label": "Operating account",
        "country": "MX",
        "currency": "MXN",
        "accountDetails": { "kind": "clabe", "clabe": "012180000000000002" }
      }'
    ```

    Then register the wallet the tokens go to:

    ```bash theme={null}
    curl -X POST https://api.sand.etherfuse.com/organization/<organization_id>/payment_account \
      -H "Authorization: <your_sandbox_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "kind": "wallet",
        "label": "Treasury wallet",
        "accountDetails": {
          "kind": "address",
          "address": "<your_testnet_wallet_address>",
          "chain": "stellar"
        }
      }'
    ```

    Each response holds the account `id` and its `rails`. You can quote a direction once its `status` is `ready`. If a bank account returns `422` `registration-info-required`, add the fields listed in `missing` under `registrationInfo` and send it again. See [Register payment accounts](/v2/overview#the-flow).
  </Step>

  <Step title="Find the asset to buy">
    List the tokens your wallet can receive. Use a token's `asset` from the response in the quote.

    ```bash theme={null}
    curl "https://api.sand.etherfuse.com/supported_assets?paymentAccountId=<wallet_id>" \
      -H "Authorization: <your_sandbox_api_key>"
    ```

    ```json theme={null}
    {
      "markets": [],
      "tokens": [
        {
          "asset": "CETES:GC3CW7EDYRTWQ635VDIGY6S4ZUF5L6TQ7AA4MWS7LEQDBLUSZXV7UPS4",
          "chain": "stellar",
          "currency": "MXN",
          "symbol": "CETES",
          "name": "Etherfuse CETES",
          "image": "https://assets.etherfuse.com/cetes.png"
        }
      ]
    }
    ```

    The bank account's `asset` is its currency, `MXN`. See [`GET /supported_assets`](/v2/api-reference/assets/list-supported-assets).
  </Step>

  <Step title="Get a quote">
    Price the transfer between the two accounts. Quotes **expire after 2 minutes**.

    ```bash theme={null}
    curl -X POST https://api.sand.etherfuse.com/organization/<organization_id>/quote \
      -H "Authorization: <your_sandbox_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "source": { "type": "stored", "id": "<bank_account_id>" },
        "destination": { "type": "stored", "id": "<wallet_id>" },
        "sourceAmount": "100",
        "sourceAsset": "MXN",
        "destinationAsset": "<asset_identifier>"
      }'
    ```

    The response holds the `quoteId`, `destinationAmount`, `rateAfterFees`, `feeBps` and the fee lines in `fees[]`. Both accounts must belong to the organization in the route. See [`POST /organization/{organizationId}/quote`](/v2/api-reference/quotes/create-quote).
  </Step>

  <Step title="Create the order">
    ```bash theme={null}
    curl -X POST https://api.sand.etherfuse.com/organization/<organization_id>/order \
      -H "Authorization: <your_sandbox_api_key>" \
      -H "Content-Type: application/json" \
      -d '{ "quoteId": "<quote_id>" }'
    ```

    The response is `201` with the order. Its `id` equals the `quoteId`, and sending the same `quoteId` again returns the same order (see [Idempotency](/v2/idempotency)). `fundingInstructions.destination` says where the source sends the funds once it is available: a CLABE for a bank source, a blockchain address for a wallet source. An `orderUpdated` delivery tells you when it arrives.
  </Step>

  <Step title="Fund the order">
    How you fund the order depends on the source account.

    <Tabs>
      <Tab title="Bank source (onramp)">
        In sandbox no real money moves. Simulate the customer's SPEI payment:

        ```bash theme={null}
        curl -X POST https://api.sand.etherfuse.com/organization/<organization_id>/order/<order_id>/fiat_received \
          -H "Authorization: <your_sandbox_api_key>" \
          -H "Content-Type: application/json" \
          -d '{ "amount": "100" }'
        ```

        See [`POST /organization/{organizationId}/order/{id}/fiat_received`](/v2/api-reference/sandbox/simulate-fiat-received).
      </Tab>

      <Tab title="Wallet source (offramp or swap)">
        There is nothing to simulate: the wallet sends the tokens on the testnet. `fundingInstructions.rail` is the wallet's chain, and `fundingInstructions.destination` holds the address to send to. Fund the order before `fundingDeadline` in one of two ways:

        1. **Sign the prepared transaction.** When `preparedTransaction` is present, deserialize `transaction`, sign it with the wallet, and submit it to the network.
        2. **Send a transfer yourself.** Send the order's `source.amount` of `source.asset` to `address`, with `memo` when it is present.

        ```json theme={null}
        {
          "fundingInstructions": {
            "rail": "stellar",
            "reference": "1000042",
            "fundingDeadline": "2026-10-07T12:30:00Z",
            "destination": {
              "address": "GBX3...",
              "expiresAt": null,
              "preparedTransaction": { "transaction": "AAAAAgAAAA...", "refreshAfter": "2026-10-07T12:30:00Z" }
            }
          }
        }
        ```

        An [embedded wallet](/v2/guides/embedded-wallets) does not send anything itself: its owner approves the order's `authorization`, and we move the funds.

        You need testnet tokens to fund from a wallet. Get them by running the bank-source onramp first. See [Testnet tokens](/v2/test-environment#testnet-tokens) and the [Offramps](/v2/guides/testing-offramps) guide.
      </Tab>
    </Tabs>

    We detect the funds, then the order moves to `funded` and `completed`. An onramp can move to `claimable` instead, when the wallet has to claim the tokens (for example a Stellar wallet with no trustline yet). Each change sends an `orderUpdated` delivery with the full order.
  </Step>
</Steps>

<Note>
  Sandbox onramps are capped at **500 MXN per quote**. See the [Sandbox Reference](/v2/test-environment).
</Note>

## Test other transfers

<CardGroup cols={3}>
  <Card title="Onramp" icon="arrow-up-right-dots" href="/v2/guides/testing-onramps">
    Fiat to tokens. The customer pays MXN and receives tokens.
  </Card>

  <Card title="Offramp" icon="arrow-down" href="/v2/guides/testing-offramps">
    Tokens to fiat. The customer sends tokens and receives MXN.
  </Card>

  <Card title="Swap" icon="right-left" href="/v2/guides/testing-swaps">
    Token to token. The customer exchanges one asset for another.
  </Card>
</CardGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Onboard customers" icon="user-check" href="/v2/guides/kyc-websdk">
    Run KYC for your customers before they transact.
  </Card>

  <Card title="Monitor with webhooks" icon="bell" href="/v2/webhooks">
    Get signed updates for orders, payment accounts and KYC instead of polling.
  </Card>

  <Card title="Understand the model" icon="diagram-project" href="/v2/overview">
    Payment accounts, rails, quotes, fees and order statuses.
  </Card>

  <Card title="Sandbox reference" icon="flask" href="/v2/test-environment">
    Test KYC data, simulated deposits, and testnet tokens.
  </Card>
</CardGroup>

## Migrating from v1

Follow the [V1 → V2 guide](/v2/migration-guide) to update an existing integration. Your API key, organizations, customers and KYC approvals remain valid.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.