跳到主要内容
NextProxyNextProxy文档

提取接口

用 API Key 换取一批免密的 ip:port,全部参数、响应格式、错误码与频率限制。

提取接口把"地区 + 会话配置"提前固定好,换出一批 ip:port。这些端口通过来源 IP 白名单授权,客户端接入时不需要用户名密码。

GET/api/v1/proxy/extract

认证条件(四条同时满足)

API Key 放在查询字符串里,不是请求头。它属于单个代理账号,一个账号恰好一个 Key,在控制台的代理账号页可以看到明文值。

参数

代理账号的 API Key,长度 20–128。放在查询字符串里。

要提取的数量,范围 1–100。

响应格式,txt 或 json。

txt 格式下的分隔符,只接受三种字面值:\n、\r\n、,。

注意:即使 type=json,这个参数也会先被校验。传了非法值同样返回 400。

两位大写 ISO 国家码。服务端强制校验长度为 2 且字符在 A-Z 范围内。

州 / 省名称,最长 100 字符。

兼容行为:country 为空且 region 恰好是 2 个字符时,region 会被当作国家码使用。

城市名称,最长 100 字符。

会话模式,sticky 或 rotating。

出口粘性会话时长,单位分钟,范围 1–120。同时也是这批端口的有效期,见下文「端口的存活时间」。

  • session=sticky 时必填
  • session=rotating 时必须省略,传了会返回 400

请求示例

shell
curl 'https://api.example.com/api/v1/proxy/extract?apikey=YOUR_KEY&num=5&type=json&country=US&region=California&city=Los%20Angeles&session=sticky&time=10'

轮换模式(不带 time):

shell
curl 'https://api.example.com/api/v1/proxy/extract?apikey=YOUR_KEY&num=10&type=txt&country=DE&session=rotating'

响应格式

txt(默认)

text
1.2.3.4:20001
1.2.3.4:20002
1.2.3.4:20003

换分隔符:

shell
# 逗号分隔
curl '.../extract?apikey=KEY&num=3&format=,'
# → 1.2.3.4:20001,1.2.3.4:20002,1.2.3.4:20003

json

json
{
  "code": 0,
  "data": [
    { "ip": "1.2.3.4", "port": 20001, "expires_at": "2026-10-12T10:00:00.000Z" },
    { "ip": "1.2.3.4", "port": 20002, "expires_at": "2026-10-12T10:00:00.000Z" }
  ]
}

expires_at 是该端口的到期时间(UTC),含义见下文「端口的存活时间」。

直接用

shell
# 免密,不带任何凭据
curl -x http://1.2.3.4:20001 https://api.ipify.org

SOCKS5 也在同一个端口上(no-auth 方式):

shell
curl -x socks5h://1.2.3.4:20001 https://api.ipify.org

端口的存活时间

每次提取得到的是一批端口租约,规则按会话模式区分:

会话模式再次提取端口有效期
sticky每次都返回一批新端口,之前提取的端口不受影响、继续可用从提取时刻起 time 分钟,与出口粘性会话同时到期
rotating同一组「来源 IP + 地区配置」返回同一批端口每次提取顺延 7 天;连续 7 天没有再提取才回收

所以"提取一批 → 再提取下一批 → 前一批继续用"是正常用法:每批端口各自对应独立的出口会话,互不影响。

除到期外,端口在这些情况下也会被删除:

  • API Key 被撤销
  • 对应的白名单条目被删除
  • 白名单条目因连续 10 天未使用被维护任务自动清理
  • 提供该端口的网关节点不健康 —— 下次提取时旧绑定会被删除并重新分配
  • 代理账号或 API Key 记录被删除

端口范围

端口范围由每个网关节点自己注册,不是固定常量。注册时的约束:

  • 起始端口 ≥ 1024
  • 结束端口 ≤ 65535
  • 单节点端口跨度 ≤ 4096

所以不要在防火墙规则里写死端口段,按接口实际返回的值配置。

频率限制

每分钟 120 次,并且分别对来源 IP 和 API Key 计数——任意一边超限就返回 429,响应带 Retry-After: 60。

全部错误响应

状态码错误码含义
400invalid_proxy_extract_timetime 非整数、不在 1–120;sticky 缺 time;rotating 却传了 time
400invalid_proxy_extract_countnum 非整数或不在 1–100
400invalid_proxy_extract_typetype 不是 txt / json
400invalid_proxy_extract_formatformat 不是 \n / \r\n / ,
400invalid_proxy_extract_sessionsession 不是 sticky / rotating
401proxy_api_key_invalidKey 格式或状态无效;账号/用户不可用或已过期
403proxy_source_not_whitelisted来源 IP 不在白名单里
422proxy_api_invalid所选国家、州省、城市或会话参数组合不可用
429proxy_extract_rate_limited每 IP 或每 Key 超过 120/min,带 Retry-After: 60
429proxy_extract_lease_limit账号同时有效的提取端口已达 2000 个,等之前的批次到期后再提取
502client_ip_unavailable无法确定调用方的公开 IPv4
503proxy_gateway_unavailable没有健康网关;绑定未确认;端口耗尽。带 Retry-After: 2
500internal_error限流存储或其他内部错误

一个可用的封装

python
import time
from dataclasses import dataclass

import requests

API = "https://api.example.com/api/v1/proxy/extract"


@dataclass
class ExtractError(Exception):
    status: int
    code: str
    message: str


def extract(
    api_key: str,
    *,
    count: int = 10,
    country: str | None = None,
    region: str | None = None,
    city: str | None = None,
    sticky_minutes: int | None = 10,
    attempts: int = 3,
) -> list[str]:
    """提取一批免密代理,返回 http://ip:port 列表。"""
    params: dict[str, object] = {
        "apikey": api_key,
        "num": count,
        "type": "json",
    }
    if country:
        params["country"] = country
    if region:
        params["region"] = region
    if city:
        params["city"] = city

    # sticky 必须带 time,rotating 必须不带
    if sticky_minutes is None:
        params["session"] = "rotating"
    else:
        params["session"] = "sticky"
        params["time"] = sticky_minutes

    for attempt in range(attempts):
        response = requests.get(API, params=params, timeout=15)

        if response.status_code == 200:
            return [
                f"http://{item['ip']}:{item['port']}"
                for item in response.json()["data"]
            ]

        # 429 和 503 都给了 Retry-After,照它等
        if response.status_code in (429, 503) and attempt < attempts - 1:
            time.sleep(int(response.headers.get("Retry-After", "2")))
            continue

        error = response.json().get("error", {})
        raise ExtractError(
            status=response.status_code,
            code=error.get("code", "unknown"),
            message=error.get("message", response.text[:200]),
        )

    raise ExtractError(status=503, code="exhausted", message="重试次数用尽")


pool = extract("YOUR_API_KEY", count=5, country="US", sticky_minutes=10)
print(pool)

什么时候不该用提取接口

场景用什么
出口 IP 会变(家宽、容器、多云)用户名参数接 58971,见 快速开始
需要按运营商(ASN)定位用户名参数,提取接口不支持
每个请求都要不同的地区用户名参数,地区能按请求变
高频换 IP用户名参数 + 新连接,别打提取接口的 120/min

这篇解决你的问题了吗?