跳到主要内容
NextProxyNextProxy文档

提取接口

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

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

GET/api/v1/proxy/extract

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

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

参数

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

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

响应格式,txtjson

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

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

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

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

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

城市名称,最长 100 字符。

会话模式,stickyrotating

出口粘性会话时长,单位分钟,范围 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 },
    { "ip": "1.2.3.4", "port": 20002 }
  ]
}

直接用

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

端口的存活时间

端口绑定在这些情况下被删除:

  • 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
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

这篇解决你的问题了吗?