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

# Convert

> Instantly convert between currencies at a quoted rate without placing orders on the orderbook.

export const RegionBaseUrl = ({className = "", showBaseUrl = true}) => {
  const [region, setRegionState] = useState(() => {
    if (typeof window !== 'undefined') {
      return localStorage.getItem("api-region-preference") || "com";
    }
    return "com";
  });
  const [mounted, setMounted] = useState(false);
  const observerRef = useRef(null);
  const isSyncingRef = useRef(false);
  const updateAllContentOnPage = targetRegion => {
    try {
      const domainFrom = targetRegion === "eu" ? "whitebit.com" : "whitebit.eu";
      const domainTo = targetRegion === "eu" ? "whitebit.eu" : "whitebit.com";
      const links = document.querySelectorAll('a');
      links.forEach(link => {
        let href = link.getAttribute('href');
        if (href && href.includes(domainFrom)) {
          link.setAttribute('href', href.replace(domainFrom, domainTo));
        }
      });
      const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {
        acceptNode: node => {
          if (node.parentElement?.closest('.region-toggle-component')) {
            return NodeFilter.FILTER_REJECT;
          }
          return node.textContent.includes(domainFrom) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
        }
      });
      let currentNode;
      while (currentNode = walker.nextNode()) {
        currentNode.textContent = currentNode.textContent.replace(new RegExp(domainFrom, 'g'), domainTo);
      }
      console.log(`[RegionSync] Global content updated to ${domainTo}`);
    } catch (e) {
      console.error("[RegionSync] Error updating content:", e);
    }
  };
  const updateRegion = (newRegion, source) => {
    if (region === newRegion) return;
    console.log(`[RegionBaseUrl] Updating to "${newRegion}" (Source: ${source})`);
    if (source === 'observer') {
      isSyncingRef.current = true;
      setTimeout(() => isSyncingRef.current = false, 1000);
    }
    setRegionState(newRegion);
    localStorage.setItem("api-region-preference", newRegion);
    updateAllContentOnPage(newRegion);
    if (source === 'user-click') {
      window.dispatchEvent(new CustomEvent("regionChange", {
        detail: newRegion
      }));
      attemptToUpdateNativeDropdown(newRegion, 0);
      setTimeout(() => attemptToUpdateNativeDropdown(newRegion, 1), 500);
      setTimeout(() => attemptToUpdateNativeDropdown(newRegion, 2), 1500);
    }
  };
  const attemptToUpdateNativeDropdown = (targetRegion, attempt) => {
    if (isSyncingRef.current) return;
    try {
      const targetUrl = targetRegion === "eu" ? "https://whitebit.eu" : "https://whitebit.com";
      const targetDesc = targetRegion === "eu" ? "EU Server" : "Production Server";
      const selects = document.querySelectorAll('select');
      for (const select of selects) {
        if (select.innerHTML.includes('whitebit.com') || select.innerHTML.includes('whitebit.eu')) {
          select.value = targetUrl;
          select.dispatchEvent(new Event('change', {
            bubbles: true
          }));
          return;
        }
      }
      const buttons = Array.from(document.querySelectorAll('button, [role="combobox"]'));
      const serverSelector = buttons.find(btn => {
        if (btn.closest('a') || btn.closest('[class*="card"]') || btn.closest('nav')) {
          return false;
        }
        const txt = btn.textContent || "";
        const isServerDropdown = (txt.includes('Production Server') || txt.includes('EU Server') || txt.includes('WhiteBIT Global Server') || txt.includes('WhiteBIT EU Server')) && !txt.includes('Run') && !txt.includes('Send') || btn.getAttribute('role') === 'combobox';
        return isServerDropdown;
      });
      if (serverSelector) {
        const currentText = serverSelector.textContent || "";
        if (currentText.includes(targetDesc)) return;
        serverSelector.click();
        setTimeout(() => {
          const options = document.querySelectorAll('[role="option"], li, button');
          for (const opt of options) {
            const optText = opt.textContent || "";
            if (optText.includes(targetDesc) || optText.includes(targetUrl)) {
              opt.click();
              return;
            }
          }
        }, 100);
      }
    } catch (e) {
      console.error("[Sync] Error:", e);
    }
  };
  useEffect(() => {
    setMounted(true);
    updateAllContentOnPage(region);
    const handleStorageChange = e => {
      if (e.key === "api-region-preference" && e.newValue) {
        updateRegion(e.newValue, 'storage');
      }
    };
    const handleRegionChange = e => {
      if (e.detail !== region) {
        updateRegion(e.detail, 'event');
      }
    };
    window.addEventListener("storage", handleStorageChange);
    window.addEventListener("regionChange", handleRegionChange);
    observerRef.current = new MutationObserver(mutations => {
      if (isSyncingRef.current) return;
      updateAllContentOnPage(region);
      for (const mutation of mutations) {
        if (mutation.type !== 'childList' && mutation.type !== 'characterData') continue;
        const target = mutation.target;
        const el = target.nodeType === Node.TEXT_NODE ? target.parentElement : target;
        if (el && (el.getAttribute('role') === 'option' || el.closest('[role="listbox"]'))) continue;
        const text = target.textContent || "";
        if (text.includes('WhiteBIT EU Server') || text.includes('https://whitebit.eu') && text.includes('Server')) {
          if (el && el.tagName !== 'A' && !el.closest('.region-toggle-component')) {
            if (region !== 'eu') updateRegion('eu', 'observer');
          }
        } else if (text.includes('WhiteBIT Global Server') || text.includes('https://whitebit.com') && text.includes('Server')) {
          if (el && el.tagName !== 'A' && !el.closest('.region-toggle-component')) {
            if (region !== 'com') updateRegion('com', 'observer');
          }
        }
      }
    });
    observerRef.current.observe(document.body, {
      childList: true,
      subtree: true,
      characterData: true
    });
    if (typeof window !== 'undefined') {
      const current = localStorage.getItem("api-region-preference");
      if (current) attemptToUpdateNativeDropdown(current, 'init');
    }
    return () => {
      window.removeEventListener("storage", handleStorageChange);
      window.removeEventListener("regionChange", handleRegionChange);
      if (observerRef.current) observerRef.current.disconnect();
    };
  }, [region]);
  const apiBaseUrl = region === "eu" ? "https://whitebit.eu" : "https://whitebit.com";
  if (!mounted) return null;
  return <div className={`flex items-center gap-2 flex-wrap my-4 region-toggle-component ${className}`}>
            <span className="text-sm text-gray-500 dark:text-gray-400 font-mono">
                Base URL
            </span>
            <span className="text-sm text-gray-400">(</span>
            <div className="inline-flex bg-gray-100 dark:bg-gray-800 rounded-lg p-0.5 border border-gray-200 dark:border-gray-700">
                <button onClick={() => updateRegion("com", "user-click")} className={`px-2 py-0.5 text-xs font-medium rounded-md transition-all ${region === "com" ? "bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm" : "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200"}`}>
                    .com
                </button>
                <button onClick={() => updateRegion("eu", "user-click")} className={`px-2 py-0.5 text-xs font-medium rounded-md transition-all ${region === "eu" ? "bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 shadow-sm" : "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200"}`}>
                    .eu
                </button>
            </div>
            <span className="text-sm text-gray-400">)</span>
            {showBaseUrl && <>
                    <span className="text-sm text-gray-400">:</span>
                    <a href={apiBaseUrl} target="_blank" rel="noopener noreferrer" className="text-sm font-mono text-primary dark:text-primary-light hover:underline">
                        {apiBaseUrl}
                    </a>
                </>}
        </div>;
};

<RegionBaseUrl />

Convert provides instant currency conversion at a quoted rate. Unlike [spot trading](/products/spot/overview), Convert requires no orderbook interaction — request a quote, confirm within 10 seconds, and the conversion executes immediately.

## When to use Convert

| Feature     | Convert                             | Spot Trading                                                      |
| ----------- | ----------------------------------- | ----------------------------------------------------------------- |
| Execution   | Instant at quoted rate              | Depends on orderbook liquidity                                    |
| Orderbook   | No orderbook interaction            | Orders placed on the orderbook                                    |
| Order types | Single quote-and-confirm flow       | 6 order types (limit, market, stop-limit, stop-market, OCO, bulk) |
| Best for    | Quick conversions, price estimation | Advanced trading strategies, precise price control                |

<Note>
  Convert also serves as a price estimation tool. Call the estimate endpoint before placing a market order to preview the approximate execution price.
</Note>

## Conversion flow

The conversion flow has two steps: estimate and confirm.

<Steps>
  <Step title="Request a quote">
    Send a `POST` request to [`/api/v4/convert/estimate`](/api-reference/convert/convert-estimate) with the following parameters: `from` (source ticker), `to` (destination ticker), `direction` (`"from"` or `"to"`), and `amount`. The response includes `id` (quote identifier), `give`, `receive`, `rate`, and `expireAt`.
  </Step>

  <Step title="Confirm the quote">
    Send a `POST` request to [`/api/v4/convert/confirm`](/api-reference/convert/convert-confirm) with `quoteId` set to the `id` returned by the estimate. The response returns `finalGive` and `finalReceive`.
  </Step>
</Steps>

<Note>
  Conversion quotes expire after 10 seconds. If the quote expires before confirmation, request a new estimate.
</Note>

## API endpoints

Convert uses 3 authenticated endpoints. All require HMAC-SHA512 signing.

| Endpoint                                                                   | Purpose                                    | Rate limit          |
| -------------------------------------------------------------------------- | ------------------------------------------ | ------------------- |
| [`POST /api/v4/convert/estimate`](/api-reference/convert/convert-estimate) | Request a conversion quote                 | 10,000 req / 10 sec |
| [`POST /api/v4/convert/confirm`](/api-reference/convert/convert-confirm)   | Confirm and execute a quote                | 10,000 req / 10 sec |
| [`POST /api/v4/convert/history`](/api-reference/convert/convert-history)   | Retrieve conversion history (max 6 months) | 10,000 req / 10 sec |

## Estimate parameters

| Parameter   | Type   | Required | Description                                                                         |
| ----------- | ------ | -------- | ----------------------------------------------------------------------------------- |
| `from`      | string | Yes      | Source currency ticker (e.g., `BTC`)                                                |
| `to`        | string | Yes      | Destination currency ticker (e.g., `USDT`)                                          |
| `direction` | string | Yes      | `"from"` = amount is in source currency; `"to"` = amount is in destination currency |
| `amount`    | string | Yes      | Amount to convert or receive                                                        |

## Code example

Estimate a BTC-to-USDT conversion and confirm the quote.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Step 1: Request a conversion estimate
    curl -X POST https://whitebit.com/api/v4/convert/estimate \
      -H "X-TXC-APIKEY: YOUR_API_KEY" \
      -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \
      -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \
      -H "Content-Type: application/json" \
      -d '{
        "from": "BTC",
        "to": "USDT",
        "direction": "from",
        "amount": "1",
        "request": "/api/v4/convert/estimate",
        "nonce": 1
      }'
    ```

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "id": "123",
      "from": "BTC",
      "to": "USDT",
      "give": "1",
      "receive": "34299.76831549",
      "rate": "34299.76831549",
      "expireAt": 1699016476
    }
    ```

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Step 2: Confirm the quote using the id from the estimate response
    curl -X POST https://whitebit.com/api/v4/convert/confirm \
      -H "X-TXC-APIKEY: YOUR_API_KEY" \
      -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \
      -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \
      -H "Content-Type: application/json" \
      -d '{
        "quoteId": "123",
        "request": "/api/v4/convert/confirm",
        "nonce": 2
      }'
    ```

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "finalGive": "1",
      "finalReceive": "34299.76831549"
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
    import time
    import json
    import hmac
    import hashlib
    import base64
    import requests

    API_KEY = "YOUR_API_KEY"
    SECRET = "YOUR_SECRET"
    BASE_URL = "https://whitebit.com"

    def send_request(path, data):
        data["request"] = path
        data["nonce"] = int(time.time() * 1000)
        payload = base64.b64encode(json.dumps(data).encode())
        signature = hmac.new(
            SECRET.encode(), payload, hashlib.sha512
        ).hexdigest()
        headers = {
            "X-TXC-APIKEY": API_KEY,
            "X-TXC-PAYLOAD": payload.decode(),
            "X-TXC-SIGNATURE": signature,
            "Content-Type": "application/json",
        }
        return requests.post(BASE_URL + path, headers=headers, json=data)

    # Step 1: Request a conversion estimate
    estimate = send_request("/api/v4/convert/estimate", {
        "from": "BTC",
        "to": "USDT",
        "direction": "from",
        "amount": "1",
    })
    estimate_data = estimate.json()
    print("Quote ID:", estimate_data["id"])
    print("Rate:", estimate_data["rate"])

    # Step 2: Confirm the quote
    confirm = send_request("/api/v4/convert/confirm", {
        "quoteId": estimate_data["id"],
    })
    confirm_data = confirm.json()
    print("Final give:", confirm_data["finalGive"])
    print("Final receive:", confirm_data["finalReceive"])
    ```
  </Tab>
</Tabs>

For Go and PHP examples, see [SDKs](/sdks).

## History filters

The [history endpoint](/api-reference/convert/convert-history) supports filtering by `fromTicker`, `toTicker`, `quoteId`, and time range (`from`/`to` timestamps). The default limit is 100 records. The maximum history depth is 6 months from the current month.

## Convert in payment flows

Convert is commonly used as part of the withdrawal flow when the currency held in Main balance differs from the currency an end user needs to withdraw. The pattern is: transfer Main → Trade, convert, transfer Trade → Main, then withdraw.

For the full step-by-step withdrawal-with-conversion flow including code examples, see [Payment Integration](/guides/payment-integration).

## What's next

<CardGroup cols={2}>
  <Card title="Payment Integration" icon="money-bill" href="/guides/payment-integration">
    Deposit and withdrawal flows including conversion.
  </Card>

  <Card title="Spot Trading" icon="chart-line" href="/products/spot/overview">
    Place orders on the orderbook with 6 order types.
  </Card>

  <Card title="WhiteBIT Codes" icon="ticket" href="/platform/whitebit-codes">
    Transfer funds between accounts using fee-free digital vouchers.
  </Card>
</CardGroup>
