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

# WhiteBIT Codes

> Create and apply fee-free digital vouchers to transfer crypto between WhiteBIT accounts.

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 />

WhiteBIT Codes are fee-free digital vouchers for transferring cryptocurrency between WhiteBIT accounts. A code encapsulates a specific amount of a currency — the creator generates the code, shares the code string, and the recipient applies the code to receive the funds.

## Use cases

Codes provide a simple transfer mechanism without requiring the recipient's deposit address.

* **Internal transfers** — Move funds between accounts without withdrawal fees
* **Partner payouts** — Distribute funds to multiple recipients by generating codes programmatically
* **Promotions and rewards** — Create codes as promotional vouchers; optionally protect with a passphrase

## Code lifecycle

The code lifecycle has two phases: creation and application.

<Steps>
  <Step title="Create a code">
    Send a `POST` request to [`/api/v4/main-account/codes`](/api-reference/account-wallet/create-code) with `ticker` (e.g., `ETH`), `amount` (string, max 8 decimals), optional `passphrase` (max 25 characters, latin letters + numbers + symbols, no whitespace), and optional `description` (max 75 characters, visible only to the creator). The amount is debited from the [Main balance](/concepts/balances). The response returns a `code` string (format: `WB{uuid}{TICKER}`, e.g., `WBe11f4fce-2a53-4edc-b195-66b693bd77e3ETH`) and an `external_id`.
  </Step>

  <Step title="Share the code">
    Transmit the code string to the intended recipient. If a passphrase was set, share the passphrase separately.
  </Step>

  <Step title="Apply the code">
    The recipient calls [`POST /api/v4/main-account/codes/apply`](/api-reference/account-wallet/apply-code) with the `code` string and `passphrase` (if set). Funds are credited to the recipient's [Main balance](/concepts/balances). A `code.apply` [webhook event](/platform/webhook) fires on the creator's account.
  </Step>
</Steps>

## API endpoints

WhiteBIT Codes uses 4 authenticated endpoints. All operate on the [Main balance](/concepts/balances).

| Endpoint                                                                                     | Purpose                               | Rate limit         |
| -------------------------------------------------------------------------------------------- | ------------------------------------- | ------------------ |
| [`POST /api/v4/main-account/codes`](/api-reference/account-wallet/create-code)               | Create a new code                     | 1,000 req / 10 sec |
| [`POST /api/v4/main-account/codes/apply`](/api-reference/account-wallet/apply-code)          | Apply (redeem) a code                 | 60 req / 1 sec     |
| [`POST /api/v4/main-account/codes/my`](/api-reference/account-wallet/get-my-codes)           | List codes created by the account     | 1,000 req / 10 sec |
| [`POST /api/v4/main-account/codes/history`](/api-reference/account-wallet/get-codes-history) | Full code history (created + applied) | 1,000 req / 10 sec |

## Create parameters

| Parameter     | Type   | Required | Description                                                                                                          |
| ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `ticker`      | string | Yes      | Currency ticker (e.g., `ETH`, `BTC`)                                                                                 |
| `amount`      | string | Yes      | Amount to encapsulate. Max precision: 8 decimals. Must be greater than 0 and less than or equal to the Main balance. |
| `passphrase`  | string | No       | Optional protection. Latin letters, numbers, symbols only. Max 25 characters. No whitespace.                         |
| `description` | string | No       | Internal note visible only to the creator. Max 75 characters.                                                        |

## Code example

Create a code for 0.002 ETH with a passphrase, then apply the code on a different account.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Step 1: Create a WhiteBIT code
    curl -X POST https://whitebit.com/api/v4/main-account/codes \
      -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 '{
        "ticker": "ETH",
        "amount": "0.002",
        "passphrase": "mySecretPass1",
        "request": "/api/v4/main-account/codes",
        "nonce": 1
      }'
    ```

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "code": "WBe11f4fce-2a53-4edc-b195-66b693bd77e3ETH",
      "message": "Code was successfully created",
      "external_id": "be08a482-5faf-11ed-9b6a-0242ac120002"
    }
    ```

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Step 2: Apply the code on the recipient's account
    curl -X POST https://whitebit.com/api/v4/main-account/codes/apply \
      -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 '{
        "code": "WBe11f4fce-2a53-4edc-b195-66b693bd77e3ETH",
        "passphrase": "mySecretPass1",
        "request": "/api/v4/main-account/codes/apply",
        "nonce": 2
      }'
    ```

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "message": "Code was successfully applied",
      "ticker": "ETH",
      "amount": "0.002",
      "external_id": "be08a482-5faf-11ed-9b6a-0242ac120002"
    }
    ```
  </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: Create a WhiteBIT code
    create = send_request("/api/v4/main-account/codes", {
        "ticker": "ETH",
        "amount": "0.002",
        "passphrase": "mySecretPass1",
    })
    create_data = create.json()
    print("Code:", create_data["code"])
    print("External ID:", create_data["external_id"])

    # Step 2: Apply the code on the recipient's account
    apply = send_request("/api/v4/main-account/codes/apply", {
        "code": create_data["code"],
        "passphrase": "mySecretPass1",
    })
    apply_data = apply.json()
    print("Applied:", apply_data["amount"], apply_data["ticker"])
    ```
  </Tab>
</Tabs>

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

## Error codes

Create endpoint error codes:

| Code | Description                                     |
| ---- | ----------------------------------------------- |
| 0    | Fiat currencies available on the front-end only |
| 1    | Currency is not withdrawable                    |
| 3    | Amount is too small                             |
| 5    | Not enough balance                              |
| 6    | Amount is less than or equal to fee             |

<Note>
  For apply errors, the most common is "Incorrect code or passphrase" — verify the code string and passphrase are correct.
</Note>

## Regional restrictions

<Warning>
  EEA users: USDT codes are blocked since December 30, 2024 (MiCA compliance). Tether has not obtained EU authorization. Use USDC or EURI as alternatives. See [Regulatory Compliance](/institutional/compliance) for details.
</Warning>

## What's next

<CardGroup cols={2}>
  <Card title="Webhook Events" icon="bell" href="/platform/webhook">
    Receive real-time notifications when codes are applied.
  </Card>

  <Card title="Convert" icon="arrows-rotate" href="/platform/convert">
    Instantly convert between currencies at a quoted rate.
  </Card>
</CardGroup>
