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

# OAuth 2.0 on WhiteBIT

> OAuth 2.0 integration with WhiteBIT enables secure, token-based authorization for third-party applications.

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

## Key Benefits

* **Enhanced Security**: Users grant access without sharing WhiteBIT credentials with third-party applications
* **Granular Permissions**: Fine-grained scope controls allow users to limit what third-party applications can access
* **Streamlined Trading Experience**: Enables seamless integration with portfolio trackers, trading bots, and analysis tools
* **Developer-Friendly**: Standardized implementation familiar to developers across the ecosystem

## How WhiteBIT OAuth Works

<Steps>
  <Step title="Authorization">
    Users approve access for a third-party application through WhiteBIT’s authorization page
  </Step>

  <Step title="Token Exchange">
    The application exchanges the authorization code for an access token
  </Step>

  <Step title="API Access">
    The application uses the access token to make API calls to WhiteBIT on the user’s behalf
  </Step>

  <Step title="Token Refresh">
    When the access token expires, the application can use a refresh token to obtain a new one
  </Step>
</Steps>

## Use Cases

#### Partner API key issuance

Partner platforms issue WhiteBIT API keys on behalf of end users through the OAuth API key flow. The flow replaces manual key creation with a consent-driven bootstrap: the user authorizes the partner once, and the WhiteBIT platform issues a partner-scoped API key with a secret that the partner retrieves through a dedicated endpoint. See the [Fast API Key integration guide](/guides/fast-api-key-via-oauth).

#### Trading Bots & Algorithmic Trading

Enable automated trading strategies without storing WhiteBIT credentials in third-party systems. Trading bots can place, modify, and cancel orders while only having the specific permissions they need.

### Portfolio Trackers & Analytics

Allow portfolio management applications to read balance and trade history information without write access to trading functions, providing users with consolidated views of their assets across multiple platforms.

### Mobile Applications

Provide a seamless authentication experience in mobile apps without requiring users to enter and store their WhiteBIT credentials in the app.

### Enterprise Integrations

Enable business systems to securely connect to WhiteBIT for institutional trading, reporting, and compliance purposes with proper audit controls.

## Available Scopes

WhiteBIT OAuth 2.0 implementation supports a wide range of permission scopes available for request during client setup, including:

* Account information access
* Balance and transaction history
* Order management (read, create, delete)
* Market data access
* Trading history
* OAuth API key management (`apikeys.create`, `apikeys.read`, `apikeys.delete`)
* And more specialized permissions

For a complete list of available scopes and detailed implementation instructions, please visit the [Usage](/platform/oauth/usage/overview#scopes) page.

## Getting Started

**WhiteBIT OAuth 2.0 integration is exclusively offered to close ecosystem partners.** To integrate WhiteBIT OAuth 2.0 with an application, contact support at [support@whitebit.com](mailto:support@whitebit.com). The support team guides through the OAuth integration process, including:

1. Application registration and approval
2. Scope request and configuration
3. Implementation support for the OAuth 2.0 authorization flow
4. Technical documentation for token exchange and API authentication

Once the integration request is approved, detailed instructions are provided for implementing the OAuth 2.0 flow.

## Next Steps: Implementation Details

The [Usage](/platform/oauth/usage/overview) page provides comprehensive documentation on:

* Endpoint specifications for authorization and token exchange
* Request and response formats with example code
* Complete list of available scopes and their permissions
* Step-by-step implementation guides for common scenarios
* Troubleshooting tips and best practices

The usage documentation guides through the entire implementation process from initial setup to making the first authenticated API calls. For partner integrations that need to issue API keys on behalf of users, the [Fast API Key integration guide](/guides/fast-api-key-via-oauth) covers the end-to-end consent and key-management flow. The [OAuth endpoint overview](/api-reference/oauth/usage/overview) lists every OAuth endpoint in the API Reference.

## Support

For questions or assistance with OAuth 2.0 integration, contact support at [support@whitebit.com](mailto:support@whitebit.com).
