> ## Documentation Index
> Fetch the complete documentation index at: https://help.miyaip.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MiyaIP short-lived residential API: generate proxy IPs

> Generate MiyaIP short-lived residential proxy IPs with a Bearer token, country and optional state selection, and a requested count that consumes IP allowance.

export const MiyaApiPlayground = ({specUrl, method, path, locale = "en"}) => {
  const miyaApiOrigin = "https://miyaip.com";
  const miyaResponseLimit = 200 * 1024;
  const miyaAllowedOperations = ["POST /api/SysLogin/Login", "GET /api/ProxyLogic/Generate", "POST /api/UserShort/GenerateIps", "GET /api/ProxyLogic/UnlimitedGenerate", "GET /api/SysLogin/GetUserInfo", "GET /api/ProxyLogic/BandwidthAnalysis", "GET /api/UserIsps/PageList", "GET /api/DatacenterIps/PageList"];
  const miyaAllowedSpecs = ["/api-reference/openapi.zh.json", "/api-reference/openapi.en.json"];
  const miyaSensitiveKey = /password|passwd|pwd|token|secret|authorization|^crc$|keyname|key$|api.?key|user.?name|proxy.?user|proxy.?pass|full.?proxy/i;
  const miyaLabels = locale => locale === "zh" ? {
    title: "在线调试",
    loading: "正在加载接口配置…",
    loadError: "无法加载接口配置。请刷新页面后重试。",
    unsupported: "此调试器仅支持文档中列出的 MiyaIP 接口。",
    request: "请求预览（凭据已隐藏）",
    send: "发送请求",
    sending: "请求中…",
    cancel: "取消请求",
    clear: "清空",
    optional: "可选",
    required: "必填",
    requiredError: "请填写此项。",
    integerError: "请输入整数。",
    emailError: "请输入有效的邮箱地址。",
    enumError: "请选择文档列出的选项。",
    minimum: "最小值为",
    maximum: "最大值为",
    live: "点击发送会向 MiyaIP 发送实际请求。凭据和响应仅保存在本页面的内存中。",
    cancelNote: "超时或取消只会停止浏览器等待，不能保证服务器撤销请求；调试器不会自动重试。",
    response: "响应",
    elapsed: "耗时",
    status: "HTTP 状态",
    contentType: "响应类型",
    businessCode: "业务 code",
    httpSuccess: "HTTP 请求完成",
    businessSuccess: "业务 code 表示成功",
    businessError: "接口返回业务错误",
    httpError: "接口返回 HTTP 错误",
    networkError: "请求失败。请检查网络、跨域策略及连接状态。",
    timeout: "等待超过 30 秒，请求已停止等待。",
    cancelled: "已取消等待响应。",
    truncated: "响应超过 200 KiB，展示内容已截断；不能据此判断完整 JSON 或业务结果。",
    invalidJson: "响应无法解析为 JSON，请检查响应类型和原始返回内容。",
    jsonHidden: "为避免泄露敏感字段，不展示截断或无法解析的 JSON 正文。",
    empty: "响应正文为空。",
    showProxy: "显示代理连接信息",
    hideProxy: "隐藏代理连接凭据",
    token: "登录 Token",
    showToken: "显示 Token",
    hideToken: "隐藏 Token",
    copyToken: "复制 Token",
    copied: "已复制 Token。",
    copyFailed: "复制失败，请显示 Token 后手动复制。",
    masked: "敏感字段默认隐藏。",
    proxyMasked: "代理连接凭据默认隐藏，可主动显示完整原文。"
  } : {
    title: "Try this API",
    loading: "Loading the API configuration…",
    loadError: "The API configuration could not be loaded. Refresh this page and try again.",
    unsupported: "This form only supports the MiyaIP endpoints listed in these docs.",
    request: "Request preview (credentials hidden)",
    send: "Send request",
    sending: "Sending…",
    cancel: "Cancel request",
    clear: "Clear",
    optional: "Optional",
    required: "Required",
    requiredError: "Enter a value.",
    integerError: "Enter a whole number.",
    emailError: "Enter a valid email address.",
    enumError: "Select one of the documented options.",
    minimum: "The minimum is",
    maximum: "The maximum is",
    live: "Sending makes a real request to MiyaIP. Credentials and responses remain in memory on this page only.",
    cancelNote: "A timeout or cancellation stops the browser from waiting; it does not guarantee that the server cancels the request. This form never retries automatically.",
    response: "Response",
    elapsed: "Elapsed",
    status: "HTTP status",
    contentType: "Content type",
    businessCode: "Business code",
    httpSuccess: "HTTP request completed",
    businessSuccess: "The business code indicates success",
    businessError: "The API returned a business error",
    httpError: "The API returned an HTTP error",
    networkError: "The request failed. Check the network, CORS policy, and connection status.",
    timeout: "The 30-second wait expired. The browser stopped waiting.",
    cancelled: "Stopped waiting for the response.",
    truncated: "The response exceeds 200 KiB and has been truncated. A partial response cannot confirm a complete JSON or business result.",
    invalidJson: "The response could not be parsed as JSON. Check its content type and returned content.",
    jsonHidden: "A truncated or unparseable JSON body is not displayed, so its sensitive fields cannot be exposed.",
    empty: "The response body is empty.",
    showProxy: "Show proxy credentials",
    hideProxy: "Hide proxy credentials",
    token: "Login token",
    showToken: "Show token",
    hideToken: "Hide token",
    copyToken: "Copy token",
    copied: "Token copied.",
    copyFailed: "Copy failed. Show the token and copy it manually.",
    masked: "Sensitive fields are hidden by default.",
    proxyMasked: "Proxy credentials are hidden by default. You can explicitly show the original text."
  };
  const miyaActiveFields = (fields, values) => fields.filter(field => !field.showWhen || Object.entries(field.showWhen).every(([name, expected]) => String(values[name]) === String(expected)));
  const miyaDefaultValues = fields => Object.fromEntries(fields.map(field => [field.name, field.defaultValue === undefined || field.defaultValue === null ? "" : String(field.defaultValue)]));
  const miyaValidate = (fields, values, labels) => {
    const errors = {};
    miyaActiveFields(fields, values).forEach(field => {
      const value = String(values[field.name] ?? "").trim();
      if (!value) {
        if (field.required) errors[field.name] = labels.requiredError;
        return;
      }
      if (field.type === "integer") {
        const number = Number(value);
        if (!(/^-?\d+$/).test(value) || !Number.isSafeInteger(number)) errors[field.name] = labels.integerError; else if (field.min !== undefined && number < field.min) errors[field.name] = `${labels.minimum} ${field.min}.`; else if (field.max !== undefined && number > field.max) errors[field.name] = `${labels.maximum} ${field.max}.`;
      }
      if (field.input === "email" && !(/^[^\s@]+@[^\s@]+\.[^\s@]+$/).test(value)) errors[field.name] = labels.emailError;
      if (field.options?.length && !field.options.some(option => String(option.value) === value)) errors[field.name] = labels.enumError;
    });
    return errors;
  };
  const miyaBearerToken = value => String(value).trim().replace(/^Bearer\s+/i, "").trim();
  const miyaKnownSecrets = (fields, values) => miyaActiveFields(fields, values).filter(field => field.sensitive || field.in === "header" || miyaSensitiveKey.test(field.name)).flatMap(field => {
    const raw = String(values[field.name] ?? "");
    return field.in === "header" ? [raw, raw.trim(), miyaBearerToken(raw)] : [raw];
  }).filter(Boolean).sort((a, b) => b.length - a.length);
  const miyaMaskString = (text, secrets = []) => {
    let masked = String(text);
    secrets.forEach(secret => {
      const formEncoded = new URLSearchParams([["value", secret]]).toString().slice(("value=").length);
      [...new Set([secret, encodeURIComponent(secret), formEncoded])].sort((a, b) => b.length - a.length).forEach(variant => {
        masked = masked.split(variant).join("[hidden]");
      });
    });
    return masked.replace(/((?:https?|socks5?h?):\/\/)[^\s/@]+(?::[^\s/@]*)?@/gi, "$1[hidden]@").replace(/(^|\n)(\s*)[^\r\n\s@]+@([^\r\n]+)/g, "$1$2[hidden]@$3").replace(/(^|\n)(\s*)[^:\s]+:[^:\s]+:(\[[^\]\s]+\]|[^:\s]+):(\d+)(?=\r?\n|$)/g, "$1$2[hidden]:[hidden]:$3:$4").replace(/(^|\n)(\s*(?:\[[^\]\s]+\]|[^\s:]+):\d+:)[^\r\n]+/g, "$1$2[hidden]:[hidden]");
  };
  const miyaRedactJson = (value, secrets = []) => {
    if (Array.isArray(value)) return value.map(item => miyaRedactJson(item, secrets));
    if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, miyaSensitiveKey.test(key) && item !== null && item !== "" && ["string", "object"].includes(typeof item) ? "[hidden]" : miyaRedactJson(item, secrets)]));
    return typeof value === "string" ? miyaMaskString(value, secrets) : value;
  };
  const miyaMaskProxyText = (text, format, secrets) => String(text).split("\n").map(line => {
    if (!line.trim()) return line;
    let masked;
    if (String(format) === "0") masked = line.replace(/^(\s*(?:\[[^\]\s]+\]|[^:\s]+):\d+):[^\r\n]+$/, "$1:[hidden]:[hidden]"); else if (String(format) === "1") masked = line.replace(/^(\s*)[^\r\n]+@([^\r\n]+)$/, "$1[hidden]@$2"); else if (String(format) === "2") masked = line.replace(/^(\s*)[^\r\n]+:(\[[^\]\s]+\]|[^:\s]+):(\d+)\s*$/, "$1[hidden]:[hidden]:$2:$3");
    return masked && masked !== line ? miyaMaskString(masked, secrets) : "[hidden]";
  }).join("\n");
  const miyaFindToken = value => {
    if (!value || typeof value !== "object") return "";
    for (const [key, item] of Object.entries(value)) {
      if ((/^(?:token|access_?token|jwt)$/i).test(key) && typeof item === "string" && item) return item;
      if (item && typeof item === "object") {
        const found = miyaFindToken(item);
        if (found) return found;
      }
    }
    return "";
  };
  const miyaBuildRequest = (method, path, fields, values, redacted = false) => {
    if (!miyaAllowedOperations.includes(`${method} ${path}`)) throw new Error("Unsupported operation");
    const url = new URL(path, miyaApiOrigin);
    const headers = {
      Accept: "application/json, text/plain"
    };
    const body = {};
    miyaActiveFields(fields, values).forEach(field => {
      const raw = String(values[field.name] ?? "");
      if (!raw.trim()) return;
      const sensitive = field.sensitive || field.in === "header" || miyaSensitiveKey.test(field.name);
      const value = redacted && sensitive ? "[hidden]" : field.type === "integer" ? Number(raw) : raw;
      if (field.in === "header") {
        headers.Authorization = redacted ? "Bearer [hidden]" : `Bearer ${miyaBearerToken(raw)}`;
      } else if (field.in === "query") url.searchParams.set(field.name, String(value)); else if (field.in === "body") body[field.name] = value;
    });
    const init = {
      method,
      headers,
      credentials: "omit",
      mode: "cors",
      redirect: "error"
    };
    if (method === "POST") {
      headers["Content-Type"] = "application/json";
      init.body = JSON.stringify(body);
    }
    return {
      url: url.toString(),
      init
    };
  };
  const miyaReadResponse = async (response, limit = miyaResponseLimit) => {
    if (!response.body?.getReader) {
      const bytes = new TextEncoder().encode(await response.text());
      return {
        text: new TextDecoder().decode(bytes.subarray(0, limit)),
        truncated: bytes.length > limit
      };
    }
    const reader = response.body.getReader();
    const chunks = [];
    let size = 0;
    let truncated = false;
    try {
      while (true) {
        const {value, done} = await reader.read();
        if (done) break;
        const remaining = limit - size;
        if (value.byteLength > remaining) {
          if (remaining > 0) chunks.push(value.subarray(0, remaining));
          size = limit;
          truncated = true;
          await reader.cancel();
          break;
        }
        chunks.push(value);
        size += value.byteLength;
      }
    } finally {
      reader.releaseLock();
    }
    const bytes = new Uint8Array(size);
    let offset = 0;
    chunks.forEach(chunk => {
      bytes.set(chunk, offset);
      offset += chunk.byteLength;
    });
    return {
      text: new TextDecoder().decode(bytes),
      truncated
    };
  };
  const miyaParseResponse = (response, payload, method, path, secrets, outputFormat) => {
    const contentType = response.headers.get("content-type") || "";
    const expectsText = method === "GET" && ["/api/ProxyLogic/Generate", "/api/ProxyLogic/UnlimitedGenerate"].includes(path);
    let parsed = null;
    let invalidJson = false;
    if (!payload.truncated && payload.text.trim() && (contentType.includes("json") || !expectsText)) {
      try {
        parsed = JSON.parse(payload.text);
      } catch {
        invalidJson = true;
      }
    }
    const code = parsed && !Array.isArray(parsed) && typeof parsed === "object" ? parsed.code : undefined;
    const codeSuccess = code === 0 || code === 200 || code === "0" || code === "200";
    const kind = !response.ok ? "httpError" : payload.truncated ? "truncated" : invalidJson ? "invalidJson" : code !== undefined ? codeSuccess ? "businessSuccess" : "businessError" : "httpSuccess";
    const token = path === "/api/SysLogin/Login" && response.ok && !payload.truncated && kind !== "businessError" ? miyaFindToken(parsed) : "";
    const textResponse = parsed === null && expectsText && !contentType.includes("json");
    const hiddenJson = !textResponse && (payload.truncated || invalidJson);
    return {
      status: response.status,
      contentType,
      kind,
      code,
      truncated: payload.truncated,
      rawText: payload.text,
      textResponse,
      hiddenJson,
      token,
      maskedText: hiddenJson ? "" : parsed !== null ? JSON.stringify(miyaRedactJson(parsed, [...secrets, token].filter(Boolean)), null, 2) : textResponse ? miyaMaskProxyText(payload.text, outputFormat, secrets) : miyaMaskString(payload.text, [...secrets, token].filter(Boolean))
    };
  };
  const labels = useMemo(() => miyaLabels(locale), [locale]);
  const [config, setConfig] = useState(null);
  const [values, setValues] = useState({});
  const [errors, setErrors] = useState({});
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState("");
  const [pending, setPending] = useState(false);
  const [result, setResult] = useState(null);
  const [showToken, setShowToken] = useState(false);
  const [showProxy, setShowProxy] = useState(false);
  const [notice, setNotice] = useState("");
  const requestRef = useRef(null);
  const sequenceRef = useRef(0);
  const liveRef = useRef(false);
  useEffect(() => {
    liveRef.current = true;
    sequenceRef.current += 1;
    requestRef.current?.controller.abort();
    requestRef.current = null;
    setConfig(null);
    setValues({});
    setErrors({});
    setResult(null);
    setShowToken(false);
    setShowProxy(false);
    setNotice("");
    setPending(false);
    setLoading(true);
    setLoadError("");
    const specController = new AbortController();
    let current = true;
    const load = async () => {
      if (!miyaAllowedSpecs.includes(specUrl) || !miyaAllowedOperations.includes(`${method} ${path}`)) {
        if (current) {
          setLoadError(labels.unsupported);
          setLoading(false);
        }
        return;
      }
      try {
        const response = await fetch(specUrl, {
          credentials: "omit",
          signal: specController.signal
        });
        if (!response.ok) throw new Error("Configuration unavailable");
        const spec = await response.json();
        const metadata = spec.paths?.[path]?.[method.toLowerCase()]?.["x-miya-playground"];
        if (!metadata || !Array.isArray(metadata.fields) || !metadata.fields.every(field => typeof field.name === "string" && ["query", "body", "header"].includes(field.in))) throw new Error("Invalid configuration");
        if (current) {
          setConfig(metadata);
          setValues(miyaDefaultValues(metadata.fields));
        }
      } catch (error) {
        if (current && !specController.signal.aborted) setLoadError(labels.loadError);
      } finally {
        if (current) setLoading(false);
      }
    };
    load();
    return () => {
      current = false;
      liveRef.current = false;
      sequenceRef.current += 1;
      specController.abort();
      requestRef.current?.controller.abort();
      requestRef.current = null;
    };
  }, [specUrl, method, path, locale]);
  const fields = config?.fields || [];
  const activeFields = miyaActiveFields(fields, values);
  const preview = useMemo(() => {
    if (!config) return "";
    try {
      const request = miyaBuildRequest(method, path, config.fields, values, true);
      return `${method} ${request.url}\n${Object.entries(request.init.headers).map(([key, value]) => `${key}: ${value}`).join("\n")}${request.init.body ? `\n\n${JSON.stringify(JSON.parse(request.init.body), null, 2)}` : ""}`;
    } catch {
      return "";
    }
  }, [config, values, method, path]);
  const updateValue = (name, value) => {
    setValues(previous => ({
      ...previous,
      [name]: value
    }));
    setErrors(previous => {
      const next = {
        ...previous
      };
      delete next[name];
      return next;
    });
  };
  const cancel = () => {
    const active = requestRef.current;
    if (!active) return;
    sequenceRef.current += 1;
    active.controller.abort();
    requestRef.current = null;
    setPending(false);
    setResult({
      kind: "cancelled",
      elapsed: Math.round(performance.now() - active.started)
    });
    setShowToken(false);
    setShowProxy(false);
    setNotice("");
  };
  const clear = () => {
    sequenceRef.current += 1;
    requestRef.current?.controller.abort();
    requestRef.current = null;
    setValues(miyaDefaultValues(fields));
    setErrors({});
    setResult(null);
    setShowToken(false);
    setShowProxy(false);
    setNotice("");
    setPending(false);
  };
  const submit = async event => {
    event.preventDefault();
    if (!config || requestRef.current || !liveRef.current) return;
    const nextErrors = miyaValidate(fields, values, labels);
    setErrors(nextErrors);
    if (Object.keys(nextErrors).length) return;
    const controller = new AbortController();
    const serial = ++sequenceRef.current;
    const started = performance.now();
    requestRef.current = {
      controller,
      serial,
      started
    };
    setPending(true);
    setResult(null);
    setShowToken(false);
    setShowProxy(false);
    setNotice("");
    let timedOut = false;
    let status;
    let contentType;
    const timeout = setTimeout(() => {
      timedOut = true;
      controller.abort();
    }, 30000);
    try {
      const request = miyaBuildRequest(method, path, fields, values);
      const response = await fetch(request.url, {
        ...request.init,
        signal: controller.signal
      });
      status = response.status;
      contentType = response.headers.get("content-type") || "";
      const payload = await miyaReadResponse(response);
      const parsed = miyaParseResponse(response, payload, method, path, miyaKnownSecrets(fields, values), values.Format);
      if (liveRef.current && sequenceRef.current === serial) setResult({
        ...parsed,
        elapsed: Math.round(performance.now() - started)
      });
    } catch {
      if (liveRef.current && sequenceRef.current === serial) setResult({
        kind: timedOut ? "timeout" : controller.signal.aborted ? "cancelled" : "networkError",
        status,
        contentType,
        elapsed: Math.round(performance.now() - started)
      });
    } finally {
      clearTimeout(timeout);
      if (requestRef.current?.serial === serial) requestRef.current = null;
      if (liveRef.current && sequenceRef.current === serial) setPending(false);
    }
  };
  const copyToken = async () => {
    if (!result?.token) return;
    const serial = sequenceRef.current;
    try {
      await navigator.clipboard.writeText(result.token);
      if (liveRef.current && sequenceRef.current === serial) setNotice(labels.copied);
    } catch {
      if (liveRef.current && sequenceRef.current === serial) setNotice(labels.copyFailed);
    }
  };
  const border = "1px solid rgba(128, 128, 128, 0.35)";
  const inputStyle = {
    width: "100%",
    minWidth: 0,
    border,
    borderRadius: "8px",
    padding: "8px 10px",
    background: "transparent",
    color: "inherit",
    font: "inherit",
    colorScheme: "inherit"
  };
  const buttonStyle = {
    border,
    borderRadius: "8px",
    padding: "8px 12px",
    background: "transparent",
    color: "inherit",
    cursor: "pointer",
    font: "inherit",
    fontSize: "14px"
  };
  const preStyle = {
    border,
    borderRadius: "8px",
    padding: "12px",
    maxHeight: "420px",
    overflow: "auto",
    whiteSpace: "pre-wrap",
    overflowWrap: "anywhere",
    fontSize: "13px",
    lineHeight: 1.6,
    background: "rgba(128, 128, 128, 0.06)",
    color: "inherit"
  };
  const hasResponseBody = result && result.rawText !== undefined;
  const responseText = hasResponseBody ? result.hiddenJson ? labels.jsonHidden : result.textResponse && showProxy ? result.rawText : result.maskedText : "";
  return <section data-miya-api-playground="true" aria-label={labels.title} style={{
    border,
    borderRadius: "12px",
    padding: "20px",
    margin: "24px 0",
    color: "inherit"
  }}>
      <h3 style={{
    marginTop: 0
  }}>{labels.title}</h3>
      {loading && <p role="status">{labels.loading}</p>}
      {loadError && <p role="alert">{loadError}</p>}
      {config && !loading && <>
          <p style={{
    fontSize: "14px",
    lineHeight: 1.6
  }}>{labels.live}</p>
          {config.warning && <p style={{
    borderLeft: "3px solid #ef7025",
    paddingLeft: "12px",
    fontSize: "14px"
  }}>{config.warning}</p>}
          <form onSubmit={submit} noValidate>
            <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 240px), 1fr))",
    gap: "16px",
    margin: "18px 0"
  }}>
              {activeFields.map(field => <label key={field.name} style={{
    display: "block",
    minWidth: 0
  }}>
                  <span style={{
    display: "block",
    marginBottom: "6px",
    fontSize: "14px",
    fontWeight: 600
  }}>
                    {field.label || field.name} <span style={{
    fontWeight: 400,
    opacity: 0.7
  }}>({field.required ? labels.required : labels.optional})</span>
                  </span>
                  {field.input === "select" || field.options?.length ? <select name={field.name} value={values[field.name] ?? ""} disabled={pending} style={inputStyle} aria-invalid={Boolean(errors[field.name])} onChange={event => updateValue(field.name, event.target.value)}>
                      {!field.options?.some(option => String(option.value) === "") && <option value="">—</option>}
                      {(field.options || []).map(option => <option key={String(option.value)} value={String(option.value)}>{option.label || String(option.value)}</option>)}
                    </select> : <input name={field.name} type={field.sensitive || field.in === "header" ? "password" : field.input || (field.type === "integer" ? "number" : "text")} value={values[field.name] ?? ""} placeholder={field.placeholder || ""} min={field.min} max={field.max} step={field.type === "integer" ? 1 : undefined} disabled={pending} autoComplete="off" spellCheck={false} aria-invalid={Boolean(errors[field.name])} onChange={event => updateValue(field.name, event.target.value)} style={inputStyle} />}
                  {field.description && <span style={{
    display: "block",
    fontSize: "12px",
    lineHeight: 1.5,
    opacity: 0.75,
    marginTop: "5px"
  }}>{field.description}</span>}
                  {errors[field.name] && <span role="alert" style={{
    display: "block",
    fontSize: "13px",
    color: "#ef7025",
    marginTop: "4px"
  }}>{errors[field.name]}</span>}
                </label>)}
            </div>
            <details style={{
    margin: "16px 0"
  }}>
              <summary style={{
    cursor: "pointer",
    fontSize: "14px"
  }}>{labels.request}</summary>
              <pre data-miya-request-preview="true" style={preStyle}>{preview}</pre>
            </details>
            <div style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "8px"
  }}>
              <button type="submit" disabled={pending} style={{
    ...buttonStyle,
    background: "#ef7025",
    color: "#fff",
    borderColor: "#ef7025",
    opacity: pending ? 0.6 : 1
  }}>
                {pending ? labels.sending : config.submitLabel || labels.send}
              </button>
              {pending && <button type="button" onClick={cancel} style={buttonStyle}>{labels.cancel}</button>}
              <button type="button" onClick={clear} style={buttonStyle}>{labels.clear}</button>
            </div>
          </form>
          <p style={{
    fontSize: "12px",
    lineHeight: 1.6,
    opacity: 0.75
  }}>{labels.cancelNote}</p>
          {result && <div data-miya-response="true" aria-live="polite" style={{
    marginTop: "20px"
  }}>
              <h4 style={{
    marginBottom: "8px"
  }}>{labels.response}</h4>
              <p role={["networkError", "timeout", "httpError", "businessError", "invalidJson"].includes(result.kind) ? "alert" : "status"}>
                {labels[result.kind] || labels.httpSuccess}
              </p>
              <p style={{
    fontSize: "13px",
    display: "flex",
    flexWrap: "wrap",
    gap: "12px"
  }}>
                {result.status !== undefined && <span>{labels.status}: <strong>{result.status}</strong></span>}
                <span>{labels.elapsed}: {result.elapsed} ms</span>
                {result.code !== undefined && <span>{labels.businessCode}: <strong>{String(result.code)}</strong></span>}
                {result.contentType && <span>{labels.contentType}: {result.contentType}</span>}
              </p>
              {result.truncated && result.kind !== "truncated" && <p>{labels.truncated}</p>}
              {result.token && <div style={{
    border,
    borderRadius: "8px",
    padding: "12px",
    margin: "12px 0"
  }}>
                  <p style={{
    margin: "0 0 8px",
    fontSize: "14px"
  }}>{labels.token}: <code style={{
    overflowWrap: "anywhere"
  }}>{showToken ? result.token : "••••••••"}</code></p>
                  <div style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "8px"
  }}>
                    <button type="button" onClick={() => setShowToken(shown => !shown)} style={buttonStyle}>{showToken ? labels.hideToken : labels.showToken}</button>
                    <button type="button" onClick={copyToken} style={buttonStyle}>{labels.copyToken}</button>
                  </div>
                  {notice && <p role="status" style={{
    fontSize: "13px",
    marginBottom: 0
  }}>{notice}</p>}
                </div>}
              {hasResponseBody && <>
                  <p style={{
    fontSize: "12px",
    opacity: 0.75
  }}>{result.textResponse ? labels.proxyMasked : labels.masked}</p>
                  {result.textResponse && <button type="button" onClick={() => setShowProxy(shown => !shown)} style={buttonStyle}>{showProxy ? labels.hideProxy : labels.showProxy}</button>}
                  <pre data-miya-response-body="true" style={preStyle}>{responseText || labels.empty}</pre>
                </>}
            </div>}
        </>}
    </section>;
};

Generate short-lived residential proxies for your account. Each generated proxy is valid for 24 hours according to the source reference.

<Warning>
  Sending this request consumes your short-lived IP allowance. Check the country, optional state, and quantity before sending. The debugger does not automatically retry generation requests.
</Warning>

## Generate a batch

1. Obtain an access token from [Log in](/api-reference/login) and enter it as the Bearer credential.
2. Fill in the required `CountryCode` and `Count`. Use an uppercase ISO country code and, if needed, the optional `StateCode` from the supported locations.
3. Send once and check the HTTP and business results. Read `proxyList` and `failedList`, then compare `requestCount` with `failedCount` rather than assuming every requested proxy was generated.

The current public form accepts `Count` from 1 to 100. This documents the interface's input range; it does not guarantee that your account has enough allowance or that every location is available. The source does not provide a complete country and state enumeration.

If a request times out or is canceled, review your account before sending another batch. A missing response does not prove that generation did not occur. See [API response handling](/api-reference/overview).

## Online debugging

<MiyaApiPlayground specUrl="/api-reference/openapi.en.json" method="POST" path="/api/UserShort/GenerateIps" locale="en" key="en:short-generate" />

[Source: official short-lived generation reference](https://miyaip.com/developer-center?endpoint=short-generate).


## OpenAPI

````yaml api-reference/openapi.en.json POST /api/UserShort/GenerateIps
openapi: 3.0.3
info:
  title: MiyaIP API integration
  version: '2026-10-13'
  description: >-
    This specification documents the eight endpoints published in the Developer
    Center. Response structures follow the source examples and do not claim to
    define every returned field. Form minimums, maximums, and initial values
    describe client behavior and are retained in x-miya-playground rather than
    asserted as unverified server constraints or defaults.
servers:
  - url: https://miyaip.com
    description: Production API base URL
security: []
tags:
  - name: authentication
    description: Authentication
    x-displayName: Authentication
  - name: proxy-generation
    description: Proxy generation
    x-displayName: Proxy generation
  - name: account-data
    description: Account and usage
    x-displayName: Account and usage
  - name: proxy-inventory
    description: Proxy inventory
    x-displayName: Proxy inventory
externalDocs:
  description: Developer Center source
  url: https://miyaip.com/developer-center
paths:
  /api/UserShort/GenerateIps:
    post:
      tags:
        - proxy-generation
      summary: Generate short-term proxies
      description: >-
        Generate short-term residential proxies by country and optional state or
        province. Each generated proxy is valid for 24 hours.


        Requires a Bearer token returned by the login API. Generation consumes
        short-term IP quota from the authenticated account.
      operationId: short-generate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                CountryCode:
                  type: string
                  example: US
                  description: >-
                    Uppercase ISO country code. Use
                    /api/Location/SearchUserShort to list available countries.
                StateCode:
                  type: string
                  example: CA
                  description: Optional state or province code within the selected country.
                Count:
                  type: integer
                  example: 1
                  description: Number of short-term proxies to generate, between 1 and 100.
              required:
                - CountryCode
                - Count
            example:
              CountryCode: US
              StateCode: CA
              Count: 1
      responses:
        '200':
          description: Generated short-term proxies
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                  message:
                    type: string
                  body:
                    type: object
                    properties:
                      proxyList:
                        type: array
                        items:
                          type: string
                      failedList:
                        type: array
                        items: {}
                      requestCount:
                        type: integer
                      failedCount:
                        type: integer
              example:
                code: 200
                message: Success
                body:
                  proxyList:
                    - gateway.miyaip.com:10000:username:********
                  failedList: []
                  requestCount: 1
                  failedCount: 0
        '400':
          description: >-
            Business or validation error


            The source labels this example as HTTP 400 while its JSON business
            code is 500. HTTP status and the JSON business code are distinct
            values; this example is not a complete catalog of error statuses or
            codes.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                  message:
                    type: string
                  body:
                    description: >-
                      The source example is null; the source does not define
                      this field's complete value type.
              example:
                code: 500
                message: Invalid request
                body: null
      security:
        - bearerAuth: []
      externalDocs:
        description: Source reference for this endpoint
        url: https://miyaip.com/developer-center?endpoint=short-generate
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl -X POST 'https://miyaip.com/api/UserShort/GenerateIps' \
              -H 'Accept: application/json' \
              -H 'Authorization: Bearer <YOUR_TOKEN>' \
              -H 'Content-Type: application/json' \
              --data '{
              "CountryCode": "US",
              "StateCode": "CA",
              "Count": 1
            }'
        - lang: javascript
          label: JavaScript
          source: |-
            const url = 'https://miyaip.com/api/UserShort/GenerateIps';

            const response = await fetch(url, {
              method: 'POST',
              headers: {
                "Accept": "application/json",
                "Authorization": "Bearer <YOUR_TOKEN>",
                "Content-Type": "application/json"
              },
              body: JSON.stringify({
                "CountryCode": "US",
                "StateCode": "CA",
                "Count": 1
              }),
            });

            const result = await response.text();
            console.log(result);
        - lang: python
          label: Python
          source: >-
            import requests


            url = "https://miyaip.com/api/UserShort/GenerateIps"

            headers = {
              "Accept": "application/json",
              "Authorization": "Bearer <YOUR_TOKEN>"
            }

            payload = {
              "CountryCode": "US",
              "StateCode": "CA",
              "Count": 1
            }


            response = requests.post(url, headers=headers, json=payload,
            timeout=30)

            response.raise_for_status()

            print(response.text)
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Use token from the login response in the Authorization: Bearer <token>
        header. The source does not specify token lifetime or refresh behavior.

````

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