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

# On/Off-Ramp

> Move corporate funds between fiat and crypto on WhiteBIT: what the on/off-ramp integration provides, who it serves, the two-phase access model, the enablement gates, and how to get onboarded.

export const RegionBaseUrl = ({className = "", showBaseUrl = true, protocol = "https"}) => {
  const {useState, useEffect, useRef} = React;
  const EU_ENABLED = false;
  const [region, setRegionState] = useState(() => {
    if (!EU_ENABLED) return "com";
    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(() => {
    if (!EU_ENABLED) return;
    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 = protocol === "wss" ? region === "eu" ? "wss://api.whitebit.eu/ws" : "wss://api.whitebit.com/ws" : region === "eu" ? "https://whitebit.eu" : "https://whitebit.com";
  const baseUrlLabel = protocol === "wss" ? "WebSocket URL" : "Base URL";
  if (!EU_ENABLED) {
    if (!showBaseUrl) 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">
                    {baseUrlLabel}
                </span>
                <span className="text-sm text-gray-400">:</span>
                {protocol === "wss" ? <code className="text-sm font-mono text-primary dark:text-primary-light">
                        {apiBaseUrl}
                    </code> : <a href={apiBaseUrl} target="_blank" rel="noopener noreferrer" className="text-sm font-mono text-primary dark:text-primary-light hover:underline">
                        {apiBaseUrl}
                    </a>}
            </div>;
  }
  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">
                {baseUrlLabel}
            </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>
                    {protocol === "wss" ? <code className="text-sm font-mono text-primary dark:text-primary-light">
                            {apiBaseUrl}
                        </code> : <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 on/off-ramp integration moves corporate funds between fiat and digital assets, in both directions — fiat in to crypto out, and crypto back to EUR — with all fiat operations at the partner's main account. For the flows, code, and reconciliation, see the [Integration guide](/guides/on-off-ramp-integration).

<Tip>
  The [On/Off-Ramp FAQ](/guides/on-off-ramp-faq) answers the common questions on activation, SEPA matching, fee semantics, reconciliation, and compliance.
</Tip>

Adjacent scenarios route to separate guides:

* The integration collects payments from end users or processes merchant flows — see [Payment Integration](/guides/payment-integration).
* End customers hold dedicated accounts under a partner master account — see the [Embedded Trading integration guide](/guides/sub-account-integration).
* For the full partner-type map, see [Partner Solutions](/guides/partner-solutions).

## What On/Off-Ramp provides

* **Fiat deposits via API** — a hosted payment URL for SEPA bank transfer or card checkout, per the providers enabled for the account.
* **Fiat withdrawals via API** — EUR payouts over IBAN (SEPA), plus card rails where enabled, each carrying a beneficiary record.
* **Quoted-rate conversion** — a locked quote executed before the balance moves, so the rate is known up front.
* **The crypto leg** — deposit addresses, withdrawals, and the refund flow.
* **Reconciliation** — signed webhooks plus history polling with client-side identifiers.

The [Integration guide](/guides/on-off-ramp-integration) documents each endpoint, the request bodies, and both directions.

## Who On/Off-Ramp is for

* **Corporate crypto investors** — convert company treasury funds between EUR and digital assets on the main account.
* **Businesses settling revenue over EUR rails** — move payouts or revenue between fiat and crypto without operating end-user accounts.
* **Crypto-native companies with fiat obligations** — off-ramp digital assets to EUR to pay suppliers, payroll, or tax from the company bank account.
* **Fiat-first companies funding on-chain operations** — on-ramp EUR to USDC or other digital assets for on-chain payouts, vendor settlement, or protocol operations on the main account.

## How it works

Every flow authenticates with an [HMAC-signed API key](/api-reference/authentication) on the partner's main account. Crypto operations are available after standard account setup; fiat operations require completed [Institutional Onboarding](/institutional/onboarding) with approved fiat access — a separate, non-automatic phase after KYB. The [Integration guide](/guides/on-off-ramp-integration) covers both directions end to end: the fiat leg, the conversion step, and the crypto leg.

## Program terms

Fee and limit figures are set per individual agreement, so no numbers appear in these pages. During onboarding, the account manager confirms:

* The fee schedule for fiat deposits and withdrawals applicable to the account.
* Deposit and withdrawal limits, for both fiat and crypto.
* The enabled currency and provider matrix. At runtime, [Asset Status](/api-reference/market-data/asset-status-list) reports the per-currency `can_deposit` / `can_withdraw` flags and the request `provider` values; the [Fee](/api-reference/market-data/fee) endpoint reports the fees and limits per fiat asset.
* Settlement windows and cutoff behavior for the fiat rails in use, including weekends and holidays.
* The conversion pairs available to the account.

## Compliance essentials

Compliance shapes which assets and flows are available to the account. The [Integration guide](/guides/on-off-ramp-integration) shows how each constraint affects requests; [Regulatory Compliance](/institutional/compliance) holds the full reference.

* **MiCA (EEA):** EEA accounts cannot deposit, withdraw, or create WhiteBIT Codes in USDT since December 30, 2024. Use USDC or EURI for the crypto leg. See [Regulatory Compliance](/institutional/compliance).
* **Travel Rule (EEA and Turkey):** inbound crypto deposits are held until Travel Rule verification completes; crypto withdrawals carry a Travel Rule payload. See [Travel Rule](/concepts/travel-rule).
* **Fiat KYC:** fiat withdrawals require KYC verification. In exceptional, documented cases the institutional team can arrange a per-account override.

## How to get started

Fiat access is the second phase of [Institutional Onboarding](/institutional/onboarding) and is not automatic after KYB approval. Phase 1 (corporate account, KYB, API keys) enables crypto operations; Phase 2 adds EUR/SEPA capabilities after review by a fiat processing partner, with source-of-funds documentation. WhiteBIT manages the fiat-partner onboarding on the applicant's behalf.

**How to apply:** email **[institutional@whitebit.com](mailto:institutional@whitebit.com)** with a description of the service. Include the registered legal entity (name, registration number, jurisdiction), licenses or registrations held, whether the scope is crypto-only or fiat as well, and the countries where the service operates. The full application question list is on the [Partner Solutions](/guides/partner-solutions#how-to-apply) page.

<Note>
  Fiat deposits and withdrawals operate at the partner's **main account** (institutional fiat access). Per-end-user fiat rails are not a standard shipped capability; confirm any such requirement with WhiteBIT before designing around it.
</Note>

Five capabilities in the ramp integration carry a dedicated enablement gate:

| Capability                                          | Gate                                          | Contact                                                                            |
| --------------------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------- |
| Fiat operations (Phase 2)                           | Institutional onboarding, fiat-partner review | [institutional@whitebit.com](mailto:institutional@whitebit.com)                    |
| `fiat-deposit-url` endpoint                         | Per-account activation                        | WhiteBIT support, with the API key                                                 |
| `successLink` / `failureLink` redirects             | Feature activation, domain validated          | WhiteBIT support                                                                   |
| Dedicated deposit addresses (`/create-new-address`) | Per-account permission                        | [support@whitebit.com](mailto:support@whitebit.com)                                |
| Travel Rule API                                     | Per-account enablement                        | Account manager or [institutional@whitebit.com](mailto:institutional@whitebit.com) |

## Support and contacts

* **Onboarding status, limits, and institutional matters:** [institutional@whitebit.com](mailto:institutional@whitebit.com), or the assigned account manager once onboarded.
* **Fiat endpoint enablement and access questions:** WhiteBIT support, with the API key included in the request.
* **Dedicated deposit addresses:** [support@whitebit.com](mailto:support@whitebit.com).
* **OTC block trading** for large conversions is part of the institutional catalog — see the [Institutional Overview](/institutional/overview).
* **Self-service:** [help.whitebit.com](https://help.whitebit.com) for platform questions; this portal for API documentation.

## What's next

<CardGroup cols={3}>
  <Card title="Integration" icon="code" href="/guides/on-off-ramp-integration">
    The on-ramp and off-ramp flows, code, reconciliation, and failure paths.
  </Card>

  <Card title="On/Off-Ramp FAQ" icon="circle-question" href="/guides/on-off-ramp-faq">
    Activation, SEPA matching, fee semantics, reconciliation, and compliance questions.
  </Card>

  <Card title="Institutional Onboarding" icon="building" href="/institutional/onboarding">
    The two-phase KYB and fiat access process with the document checklist.
  </Card>
</CardGroup>
