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

# Cancel bulk orders

> The endpoint cancels up to 100 [orders](/glossary#orders) in a single request. Each item identifies a target order by `market` plus exactly one of `orderId` or `clientOrderId`. The response is an array whose items match the input order one-to-one — `response[i]` corresponds to `request.orders[i]`.

<Warning>
Rate limit: 10000 requests/10 sec.
</Warning>

<Warning>
Limit: From 1 to 100 orders per request.
</Warning>

<Note>
- Provide exactly one of `orderId` or `clientOrderId` per item. Sending both, or neither, returns a per-item validation error.
- The endpoint always processes every item independently. There is no `stopOnFail`-style switch.
- When the caller is not authenticated, the API returns the standard authorization error and skips per-item validation.
</Note>

<Note>
**`timestamp` and `mtime` on a successful item:** a canceled item's `result` may echo the order's `timestamp` (creation time) and `mtime` (the last time the matching engine modified the order — the moment of cancellation, since a cancellation is an order's final modification). Both are best-effort echoes: either may be omitted, so do not rely on either field's presence. For a cancel response that always includes `mtime`, use the single [Cancel order](/api-reference/trading/cancel-order) endpoint instead.
</Note>


export const signerFields = [{
  "name": "orders",
  "type": "array",
  "required": true,
  "description": "Array of orders to cancel. From 1 to 100 items per request."
}];

export const WhitebitSigner = ({path: defaultPath = "/api/v4/order/market", defaultParams = "{}", fields = null}) => {
  const {useState, useMemo} = React;
  const [baseUrl, setBaseUrl] = useState("https://whitebit.com");
  const getApiHost = () => baseUrl;
  const hex = buf => Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, "0")).join("");
  const b64 = s => {
    const bytes = new TextEncoder().encode(s);
    let bin = "";
    bytes.forEach(b => bin += String.fromCharCode(b));
    return btoa(bin);
  };
  const hmacSha512Hex = async (secret, msg) => {
    const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), {
      name: "HMAC",
      hash: "SHA-512"
    }, false, ["sign"]);
    const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(msg));
    return hex(sig);
  };
  const queryFields = fields ? fields.filter(function (f) {
    return f.paramIn === "query" || f.paramIn === "path";
  }) : [];
  const bodyFields = fields ? fields.filter(function (f) {
    return !f.paramIn || f.paramIn === "body";
  }) : [];
  const [open, setOpen] = useState(false);
  const [authOpen, setAuthOpen] = useState(true);
  const [paramsOpen, setParamsOpen] = useState(true);
  const [apiKey, setApiKey] = useState("");
  const [apiSecret, setApiSecret] = useState("");
  const [showSecret, setShowSecret] = useState(false);
  const [path, setPath] = useState(defaultPath);
  const initFieldValues = fieldDefs => {
    if (!fieldDefs) return {};
    const vals = {};
    for (const f of fieldDefs) {
      vals[f.name] = f.default !== undefined ? String(f.default) : "";
    }
    return vals;
  };
  const [fieldValues, setFieldValues] = useState(function () {
    return initFieldValues(fields);
  });
  const [showRaw, setShowRaw] = useState(false);
  const [params, setParams] = useState(defaultParams === "{}" ? "" : defaultParams);
  const [computed, setComputed] = useState(null);
  const [response, setResponse] = useState(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [urlCopied, setUrlCopied] = useState(false);
  const useFieldsMode = fields !== null && fields !== undefined && !showRaw;
  const setFieldValue = (name, value) => setFieldValues(function (prev) {
    return {
      ...prev,
      [name]: value
    };
  });
  const toggleRaw = () => {
    if (fields === null || fields === undefined) return;
    if (!showRaw) {
      const obj = {};
      for (const f of bodyFields) {
        const val = fieldValues[f.name];
        if (val !== "" && val !== null && val !== undefined) {
          obj[f.name] = f.type === "integer" || f.type === "number" ? Number(val) : val;
        }
      }
      setParams(Object.keys(obj).length ? JSON.stringify(obj, null, 2) : "");
      setShowRaw(true);
    } else {
      try {
        const parsed = JSON.parse(params.trim() || "{}");
        const next = {
          ...fieldValues
        };
        for (const f of bodyFields) {
          if (parsed[f.name] !== undefined) next[f.name] = String(parsed[f.name]);
        }
        setFieldValues(next);
      } catch (e) {}
      setShowRaw(false);
    }
  };
  const compute = async () => {
    setError("");
    setComputed(null);
    setResponse(null);
    try {
      if (!apiKey.trim()) throw new Error("API key is required");
      if (!apiSecret.trim()) throw new Error("API secret is required");
      let extraBodyParams = {};
      let queryString = "";
      if (useFieldsMode) {
        const qParams = {};
        for (const f of fields) {
          const val = fieldValues[f.name];
          const empty = val === "" || val === null || val === undefined;
          if (empty) {
            if (f.required) throw new Error('"' + f.name + '" is required');
            continue;
          }
          if (f.paramIn === "query" || f.paramIn === "path") {
            qParams[f.name] = String(val);
          } else {
            if (f.type === "integer" || f.type === "number") {
              const num = Number(val);
              if (isNaN(num)) throw new Error('"' + f.name + '" must be a number');
              extraBodyParams[f.name] = num;
            } else {
              extraBodyParams[f.name] = val;
            }
          }
        }
        if (Object.keys(qParams).length > 0) {
          queryString = "?" + Object.entries(qParams).map(function (kv) {
            return encodeURIComponent(kv[0]) + "=" + encodeURIComponent(kv[1]);
          }).join("&");
        }
      } else if (params.trim()) {
        try {
          extraBodyParams = JSON.parse(params.trim());
        } catch (e) {
          throw new Error("Body params is not valid JSON");
        }
      }
      const bodyObj = {
        request: path,
        nonce: Date.now(),
        nonceWindow: true
      };
      for (const k in extraBodyParams) bodyObj[k] = extraBodyParams[k];
      const bodyStr = JSON.stringify(bodyObj);
      const payload = b64(bodyStr);
      const signature = await hmacSha512Hex(apiSecret.trim(), payload);
      const result = {
        payload,
        signature,
        bodyStr,
        queryString
      };
      setComputed(result);
      return result;
    } catch (e) {
      setError(e && e.message ? e.message : String(e));
      return null;
    }
  };
  const send = async () => {
    setBusy(true);
    setResponse(null);
    try {
      const out = await compute();
      if (!out) return;
      const res = await fetch("/_mintlify/api/request", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          method: "post",
          url: getApiHost() + path + out.queryString,
          header: {
            "content-type": "application/json",
            "X-TXC-APIKEY": apiKey.trim(),
            "X-TXC-PAYLOAD": out.payload,
            "X-TXC-SIGNATURE": out.signature
          },
          body: JSON.parse(out.bodyStr),
          cookie: {},
          query: {}
        })
      });
      const text = await res.text();
      let status = res.status;
      let pretty = text;
      try {
        const json = JSON.parse(text);
        if (json.statusCode !== undefined) {
          status = json.statusCode;
          const raw = typeof json.body === "string" ? json.body : JSON.stringify(json.body);
          try {
            pretty = JSON.stringify(JSON.parse(raw), null, 2);
          } catch (e2) {
            pretty = raw;
          }
        } else {
          pretty = JSON.stringify(json, null, 2);
        }
      } catch (e2) {}
      setResponse({
        status,
        body: pretty
      });
    } catch (e) {
      setError(e && e.message ? e.message : String(e));
    } finally {
      setBusy(false);
    }
  };
  const copy = text => {
    if (navigator && navigator.clipboard) navigator.clipboard.writeText(text);
  };
  const headerRows = useMemo(function () {
    if (!computed) return [];
    return [{
      key: "X-TXC-APIKEY",
      value: apiKey.trim()
    }, {
      key: "X-TXC-PAYLOAD",
      value: computed.payload
    }, {
      key: "X-TXC-SIGNATURE",
      value: computed.signature
    }];
  }, [computed, apiKey]);
  const INPUT_CLS = "w-full rounded-xl border-standard px-3 py-2 text-sm font-mono bg-background-light dark:bg-background-dark outline-none focus:ring-1 focus:ring-[#3064E3]/40 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-white/20";
  const SECTION_CLS = "rounded-2xl border border-zinc-200 dark:border-zinc-800";
  const SECTION_BTN_CLS_OPEN = "flex w-full pt-3.5 pb-3 px-3.5 items-center justify-between cursor-pointer hover:bg-gray-50 dark:hover:bg-white/5 transition-colors rounded-t-2xl";
  const SECTION_BTN_CLS_CLOSED = "flex w-full pt-3.5 pb-3 px-3.5 items-center justify-between cursor-pointer hover:bg-gray-50 dark:hover:bg-white/5 transition-colors rounded-2xl";
  const renderField = function (f) {
    return <div key={f.name}>
        <div className="flex items-center gap-1.5 mb-1 mt-2.5">
          <span className="text-xs font-mono font-medium text-gray-700 dark:text-gray-300">{f.name}</span>
          {f.required ? <span className="text-xs text-red-500 dark:text-red-400">required</span> : <span className="text-xs text-gray-400 dark:text-gray-500">optional</span>}
          <span className="text-xs text-gray-400 dark:text-gray-500 ml-auto">{f.type}{f.enum ? " · enum" : ""}</span>
        </div>
        {f.description && <div className="text-xs text-gray-400 dark:text-gray-500 mb-1">{f.description}</div>}
        {f.enum ? <select className={INPUT_CLS} value={fieldValues[f.name] || ""} onChange={function (e) {
      setFieldValue(f.name, e.target.value);
    }}>
            {!f.required && <option value="">— leave empty —</option>}
            {f.enum.map(function (v) {
      return <option key={v} value={v}>{v}</option>;
    })}
          </select> : <input type={f.type === "integer" || f.type === "number" ? "number" : "text"} className={INPUT_CLS} value={fieldValues[f.name] || ""} onChange={function (e) {
      setFieldValue(f.name, e.target.value);
    }} placeholder={f.example !== undefined ? String(f.example) : f.required ? f.name : "optional"} spellCheck={false} autoComplete="off" />}
      </div>;
  };
  return <div className="not-prose my-6 flex w-full flex-col bg-background-light dark:bg-background-dark border-standard rounded-2xl p-1.5">

      {}
      <div className="flex w-full items-center space-x-1.5 rounded-xl p-1.5 border-standard">

        {}
        <div className="flex items-center gap-1.5 flex-1 min-w-0">
          <span className="rounded-lg font-bold px-1.5 py-0.5 text-xs leading-5 shrink-0 bg-blue-400/20 text-blue-700 dark:text-blue-400">
            POST
          </span>
          <div className="flex items-center flex-1 min-w-0 text-sm font-mono overflow-hidden">
            {}
            <div className="relative shrink-0 flex items-center">
              <select value={baseUrl} onChange={function (e) {
    setBaseUrl(e.target.value);
  }} onClick={function (e) {
    e.stopPropagation();
  }} className="appearance-none bg-transparent outline-none font-mono text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 transition-colors cursor-pointer pr-4">
                <option value="https://whitebit.com">https://whitebit.com</option>
                <option value="https://whitebit.eu">https://whitebit.eu</option>
              </select>
              <svg className="absolute right-0 top-1/2 -translate-y-1/2 pointer-events-none text-gray-400 dark:text-gray-500" width="10" height="10" viewBox="0 0 10 10" fill="none">
                <path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </div>
            {}
            <button type="button" title="Copy URL" onClick={function () {
    var url = baseUrl + path;
    if (navigator && navigator.clipboard) navigator.clipboard.writeText(url);
    setUrlCopied(true);
    setTimeout(function () {
      setUrlCopied(false);
    }, 1500);
  }} className="truncate text-left text-black dark:text-white transition-colors">
              {path}
            </button>
          </div>
        </div>

        <div className="flex items-center gap-1.5 shrink-0">
          {}
          <button type="button" title="Copy URL" onClick={function () {
    var url = getApiHost() + path;
    if (navigator && navigator.clipboard) navigator.clipboard.writeText(url);
    setUrlCopied(true);
    setTimeout(function () {
      setUrlCopied(false);
    }, 1500);
  }} className="flex items-center justify-center w-6 h-6 rounded-lg hover:bg-gray-200 dark:hover:bg-white/10 text-gray-400 dark:text-gray-500 transition-colors">
            {urlCopied ? <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
                <path d="M2 7L5 10L11 3" stroke="#2AB673" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
              </svg> : <svg width="13" height="13" viewBox="0 0 13 13" fill="none">
                <rect x="4.5" y="1.5" width="7" height="8" rx="1.5" stroke="currentColor" strokeWidth="1.2" />
                <path d="M2 4.5H1.5A1 1 0 0 0 .5 5.5v6A1 1 0 0 0 1.5 12.5h6A1 1 0 0 0 8.5 11.5V11" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" />
              </svg>}
          </button>

          {}
          <button type="button" onClick={function () {
    setOpen(function (v) {
      return !v;
    });
  }} className="text-sm font-semibold px-3 py-1.5 rounded-lg bg-[#2AB673] text-white hover:bg-[#239660] active:bg-[#1e7d52] transition-colors hidden sm:inline-flex items-center gap-1.5 cursor-pointer">
            {open ? <>
                Close
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none" className="shrink-0">
                  <path d="M2 9L6 5L10 9" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </> : <>
                Try it
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none" className="shrink-0">
                  <polygon points="2,1 11,6 2,11" fill="currentColor" />
                </svg>
              </>}
          </button>
        </div>
      </div>

      {}
      {open && <div className="mt-1.5 space-y-1.5">

          {}
          <div className={SECTION_CLS}>
            <button type="button" onClick={function () {
    setAuthOpen(function (v) {
      return !v;
    });
  }} className={authOpen ? SECTION_BTN_CLS_OPEN : SECTION_BTN_CLS_CLOSED}>
              <div className="flex items-center gap-x-1.5">
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none" className="text-gray-400 dark:text-gray-500 transition-transform shrink-0" style={{
    transform: authOpen ? "rotate(90deg)" : "rotate(0deg)"
  }}>
                  <path d="M4 2.5L8 6L4 9.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
                <span className="text-sm font-medium text-gray-800 dark:text-gray-200 leading-6">Authentication</span>
              </div>
            </button>
            {authOpen && <div className="px-3.5 pb-3.5 pt-0 border-t border-zinc-100 dark:border-zinc-800/60">
                <div className="flex items-center gap-1.5 mb-1 mt-2.5">
                  <span className="text-xs font-mono font-medium text-gray-700 dark:text-gray-300">X-TXC-APIKEY</span>
                  <span className="text-xs text-red-500 dark:text-red-400">required</span>
                  <span className="text-xs text-gray-400 dark:text-gray-500 ml-auto">string</span>
                </div>
                <input className={INPUT_CLS} value={apiKey} onChange={function (e) {
    setApiKey(e.target.value);
  }} placeholder="your-api-key" autoComplete="off" spellCheck={false} />

                <div className="flex items-center gap-1.5 mb-1 mt-2.5">
                  <span className="text-xs font-mono font-medium text-gray-700 dark:text-gray-300">API secret</span>
                  <span className="text-xs text-red-500 dark:text-red-400">required</span>
                  <span className="text-xs text-gray-400 dark:text-gray-500 ml-auto">string</span>
                </div>
                <div className="flex gap-1.5">
                  <input type={showSecret ? "text" : "password"} className={INPUT_CLS + " flex-1"} value={apiSecret} onChange={function (e) {
    setApiSecret(e.target.value);
  }} placeholder="your-api-secret" autoComplete="off" spellCheck={false} />
                  <button type="button" onClick={function () {
    setShowSecret(function (v) {
      return !v;
    });
  }} className="text-xs px-2.5 rounded-xl border-standard bg-background-light dark:bg-background-dark hover:bg-gray-50 dark:hover:bg-white/5 text-gray-500 dark:text-gray-400 shrink-0 transition-colors">
                    {showSecret ? "hide" : "show"}
                  </button>
                </div>
                <p className="text-xs text-gray-400 dark:text-gray-500 mt-1.5">
                  Credentials stay in memory only — never written to localStorage or cookies.
                </p>
              </div>}
          </div>

          {}
          <div className={SECTION_CLS}>
            <button type="button" onClick={function () {
    setParamsOpen(function (v) {
      return !v;
    });
  }} className={paramsOpen ? SECTION_BTN_CLS_OPEN : SECTION_BTN_CLS_CLOSED}>
              <div className="flex items-center gap-x-1.5">
                <svg width="12" height="12" viewBox="0 0 12 12" fill="none" className="text-gray-400 dark:text-gray-500 transition-transform shrink-0" style={{
    transform: paramsOpen ? "rotate(90deg)" : "rotate(0deg)"
  }}>
                  <path d="M4 2.5L8 6L4 9.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
                <span className="text-sm font-medium text-gray-800 dark:text-gray-200 leading-6">Body</span>
              </div>
              {fields !== null && fields !== undefined && bodyFields.length > 0 && <button type="button" onClick={function (e) {
    e.stopPropagation();
    toggleRaw();
  }} className="text-xs text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 underline mr-1">
                  {showRaw ? "form fields" : "edit as JSON"}
                </button>}
            </button>
            {paramsOpen && <div className="px-3.5 pb-3.5 pt-0 border-t border-zinc-100 dark:border-zinc-800/60">
                {queryFields.length > 0 && <div className="mb-1">
                    <p className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1 mt-2.5">Query parameters</p>
                    {queryFields.map(renderField)}
                  </div>}

                {useFieldsMode ? bodyFields.length > 0 ? <div>
                      {bodyFields.map(renderField)}
                      <p className="text-xs text-gray-400 dark:text-gray-500 mt-2">
                        <code className="font-mono">request</code>, <code className="font-mono">nonce</code>, <code className="font-mono">nonceWindow</code> added automatically.
                      </p>
                    </div> : <p className="text-xs text-gray-400 dark:text-gray-500 mt-2.5">
                      No body parameters required.{" "}
                      <code className="font-mono">request</code>, <code className="font-mono">nonce</code>, <code className="font-mono">nonceWindow</code> added automatically.
                    </p> : <div>
                    <p className="text-xs text-gray-400 dark:text-gray-500 mt-2.5 mb-1.5">
                      <code className="font-mono">request</code>, <code className="font-mono">nonce</code>, <code className="font-mono">nonceWindow</code> added automatically.
                    </p>
                    <textarea className={INPUT_CLS + " min-h-[80px] resize-y"} rows={4} value={params} onChange={function (e) {
    setParams(e.target.value);
  }} placeholder="{ &quot;market&quot;: &quot;BTC_USDT&quot; }" spellCheck={false} />
                  </div>}
              </div>}
          </div>

          {}
          <div className="flex flex-wrap items-center gap-1.5 px-0.5">
            <button type="button" onClick={send} disabled={busy} className="flex items-center justify-center px-3 h-9 text-sm font-medium rounded-xl hover:opacity-80 gap-1.5 transition-opacity disabled:opacity-50 disabled:pointer-events-none bg-[#3064E3] text-white">
              {busy ? <svg className="animate-spin w-4 h-4" viewBox="0 0 24 24" fill="none">
                  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                  <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z" />
                </svg> : "Send request"}
            </button>
            <button type="button" onClick={compute} disabled={busy} className="flex items-center justify-center px-3 h-9 text-sm font-medium rounded-xl border-standard hover:bg-gray-50 dark:hover:bg-white/5 transition-colors disabled:opacity-50 disabled:pointer-events-none text-gray-700 dark:text-gray-300 bg-background-light dark:bg-background-dark">
              Compute headers
            </button>
          </div>

          {}
          {error && <div className="px-3.5 py-2.5 rounded-2xl border border-red-200 dark:border-red-900/40 bg-red-50 dark:bg-red-950/20 text-sm text-red-600 dark:text-red-400 break-words">
              {error}
            </div>}

          {}
          {computed && <div className={SECTION_CLS + " overflow-hidden"}>
              <div className="flex items-center justify-between pt-3 pb-2.5 px-3.5 border-b border-zinc-100 dark:border-zinc-800/60">
                <span className="text-sm font-medium text-gray-800 dark:text-gray-200">Computed headers</span>
              </div>
              <div className="px-3.5 pb-3.5">
                {headerRows.map(function (row) {
    return <div key={row.key} className="mt-2.5">
                      <div className="flex items-center justify-between mb-1">
                        <span className="text-xs font-mono text-gray-500 dark:text-gray-400">{row.key}</span>
                        <button type="button" onClick={function () {
      copy(row.value);
    }} className="text-xs px-2 py-0.5 rounded-lg border-standard hover:bg-gray-50 dark:hover:bg-white/5 text-gray-500 dark:text-gray-400 transition-colors">
                          copy
                        </button>
                      </div>
                      <input readOnly value={row.value} className="w-full rounded-xl border-standard px-3 py-2 text-xs font-mono bg-gray-50 dark:bg-white/[0.03] text-gray-500 dark:text-gray-400 outline-none select-all cursor-default" />
                    </div>;
  })}
                <details className="mt-2.5">
                  <summary className="text-xs text-gray-400 dark:text-gray-500 cursor-pointer select-none hover:text-gray-600 dark:hover:text-gray-300 transition-colors">
                    full request body
                  </summary>
                  <pre className="text-xs font-mono whitespace-pre-wrap break-all mt-2 text-gray-600 dark:text-gray-400 m-0">
                    {(function () {
    try {
      return JSON.stringify(JSON.parse(computed.bodyStr), null, 2);
    } catch (e) {
      return computed.bodyStr;
    }
  })()}
                  </pre>
                </details>
                {computed.queryString && <p className="text-xs text-gray-400 dark:text-gray-500 font-mono mt-1">
                    query: {computed.queryString}
                  </p>}
              </div>
            </div>}

          {}
          {response && <div className={SECTION_CLS + " overflow-hidden"}>
              <div className="flex items-center gap-2 pt-3 pb-2.5 px-3.5 border-b border-zinc-100 dark:border-zinc-800/60">
                <span className="text-sm font-medium text-gray-800 dark:text-gray-200">Response</span>
                <span className={"text-xs font-mono font-medium px-1.5 py-0.5 rounded-lg " + (response.status < 400 ? "bg-[#2AB673]/10 text-[#2AB673]" : "bg-red-100/50 dark:bg-red-400/10 text-red-600 dark:text-red-300")}>
                  {response.status}
                </span>
              </div>
              <pre className="text-xs font-mono whitespace-pre-wrap overflow-auto max-h-80 m-0 px-3.5 py-3 text-gray-700 dark:text-gray-300">
                {response.body}
              </pre>
            </div>}

        </div>}

    </div>;
};

export const RelatedResources = ({children}) => {
  const {useEffect, useRef, useState} = React;
  const ref = useRef(null);
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    if (el.parentElement) {
      el.parentElement.appendChild(el);
    }
    setVisible(true);
  }, []);
  return <div ref={ref} className="related-resources" style={{
    marginTop: "2.5rem",
    paddingTop: "1.5rem",
    borderTop: "1px solid var(--border-color, #e5e7eb)",
    opacity: visible ? 1 : 0,
    transition: "opacity 0.15s ease-in"
  }}>
      <h2 style={{
    marginTop: 0
  }}>Related resources</h2>
      {children}
    </div>;
};

<WhitebitSigner path="/api/v4/order/cancel/bulk" fields={signerFields} />

<RelatedResources>
  * [Cancel order](/api-reference/trading/cancel-order) — cancel a single order by ID
  * [Cancel all orders](/api-reference/trading/cancel-all-orders) — cancel every open order in a market
  * [Bulk limit order](/api-reference/trading/bulk-limit-order) — sibling bulk endpoint for order creation
  * [Query unexecuted orders](/api-reference/trading/query-unexecuted-orders) — list open orders to cancel
</RelatedResources>


## OpenAPI

````yaml openapi/private/http-trade-v4.yaml POST /api/v4/order/cancel/bulk
openapi: 3.0.3
info:
  title: Private HTTP API V4 - Collateral Trading
  description: |
    WhiteBIT Private HTTP API V4 for collateral/margin trading operations.

    Base URL: https://whitebit.com

    All endpoints return time in Unix-time format.
    All endpoints return either a JSON object or array.
    For receiving responses from API calls please use http method POST.

    Authentication required for all endpoints.
  version: 4.0.0
  license:
    name: WhiteBIT Terms of Service
    url: https://whitebit.com/terms
servers:
  - url: https://whitebit.com
    description: WhiteBIT Global Server
  - url: https://whitebit.eu
    description: WhiteBIT EU Server
  - url: https://whitebit.tr
    description: WhiteBIT TR Server
  - url: https://whitebit.ge
    description: WhiteBIT GE Server
security:
  - ApiKeyAuth: []
    PayloadAuth: []
    SignatureAuth: []
tags:
  - name: Collateral Trading
    description: Endpoints for collateral/margin trading operations
  - name: Spot Trading
    description: Endpoints for spot trading operations
  - name: Market Fee
    description: Endpoints for querying trading fees
paths:
  /api/v4/order/cancel/bulk:
    post:
      tags:
        - Spot Trading
      summary: Cancel bulk orders
      description: >
        The endpoint cancels up to 100 [orders](/glossary#orders) in a single
        request. Each item identifies a target order by `market` plus exactly
        one of `orderId` or `clientOrderId`. The response is an array whose
        items match the input order one-to-one — `response[i]` corresponds to
        `request.orders[i]`.


        <Warning>

        Rate limit: 10000 requests/10 sec.

        </Warning>


        <Warning>

        Limit: From 1 to 100 orders per request.

        </Warning>


        <Note>

        - Provide exactly one of `orderId` or `clientOrderId` per item. Sending
        both, or neither, returns a per-item validation error.

        - The endpoint always processes every item independently. There is no
        `stopOnFail`-style switch.

        - When the caller is not authenticated, the API returns the standard
        authorization error and skips per-item validation.

        </Note>


        <Note>

        **`timestamp` and `mtime` on a successful item:** a canceled item's
        `result` may echo the order's `timestamp` (creation time) and `mtime`
        (the last time the matching engine modified the order — the moment of
        cancellation, since a cancellation is an order's final modification).
        Both are best-effort echoes: either may be omitted, so do not rely on
        either field's presence. For a cancel response that always includes
        `mtime`, use the single [Cancel
        order](/api-reference/trading/cancel-order) endpoint instead.

        </Note>
      operationId: cancelBulkOrders
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - orders
                - request
                - nonce
              properties:
                orders:
                  type: array
                  minItems: 1
                  maxItems: 100
                  description: Array of orders to cancel. From 1 to 100 items per request.
                  items:
                    $ref: '#/components/schemas/BulkCancelOrderItem'
                request:
                  type: string
                  example: '{{request}}'
                nonce:
                  type: integer
                  example: 1594297865000
            example:
              orders:
                - market: BTC_USDT
                  orderId: 4326248250
                - market: ETH_USDT
                  clientOrderId: my-client-id
              request: '{{request}}'
              nonce: 1594297865000
      responses:
        '200':
          description: >
            Bulk cancel result. The response is an array — `response[i]`
            corresponds to `request.orders[i]`. Each item contains either a
            `result` (cancellation succeeded) or an `error` (cancellation failed
            for that item). Partial failures within the array are normal; the
            request itself returns HTTP 200.


            Per-item error codes: `30` (validation failure), `404` (order not
            found), `500` (trade service unavailable). A failed item carries an
            `error` object following the standard error shape, for example:


            ```json

            {
              "result": null,
              "error": {
                "code": 30,
                "message": "Validation failed",
                "errors": { "market": ["validation.required"] }
              }
            }

            ```
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkCancelOrderResponse'
        '400':
          description: Inner validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service temporarily unavailable
      security:
        - ApiKeyAuth: []
          PayloadAuth: []
          SignatureAuth: []
components:
  schemas:
    BulkCancelOrderItem:
      type: object
      description: >-
        A single cancel target. Provide `market` and exactly one of `orderId` or
        `clientOrderId`. Sending both, or neither, returns a per-item validation
        error.
      required:
        - market
      properties:
        market:
          type: string
          description: 'Available [market](/glossary#market). Example: `BTC_USDT`.'
          example: BTC_USDT
        orderId:
          type: integer
          description: >-
            System-assigned order ID. Required if `clientOrderId` is not set;
            mutually exclusive with `clientOrderId`.
          example: 4326248250
        clientOrderId:
          type: string
          description: >-
            Client-defined order ID supplied at order creation. Required if
            `orderId` is not set; mutually exclusive with `orderId`.
          example: my-client-id
    BulkCancelOrderResponse:
      type: array
      description: >-
        Per-item cancel results. `response[i]` corresponds to
        `request.orders[i]`. Each item contains either `result` (cancellation
        succeeded) or `error` (cancellation failed for that item) — never both.
      items:
        type: object
        properties:
          result:
            type: object
            allOf:
              - $ref: '#/components/schemas/BulkCancelOrderResult'
            nullable: true
          error:
            type: object
            allOf:
              - $ref: '#/components/schemas/ErrorResponse'
            nullable: true
    ErrorResponse:
      type: object
      properties:
        code:
          type: integer
          description: Error code
          example: 30
        message:
          type: string
          description: Error message
          example: Validation failed
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Detailed error information
    BulkCancelOrderResult:
      type: object
      description: >-
        Acknowledgement that a single item was canceled. The endpoint echoes the
        identifiers from the request item and, when available, the order's
        `timestamp` and `mtime`. Full order state is not returned. Use the
        single Cancel order endpoint when post-cancel order state is required.
      properties:
        orderId:
          type: integer
          description: System-assigned order ID of the canceled order.
          example: 4326248250
        clientOrderId:
          type: string
          description: >-
            Client-defined order ID of the canceled order, if one was set at
            order creation.
          example: my-client-id
        market:
          type: string
          description: >-
            Trading pair of the canceled order. Format: `BASE_QUOTE` (e.g.
            `BTC_USDT`).
          example: BTC_USDT
        timestamp:
          type: number
          description: >-
            Unix timestamp in seconds (UTC), with microsecond precision, of
            order creation. Optional. May be omitted; do not rely on its
            presence.
          example: 1595792396.165973
        mtime:
          type: number
          description: >-
            Unix timestamp in seconds (UTC), with microsecond precision, of the
            last time the matching engine modified the order. When present, the
            value is the moment the engine processed the cancellation, because a
            cancellation is the order's final modification. Optional — may be
            omitted; do not rely on its presence.
          example: 1595792412.443301
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-TXC-APIKEY
      description: The public WhiteBIT API key.
    PayloadAuth:
      type: apiKey
      in: header
      name: X-TXC-PAYLOAD
      description: Base64-encoded JSON request body.
    SignatureAuth:
      type: apiKey
      in: header
      name: X-TXC-SIGNATURE
      description: >-
        HMAC-SHA512 signature of the payload, hex-encoded. Computed as
        hex(HMAC-SHA512(payload, api_secret)).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.