> ## 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 unlimited residential API: generate proxy details

> Generate MiyaIP unlimited residential proxy details with Crc and KeyName, and choose the location, gateway, session, and text output format.

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 connection details for your unlimited residential product. Use that product's `Crc` and `unlimitedKey` credentials from your dashboard.

## Prepare the connection list

1. Fill in `Crc` and `KeyName` with the unlimited product credentials. A login token or dynamic product key does not replace them.
2. Select supported location and gateway values, then choose the quantity, output format, and session parameters.
3. Send the request. Check the HTTP status and read a successful response as a plain-text proxy list before configuring your client.

`SessionTime=0` selects rotation on each request, and `SessionTime=-1` is the documented manual-rotation value. The source does not specify positive session-time units or a complete supported range. Use the current product settings to confirm availability before calling.

Form bounds reflect the current public interface. Example country and gateway values do not define every available option.

See the [unlimited residential quick start](/proxy/unlimited-residential/quick-start) for dashboard setup and the [API overview](/api-reference/overview) for response handling.

## Online debugging

<MiyaApiPlayground specUrl="/api-reference/openapi.en.json" method="GET" path="/api/ProxyLogic/UnlimitedGenerate" locale="en" key="en:unlimited-generate" />

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


## OpenAPI

````yaml api-reference/openapi.en.json GET /api/ProxyLogic/UnlimitedGenerate
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/ProxyLogic/UnlimitedGenerate:
    get:
      tags:
        - proxy-generation
      summary: Generate unlimited proxies
      description: >-
        Generate proxy credentials for an active unlimited-traffic key.


        Crc and KeyName are query credentials. KeyName must reference an active
        unlimited key.
      operationId: unlimited-generate
      parameters:
        - name: Num
          in: query
          required: true
          description: Number of proxy lines to return.
          schema:
            type: integer
            example: 1
        - name: Country
          in: query
          required: false
          description: Optional country code.
          schema:
            type: string
            example: US
        - name: State
          in: query
          required: false
          description: Optional state or province.
          schema:
            type: string
        - name: City
          in: query
          required: false
          description: Optional city.
          schema:
            type: string
        - name: SessionTime
          in: query
          required: true
          description: 0 rotates each request; -1 enables manual switching.
          schema:
            type: integer
            example: -1
        - name: Server
          in: query
          required: true
          description: Gateway node, such as as, us, or eu.
          schema:
            type: string
            example: us
        - name: Format
          in: query
          required: true
          description: Controls the returned proxy credential layout.
          schema:
            type: string
            enum:
              - '0'
              - '1'
              - '2'
            example: '0'
        - name: Crc
          in: query
          required: true
          description: Password value associated with the proxy account.
          schema:
            type: string
            format: password
        - name: KeyName
          in: query
          required: true
          description: An active unlimitedKey value.
          schema:
            type: string
            format: password
      responses:
        '200':
          description: Generated proxy lines
          content:
            text/plain:
              schema:
                type: string
              example: unlimited.miyaip.com:20000:username-zone-us:********
        '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:
        - proxyCrc: []
          proxyKey: []
      externalDocs:
        description: Source reference for this endpoint
        url: https://miyaip.com/developer-center?endpoint=unlimited-generate
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --get 'https://miyaip.com/api/ProxyLogic/UnlimitedGenerate' \
              -H 'Accept: text/plain' \
              --data-urlencode 'Num=1' \
              --data-urlencode 'Country=US' \
              --data-urlencode 'SessionTime=-1' \
              --data-urlencode 'Server=us' \
              --data-urlencode 'Format=0' \
              --data-urlencode 'Crc=<YOUR_PASSWORD>' \
              --data-urlencode 'KeyName=<YOUR_UNLIMITED_KEY>'
        - lang: javascript
          label: JavaScript
          source: >-
            const params = new URLSearchParams({
              "Num": "1",
              "Country": "US",
              "SessionTime": "-1",
              "Server": "us",
              "Format": "0",
              "Crc": "<YOUR_PASSWORD>",
              "KeyName": "<YOUR_UNLIMITED_KEY>"
            });

            const url =
            `https://miyaip.com/api/ProxyLogic/UnlimitedGenerate?${params}`;


            const response = await fetch(url, {
              method: 'GET',
              headers: {
                "Accept": "text/plain"
              },
            });


            const result = await response.text();

            console.log(result);
        - lang: python
          label: Python
          source: >-
            import requests


            url = "https://miyaip.com/api/ProxyLogic/UnlimitedGenerate"

            headers = {
              "Accept": "text/plain"
            }

            params = {
              "Num": 1,
              "Country": "US",
              "SessionTime": -1,
              "Server": "us",
              "Format": "0",
              "Crc": "<YOUR_PASSWORD>",
              "KeyName": "<YOUR_UNLIMITED_KEY>"
            }


            response = requests.get(url, headers=headers, params=params,
            timeout=30)

            response.raise_for_status()

            print(response.text)
components:
  securitySchemes:
    proxyCrc:
      type: apiKey
      in: query
      name: Crc
      description: >-
        Proxy-account password value; a sensitive credential in the query
        string.
    proxyKey:
      type: apiKey
      in: query
      name: KeyName
      description: Main key for the selected product; supply it together with Crc.

````

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