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

# Overview

> Overview of the FX API

This API allows you to integrate crypto on/off ramps and swaps into your application. Your customers can buy crypto with fiat (onramp), sell crypto for fiat (offramp), or exchange one crypto asset for another (swap).

<Info>
  **Use the sandbox for development.** All examples in the guides work with the sandbox environment at `https://api.sand.etherfuse.com`. If you haven't set up your sandbox account, see [Initial Setup](/initial-setup).
</Info>

## Integration Flow

The typical integration follows this pattern:

<Steps>
  <Step title="Onboard Customer">
    Generate a presigned URL and have your customer complete KYC verification, bank account linking, and agreement signing. You generate the `customerId` and `bankAccountId` UUIDs — store them, as they're permanently bound after onboarding.

    Two approaches: [Hosted UI](/guides/onboarding-hosted) (fastest) or [Programmatic](/guides/onboarding-programmatic) (white-label). See [Onboarding Customers](/guides/onboarding) for details.
  </Step>

  <Step title="Get Available Assets">
    Discover which assets your customer can buy, sell, or swap. Use [GET /ramp/assets](/api-reference/assets/get-rampable-assets) (auth required, returns all rampable stablecoins and stablebonds for the chain, sorted by currency priority) or [GET /lookup/stablebonds](/api-reference/lookup/get-all-stablebonds) (public, all assets). Use the `identifier` field from the response when creating quotes.
  </Step>

  <Step title="Create Quote">
    Get pricing via [POST /ramp/quote](/api-reference/quotes/get-quote-for-conversion). Quotes expire after **2 minutes**. The response includes `exchangeRate`, `feeBps`, `feeAmount`, and `destinationAmount`.

    See the detailed guides for quote examples: [Onramps](/guides/testing-onramps), [Offramps](/guides/testing-offramps), [Swaps](/guides/testing-swaps).
  </Step>

  <Step title="Create Order or Swap">
    Execute using the quote. For on/off-ramps, call [POST /ramp/order](/api-reference/orders/create-a-new-order) — the order inherits direction and amounts from the quote. For swaps, call [POST /ramp/swap](/api-reference/swap/swap-assets).

    See [Testing Onramps](/guides/testing-onramps), [Testing Offramps](/guides/testing-offramps), or [Testing Swaps](/guides/testing-swaps) for the full flow.
  </Step>

  <Step title="Monitor via Webhooks">
    Subscribe to webhooks via [POST /ramp/webhook](/api-reference/webhooks/create-webhook) to receive real-time updates. See [Webhooks](#webhooks) below for event types and status flows.
  </Step>
</Steps>

***

## Quote Types

| Type      | Source                     | Target                     | Use Case                                  |
| --------- | -------------------------- | -------------------------- | ----------------------------------------- |
| `onramp`  | Fiat (MXN)                 | Crypto (USDC, CETES, etc.) | Customer buys crypto                      |
| `offramp` | Crypto (USDC, CETES, etc.) | Fiat (MXN)                 | Customer sells crypto                     |
| `swap`    | Crypto                     | Crypto                     | Customer exchanges one crypto for another |

***

## Fees

Fees are based on your rolling 30-day transaction volume. Higher volume means lower fees.

| 30-Day Volume (USD) | Fee            |
| ------------------- | -------------- |
| 0 - 5 million       | 20 bps (0.20%) |
| 5 - 10 million      | 15 bps (0.15%) |
| 10 - 50 million     | 10 bps (0.10%) |
| 50 - 100 million    | 8 bps (0.08%)  |
| 100 million+        | 5 bps (0.05%)  |

The fee is calculated on the output amount and included in the quote response (`feeBps`, `feeAmount`). Your current fee tier is applied automatically.

### Partner Fees

Organizations can configure an additional **partner fee** (up to 500 bps / 5.00%) that layers on top of the platform fee. This is useful for revenue sharing when you operate child organizations on behalf of partners.

* Set a default via [PUT /ramp/organization/\{org\_id}/partner-fee](/api-reference/organizations/set-partner-fee-default) or when [creating a child org](/api-reference/organizations/create-a-child-organization)
* Override per-quote by passing `partnerFeeBps` in the [quote request](/api-reference/quotes/get-quote-for-conversion)
* Resolution order: per-quote override > org default > 0
* Check your current default via [GET /ramp/me](/api-reference/lookup/get-current-organization-identity) (`partnerFeeDefaultBps`)

Partner fees are tracked on each order (`partnerFeeBps`, `partnerFeeAmountFiat`, `partnerFeeStatus`) and settled offline via finance — no on-chain component.

***

## Webhooks

Webhook payloads are signed with HMAC-SHA256. Every delivery includes an `X-Signature` header for verification. See [Verifying Webhooks](/guides/verifying-webhooks) for setup instructions and code examples.

### Event Types

| Event Type             | Description                                          |
| ---------------------- | ---------------------------------------------------- |
| `customer_updated`     | KYC verification status changed                      |
| `bank_account_updated` | Bank account verification status changed             |
| `order_updated`        | Order status changed                                 |
| `swap_updated`         | Swap transaction status changed                      |
| `kyc_updated`          | KYC submission status changed (for programmatic KYC) |

### Order Status Flow

**Onramp** (customer buys crypto with MXN):

```
created → funded → completed
    ↓        ↓
  failed   refunded
    ↓
 canceled
```

1. **`created`** — Waiting for customer to deposit MXN to the `depositClabe`
2. **`funded`** — MXN deposit received and confirmed
3. **`completed`** — Crypto sent to customer's wallet (`confirmedTxSignature` contains the tx hash)

**Offramp** (customer sells crypto for MXN):

```
created → funded → completed → finalized
    ↓        ↓
  failed   failed
    ↓
 canceled
```

1. **`created`** — `burnTransaction` ready for customer to sign
2. **`funded`** — Customer's crypto transaction confirmed on-chain
3. **`completed`** — MXN sent to customer's bank account
4. **`finalized`** — Reversal window has passed, funds cannot be returned

**Swap** (crypto to crypto):

```
created → funded → completed
    ↓        ↓
  failed   failed
```

1. **`created`** — `sendTransaction` ready for customer to sign
2. **`funded`** — Customer's crypto transaction confirmed on-chain
3. **`completed`** — Target crypto sent to customer's wallet

**Other statuses:** `failed` (timeout/error), `refunded` (onramp only — e.g. if the deposited amount doesn't match the order, the funds are returned), `canceled` (before funding).

### Other Webhook Statuses

<Expandable title="Customer, bank account, and KYC statuses">
  **Customer statuses** (`customer_updated`):

  * `customer_pending` — Verification in progress
  * `customer_verified` — Successfully verified
  * `customer_failed` — Verification failed

  **Bank account statuses** (`bank_account_updated`):

  * `bank_account_pending` — Verification pending
  * `bank_account_awaiting_deposit_verification` — Waiting for deposit verification
  * `bank_account_active` — Active and ready to use
  * `bank_account_inactive` — Inactive

  **KYC statuses** (`kyc_updated`):

  * `kyc_proposed` — Data submitted, awaiting admin review
  * `kyc_approved` — Approved (on-chain marking will follow for Solana)
  * `kyc_rejected` — Rejected (includes `updateReason` with details)
</Expandable>

If a transaction expires before submission, use [POST /ramp/order/\{id}/regenerate\_tx](/api-reference/orders/regenerate-transaction) or [POST /ramp/swap/\{id}/regenerate\_tx](/api-reference/swap/regenerate-swap-transaction) to get a new transaction. For Stellar onramp orders with claimable balances, the same regenerate endpoint returns a fresh unsigned claim transaction if the sequence number has gone stale.

<Note>
  **Use webhooks for order tracking.** Webhooks deliver updates as soon as they happen. If you poll the list orders endpoint instead, there may be a brief indexing delay before newly created orders appear.
</Note>

***

## Resources

The API manages these resources, all scoped to your organization:

* **Organizations** (`organizationId`) — Your organization and any child organizations you create. Child orgs can be created programmatically via [POST /ramp/organization](/api-reference/organizations/create-a-child-organization) and renamed via [PUT /ramp/organization/\{org\_id}/name](/api-reference/organizations/rename-an-organization).
* **Customers** (`customerId`) — Your end users who complete KYC. You generate this UUID during onboarding.
* **Bank Accounts** (`bankAccountId`) — Mexican bank accounts linked to a customer. You generate this UUID during onboarding.
* **Wallets** (`publicKey`) — Crypto wallet addresses registered during onboarding. Can also be registered programmatically via [POST /ramp/wallet](/api-reference/crypto-wallets/register-a-crypto-wallet) or scoped to a child org customer via [POST /ramp/customer/\{customer\_id}/wallet](/api-reference/crypto-wallets/register-a-wallet-for-a-child-org-customer).
* **Orders** (`orderId`) — Onramp and offramp transactions. You generate this UUID.
* **Webhooks** — Event notification subscriptions.

***

## Troubleshooting

| Error                     | Cause                                                                       | Fix                                                    |
| ------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------ |
| `Proxy account not found` | `customerId` or `publicKey` doesn't match onboarding                        | Use the exact same IDs from the onboarding call        |
| `Bank account not found`  | `bankAccountId` doesn't match onboarding or belongs to a different customer | Verify the bank account was linked to this customer    |
| `401 Unauthorized`        | Invalid API key or incorrect auth header                                    | Use `Authorization: <api_key>` with no `Bearer` prefix |
| `Quote expired`           | Order created more than 2 minutes after the quote                           | Create a fresh quote                                   |

### Common Pitfalls

* **IDs are permanently bound after onboarding.** The `customerId`, `bankAccountId`, and `publicKey` are linked during onboarding. You cannot mix and match IDs across different customers.
* **Stellar: trust lines are handled automatically for onramps.** Pass `walletAddress` in your quote request to enable automatic wallet setup. If the wallet lacks a trustline or doesn't exist on-chain yet, the quote fee will include a one-time onboarding cost. After the order completes, the order response includes a `stellarClaimTransaction` — an unsigned XDR that the user signs to add the trustline and claim their tokens. See [Stellar: First-Time Wallet Onramp](/guides/testing-onramps#stellar-first-time-wallet-onramp) for the full flow. For offramps and swaps, the wallet must still have trust lines set up beforehand.
