> ## Documentation Index
> Fetch the complete documentation index at: https://whitebit-mintlify-fix-broken-links-1777248521.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Broker Integration Guide

> Complete guide for the WhiteBIT Broker Program — fee share model, customer onboarding, sub-account management, per-customer API keys, and revenue monitoring.

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

The WhiteBIT Broker Program enables trading platforms and fintechs to offer WhiteBIT exchange infrastructure to end users. Brokers earn a share of trading fees generated by referred users. The guide covers program enrollment, customer onboarding, sub-account architecture, API key management, and revenue tracking.

## Broker Program overview

The Broker Program offers a revenue-sharing model where brokers receive up to 40% of trading fees generated by referred users.

**Fee share model:**

The base fee share is **40% of the trading fee** generated by each referred user.

**Worked example:**

```
Referred user trades $10,000 on BTC_USDT (spot)
Standard trading fee: 0.1% taker = $10.00
Broker fee share (40%): $10.00 × 0.40 = $4.00
```

**WBT holding boost tiers:**

WBT is WhiteBIT's native utility token (WhiteBIT Token). Holding WBT increases the fee share percentage:

| WBT Holdings        | Fee Share |
| ------------------- | --------- |
| 200 WBT             | 40%       |
| Up to 2,000,000 WBT | 50%       |

Check the [Broker Program page](https://institutional.whitebit.com/broker-program) for the current WBT tier table with all intermediate breakpoints.

**How to apply:** Contact **[institutional@whitebit.com](mailto:institutional@whitebit.com)** with the business description and expected user volume.

**Program benefits:**

* Sub-account architecture for per-customer isolation
* Per-customer API keys
* Fee-free internal transfers between master and sub-accounts
* Cross-marketing support

## Customer onboarding flow

Each end customer is onboarded as a sub-account under the broker's master account.

<Steps>
  <Step title="Create a sub-account">
    Call the sub-account creation endpoint to create a new sub-account for the customer. Each sub-account receives an independent balance and can have dedicated API keys.

    **Endpoint:** `POST /api/v4/sub-account/create` — [API Reference](/api-reference/sub-accounts/create-sub-account)
  </Step>

  <Step title="Generate a KYC verification URL">
    Generate a KYC URL for the sub-account holder. The end customer completes KYC verification through the WhiteBIT interface (WhiteBIT-branded, not white-label).

    **Endpoint:** `POST /api/v4/sub-account/kyc-url` — [API Reference](/api-reference/sub-accounts/kyc-url)
  </Step>

  <Step title="Customer completes KYC">
    The end customer opens the KYC URL and completes identity verification. The broker monitors KYC status via the sub-account details endpoint.
  </Step>

  <Step title="Enable trading">
    Once KYC is approved, transfer initial funds to the sub-account (fee-free) and create an API key for the sub-account if the customer needs direct API access.
  </Step>
</Steps>

<Note>
  The KYC verification flow is WhiteBIT-branded. The broker cannot white-label the KYC interface.
</Note>

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    # Create a sub-account
    curl -X POST "https://whitebit.com/api/v4/sub-account/create" \
      -H "Content-Type: application/json" \
      -H "X-TXC-APIKEY: YOUR_API_KEY" \
      -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \
      -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \
      -d '{
        "alias": "customer-001",
        "request": "/api/v4/sub-account/create",
        "nonce": "YOUR_NONCE"
      }'

    # Generate a KYC URL for the sub-account
    curl -X POST "https://whitebit.com/api/v4/sub-account/kyc-url" \
      -H "Content-Type: application/json" \
      -H "X-TXC-APIKEY: YOUR_API_KEY" \
      -H "X-TXC-PAYLOAD: YOUR_PAYLOAD" \
      -H "X-TXC-SIGNATURE: YOUR_SIGNATURE" \
      -d '{
        "id": "SUB_ACCOUNT_ID",
        "request": "/api/v4/sub-account/kyc-url",
        "nonce": "YOUR_NONCE"
      }'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import hashlib
    import hmac
    import json
    import time
    import base64
    import requests

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

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

    # Create a sub-account
    response = send_request("/api/v4/sub-account/create", {
        "alias": "customer-001",
    })
    sub_account = response.json()
    print(sub_account)

    # Generate a KYC URL
    response = send_request("/api/v4/sub-account/kyc-url", {
        "id": sub_account.get("id"),
    })
    print(response.json())
    ```
  </Tab>
</Tabs>

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

## Sub-account management

Sub-accounts provide complete isolation — each customer has independent balances, order history, and API credentials.

**CRUD operations:**

| Operation | Endpoint                           | Description                      |
| --------- | ---------------------------------- | -------------------------------- |
| Create    | `POST /api/v4/sub-account/create`  | Create a new sub-account         |
| List      | `POST /api/v4/sub-account/list`    | List all sub-accounts            |
| Block     | `POST /api/v4/sub-account/block`   | Suspend trading for a customer   |
| Unblock   | `POST /api/v4/sub-account/unblock` | Re-enable trading for a customer |

**Fee-free transfers:**

Transfer funds between the master account and any sub-account without fees using `POST /api/v4/sub-account/transfer` — see the [API Reference](/api-reference/sub-accounts/sub-account-transfer).

* Master to sub-account: funding a customer account
* Sub-account to master: revenue collection

**Balance monitoring:**

Query balances per sub-account and monitor across all sub-accounts for aggregate reporting.

See the [Sub-Accounts Overview](/products/sub-accounts/overview) for the complete product overview.

## Per-customer API keys

Each sub-account can have dedicated API keys with independent IP whitelists and permissions.

* Create API keys per sub-account for customers who need direct API access
* **IP whitelisting:** up to **50 IP addresses** per API key
* **Permissions:** configure per-key permissions (`Info + Trading` vs. `Info + Trading + Deposit + Withdraw`)

<Warning>
  Create separate API keys for each customer sub-account. Do not share the master account's API keys with customers.
</Warning>

See [Security Best Practices](/best-practices/security) for API key management guidance.

For structured order tracking across customer sub-accounts, use `clientOrderId` naming
conventions — see [Client Order ID: Broker Implementation](/guides/client-order-id#example-broker-implementation).

## Revenue monitoring

Track fee share revenue across all referred users to monitor Broker Program earnings.

**Fee share tracking:** Monitor trading activity across sub-accounts to estimate fee share earnings. The worked fee share calculation from the Overview section applies to each trade executed by a referred user.

**Reporting recommendations:**

* Track trading volume per sub-account over 30-day rolling windows
* Monitor fee tier progression — higher volume improves the base fee rate, which increases the absolute fee share
* Export trade history per sub-account for reconciliation

## Fiat for broker end users

European broker end users frequently expect EUR deposit and withdrawal capabilities.

Fiat operations (EUR/SEPA) require institutional onboarding with fiat access approval. The broker's master account must complete the two-phase onboarding process (crypto access via KYB, then fiat access via fiat processing partner review). Once fiat access is approved on the master account, sub-accounts can process fiat deposits and withdrawals.

See [Institutional Onboarding](/institutional/onboarding) for the two-phase process. See [Payment Integration](/guides/payment-integration) for fiat endpoint details.

<Note>
  Fiat deposit and withdrawal access requires completion of institutional onboarding including the fiat provider approval phase. Contact [institutional@whitebit.com](mailto:institutional@whitebit.com) to begin the process.
</Note>

## Integration checklist

Complete the following checklist before going live with the Broker Program integration.

* [ ] **Program enrollment** — Application submitted to [institutional@whitebit.com](mailto:institutional@whitebit.com) and approved.
* [ ] **Master account KYB** — KYB verification completed for the broker entity.
* [ ] **API key generated** — Master account API key created with appropriate permissions.
* [ ] **Sub-account creation** — Successfully created at least one test sub-account.
* [ ] **KYC URL generation** — KYC URL generated and tested for a sub-account.
* [ ] **Fund transfer** — Fee-free transfer between master and sub-account verified.
* [ ] **Per-customer API key** — API key created for a sub-account with IP whitelist configured.
* [ ] **Balance monitoring** — Sub-account balance query working.
* [ ] **Fee share tracking** — Revenue monitoring process established.
* [ ] **Fiat access** (if applicable) — Institutional onboarding Phase 2 completed for SEPA access.
* [ ] **Security review** — IP whitelists, API key permissions, and secret storage reviewed per [Security Best Practices](/best-practices/security).
* [ ] **Go-live review** — All items on the [Go-Live Checklist](/best-practices/go-live-checklist) verified.

## What's Next

<CardGroup cols={3}>
  <Card title="Sub-Accounts" icon="users" href="/products/sub-accounts/overview">
    Full product overview for the sub-account system.
  </Card>

  <Card title="Institutional Onboarding" icon="building" href="/institutional/onboarding">
    Step-by-step KYB and fiat onboarding process.
  </Card>

  <Card title="Go-Live Checklist" icon="clipboard-check" href="/best-practices/go-live-checklist">
    Pre-production readiness verification.
  </Card>
</CardGroup>
