文档菜单

令牌API

所有代理令牌:列表、读取、一个或多个令牌的用量,以及按流量计费代理的创建、更改、重新签发凭证和删除。位置可更改的不限流量令牌还支持位置、轮换,以及按需获取新IP。

列表与读取#

GET /api/v1/tokens
Authorization: Bearer lit_...
参数 类型 规则
limit integer 整数1-100;默认50。
cursor string 上一页的page.nextCursor,原样传回。
type string unlimited或ppg。
status string active、expired或disabled。
packageId integer 账户所拥有套餐的公开数字ID。未知或属于他人的值会返回空列表。格式错误的值会返回INVALID_PACKAGE_ID。

结果按最新优先排序。持续请求返回的page.nextCursor,直到它为null。

GET /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...

返回一个令牌,其结构与GET /tokens列表元素完全相同,包括其username和password。未知、不属于您或无法解析的tokenId会返回404 TOKEN_NOT_FOUND;响应绝不会透露其他用户的令牌。

示例#

一个不限流量数据中心令牌,所属套餐带有IP白名单,令牌本身的位置可更改:

{
  "id": 12345,
  "type": "unlimited",
  "status": "active",
  "disabledReason": null,
  "label": "Production crawler",
  "externalRef": null,
  "createdAt": "2026-08-01T10:15:00.000Z",
  "expiresAt": "2026-12-01T00:00:00.000Z",
  "allowanceBytes": null,
  "allowanceReservedBytes": null,
  "ingress": {
    "hub": "us-11",
    "protocol": "http",
    "mode": "assigned",
    "host": "hub-us-11-1.litport.net",
    "port": 31337,
    "status": "available"
  },
  "packageId": 45,
  "ipAuth": { "host": "hub-us-11-1.litport.net", "port": 31338 },
  "location": { "country": "us", "region": "new-york", "city": "new-york-city" },
  "rotation": { "intervalSec": 600, "options": [600, 1800, 3600], "changeable": true },
  "username": "proxy-username",
  "password": "proxy-password"
}

锁定为一个代理池、带有引用、到期时间和流量上限的按流量计费令牌:

{
  "id": 12399,
  "type": "ppg",
  "status": "active",
  "disabledReason": null,
  "label": "Residential crawler",
  "externalRef": "customer-1042",
  "createdAt": "2026-08-01T10:15:00.000Z",
  "expiresAt": "2026-12-31T23:59:59.999Z",
  "allowanceBytes": 5000000000,
  "allowanceReservedBytes": 1200000000,
  "ingress": {
    "hub": "example-hub",
    "protocol": "http",
    "mode": "request-selected",
    "supportedProtocols": ["http", "https", "socks5"]
  },
  "poolSelection": {
    "mode": "fixed",
    "pool": { "authKey": "residential-main", "name": "Residential Main" }
  },
  "packageId": null,
  "ipAuth": null,
  "username": "proxy-username",
  "password": "proxy-password"
}

本文档中的示例标识符和节点均为示意。

字段含义#

type为ppg或unlimited。status为active、expired或disabled。它绝不会是hub-unavailable;该值属于下文的ingress.status。

disabledReason说明令牌为何不处理流量。status为active时它为null。

status disabledReason 含义
disabled owner 被您关闭(enabled: false),或者对套餐的令牌来说,被其套餐关闭。
disabled ban 因账户被封禁而关闭。
expired expired 已超过expiresAt。
disabled allowance 已开启,但其流量上限已全部用完。提高或移除上限即可再次启动。
disabled balance 已开启,但账户余额不足以支付。充值后即可再次使用。

GET /tokens上的status筛选只按令牌自身的开关和到期时间选择。它找不到因allowance或balance而处于disabled的令牌,所以请在结果中读取disabledReason。

externalRef是您为按流量计费代理设置的自有引用,没有时为null。expiresAt是令牌停止的时间,没有时为null。allowanceBytes是以字节为单位的流量上限,无上限时为null;allowanceReservedBytes是迄今已预留的上限额度,无上限时为null。

对于PPG令牌,ingress.mode为request-selected:没有单一的主机或端口,因为节点、协议和代理池是按每次请求或导出选择的。ingress.hub和ingress.protocol是控制台和导出的偏好设置,ingress.supportedProtocols列出可选项。主机取自代理池的hubs,端口取自其httpPort/socks5Port,见按流量计费。

对于不限流量令牌,ingress.mode为assigned:令牌只对应一个端点,始终以ingress.host和ingress.port给出。ingress.status为available或hub-unavailable。hub-unavailable表示令牌指定的节点已停止服务:此时ingress.host和ingress.port为null,在客服将令牌迁移到当前节点之前,凭证无法使用。

当令牌属于您拥有的套餐时,packageId是公开的数字套餐ID,否则为null;用套餐读取该套餐。ipAuth是{host, port},即令牌的免密码端点,如果令牌当前没有,则为null。它只接受来自该套餐IP白名单的连接。

location只出现在位置可更改的令牌上;哪些令牌符合条件,见位置。其结构取决于类型:数据中心或ISP令牌报告{country, region, city};移动令牌报告{country, city, carrier}。

rotation是{intervalSec, options, changeable},出现在每个按计时器轮换的令牌上。见轮换。

rotateUrl是独享设备或动态数据中心/ISP令牌的更换IP链接,仅在令牌有该链接时出现。请像保护旁边的密码一样保护它。详见下文的更换IP链接;获取新IP的各种方式见更换IP。

username和password是该令牌的代理凭证。与ingress或控制台中显示的端点配合使用。

如果账户开启了使用中性地址,此API返回的主机名(ingress.host、ipAuth.host)、代理池的authKey和rotateUrl链接都使用中性名称。您发送的代理池名称两种形式都可接受。对于HTTPS代理,请使用ingress.httpsHost(http协议上的不限流量令牌):证书是为该名称签发的。它是节点自己的名称,除非账户使用中性地址,否则与ingress.host相同。对于按流量计费的令牌,请从代理池的hubs中获取httpsHostname。

创建和管理代理#

按流量计费的代理可以通过API创建、更改和删除,您拥有的任何代理的凭证都可以重新签发。控制台中的按流量计费代理表单遵循相同的规则。这里的每个调用都需要Bearer API密钥,写入计入该密钥每60秒120次请求的限制。

套餐的代理属于其套餐,由套餐创建、结束,并由套餐启用和停用。对它们只能更改标签和重新签发凭证,其他都不行。

所有账户都允许转售。您需要对客户如何使用其代理负责:其中一个客户的滥用可能导致您的整个账户被封禁。

创建代理#

POST /api/v1/tokens
Authorization: Bearer lit_...
Content-Type: application/json

发送一个JSON对象,至少是{}。没有请求体的请求不会创建任何东西。

字段 规则
pool 可选。来自按流量计费的代理池authKey。省略它或发送null,则代理按每次请求选择代理池。您无法选择的代理池返回400 INVALID_POOL。
label 可选。最多255个字符。
externalRef 可选,建议始终发送。1到128个可打印字符,在您现有的代理中唯一。
expiresAt 可选。带时区的ISO 8601日期时间,例如2026-12-31T10:00:00Z,或日期,例如2026-12-31,表示当天结束(UTC)。必须晚于当前时间。代理在该时间停止。
allowanceBytes 可选。以字节为单位的流量上限,不小于1的整数。
curl -X POST 'https://litport.net/api/v1/tokens' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"pool": "residential-main", "label": "Residential crawler", "externalRef": "customer-1042", "expiresAt": "2026-12-31", "allowanceBytes": 5000000000}'

响应为201,以及示例中所示结构的代理,其中包含username和password。请按按流量计费代理参数中的说明,用它们组成代理用户名。

请始终发送externalRef。它是您自己的引用,例如客户ID或订单号。重复使用了您已有的externalRef的创建请求会返回200和那个代理,不做任何更改,即使请求体的其余部分不同。因此,如果创建超时,或您没有收到响应,用同一个externalRef再次发送,就会得到已存在的代理。没有externalRef时,重复发送可能创建出第二个代理。已删除的代理会释放其externalRef,所以可以再次使用。

创建需要正数余额(INSUFFICIENT_BALANCE)和未被封禁的账户(ACCOUNT_BANNED)。一个账户可持有的按流量计费代理数量有限(TOKEN_LIMIT_REACHED);如需提高,请联系客服。

一个账户每分钟可创建60个新代理,其所有API密钥和控制台合并计算。重复使用已有的externalRef不计入。超过限制后,创建请求会返回429 RATE_LIMITED及Retry-After,且不会创建任何代理:等待结束后再次发送同一请求。

更改代理#

PATCH /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...
Content-Type: application/json

只发送您要更改的字段,且至少一个。省略的字段保持不变。null可清除label、pool、expiresAt和allowanceBytes。

字段 规则
label 最多255个字符,或null。
enabled false关闭代理,true开启代理。开启需要正数余额和未被封禁的账户。
pool 代理池的authKey,或null(代理按每次请求选择代理池)。通过IP白名单登录的代理保留其代理池:null返回409 POOL_REQUIRED_FOR_IP_AUTH。
expiresAt 晚于当前时间的日期时间或日期(同创建),或null表示不设到期时间。
allowanceBytes 以字节为单位的流量上限,不小于1的整数,或null表示移除。

响应为200,以及代理当前的状态。不改变任何内容的请求体不会写入任何内容。新的代理池应用于新连接;已打开的连接保持其开始时使用的代理池,并按该代理池的价格计费。

关闭、更改标签、更改到期时间或上限始终可用,即使余额为空,所以您随时可以切断某个客户。重新签发凭证和删除同样如此。对套餐的代理来说,label是唯一的字段;其他任何字段都返回400 FIELD_NOT_ALLOWED。

重新签发凭证#

POST /api/v1/tokens/{tokenId}/credentials
Authorization: Bearer lit_...
Content-Type: application/json

{"requestId": "reissue-2026-11-04-a"}

为您拥有的任何代理(按流量计费或套餐的)签发新的用户名、密码和更换IP密钥。响应为200,以及示例中所示结构的代理,其中包含新的username和password,代理有更换IP链接时还包含新的rotateUrl。请求体可选。

  • 旧密码停止生效,其已打开的连接会关闭。
  • 旧的更换IP链接停止生效。
  • 套餐的IP白名单继续生效,其连接保持打开。IP白名单属于整个套餐,而不是某一个代理,所以重新签发一个代理的凭证无法切断从白名单IP连接的客户。请只用密码在多个客户之间共用套餐。

requestId为1到64个字符:字母、数字、下划线或连字符。每次想要重新签发时都使用新的requestId。只有在重试一个没有收到响应的调用时才发送同一个:重复请求会返回第一次调用签发的凭证,不会再签发新的,无论第一次调用已经完成还是仍在进行。没有requestId时,每次调用都会签发一组新的凭证,所以不要盲目重复。

删除代理#

DELETE /api/v1/tokens/{tokenId}
Authorization: Bearer lit_...

删除一个按流量计费的代理。响应为204,没有响应体。代理停止工作,其已打开的连接会关闭。它的历史记录会保留:多个令牌的用量仍会列出它,并标记为deleted,GET /tokens/{tokenId}/usage仍会返回它的用量。GET /tokens和GET /tokens/{tokenId}不再返回它。再次删除已删除的代理,仍返回204。

套餐的代理不能删除:409 NOT_SUPPORTED。它随其套餐一起结束。

流量上限#

按流量计费的代理可以有流量上限allowanceBytes:它最多可使用的流量,以字节为单位(1 GB为1,000,000,000字节)。用它给每位客户、团队成员或工具分配固定的额度。上限是可选的。在控制台中,它是代理的**流量上限(GB)**字段。

  • 计入什么。客户端与节点之间双向的全部流量,包含协议开销。因此上限绝不会小于用量中计费的流量:代理计费的流量绝不会超过其上限。
  • 在哪里停止。代理可能在达到上限之前略早停止,但绝不会超出。Litport会在使用之前为代理预留流量,未用完的部分不会退回。
  • allowanceReservedBytes。迄今已预留的上限额度。它与计费的用量不是同一个数字:它可能领先于已交付的流量,而且绝不会从您被计费的金额中扣除。请从用量中读取计费的流量。
  • 计费不变。上限只会拒绝流量。
  • 用完时。status为disabled,disabledReason为allowance,新连接会收到代理错误24(HTTP 403)。提高或移除上限即可再次使用该代理。
  • 更改上限。添加、提高、降低或移除上限会让代理已打开的连接结束一次;客户端会按新的上限重新连接。上限降到低于已预留额度时,代理会在已预留的流量用完后立即停止。不会退回任何内容。

代理写入错误#

状态码 错误码 含义
400 INVALID_REQUEST_BODY 请求体不是JSON对象,包含该调用不接受的字段,或(PATCH)一个字段也没有。
400 FIELD_NOT_ALLOWED PATCH向套餐的代理发送了label以外的字段。
400 INVALID_LABEL, INVALID_EXTERNAL_REF, INVALID_REQUEST_ID, INVALID_ENABLED, INVALID_EXPIRY, INVALID_ALLOWANCE 所指字段超出范围或类型错误。
400 INVALID_POOL pool不是您可以选择的代理池。
402 INSUFFICIENT_BALANCE 创建或开启需要正数余额。
403 ACCOUNT_BANNED 账户被封禁期间,不能创建或开启。
404 TOKEN_NOT_FOUND tokenId未知、不属于您或格式错误。
409 NOT_SUPPORTED 对套餐的代理执行DELETE。
409 TOKEN_LIMIT_REACHED 账户已持有允许的最大数量的按流量计费代理。
409 ALLOWANCE_CONFLICT 上限未能保存。请再次发送同一请求。
409 POOL_REQUIRED_FOR_IP_AUTH 通过IP白名单登录的代理不能去掉其代理池。
409 TOKEN_NOT_EDITABLE 该代理已无法再编辑,例如因为写入进行期间它被删除了。未发生任何更改。
409 CONCURRENT_CHANGE 对此代理的另一次写入恰好在同一时刻生效。请再次发送同一请求。
429 RATE_LIMITED 创建时:最近一分钟内新建的代理超过了账户的限制(或超过了密钥的请求限制)。未创建任何代理。请等待Retry-After,然后再次发送同一请求。

每个错误码在API错误中都有对应的标题。

用量#

读取一个自有令牌中客户可见的流量。

GET /api/v1/tokens/{tokenId}/usage
Authorization: Bearer lit_...

查询参数#

参数 规则
from 含该时刻的规范UTC ISO-8601时间戳。
to 不含该时刻的规范UTC ISO-8601时间戳;必须晚于from。
groupBy hour、day或month;默认为day。
include 以逗号分隔的domains和/或charges。charges要求groupBy=hour。

省略时间范围时,API使用当前UTC日之前的30个完整UTC日。按小时的范围上限为31天,按天的范围上限为366天,按月的范围上限为36个月。

示例#

curl --get 'https://litport.net/api/v1/tokens/12345/usage' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  --data-urlencode 'from=2026-08-01T00:00:00Z' \
  --data-urlencode 'to=2026-08-03T00:00:00Z' \
  --data-urlencode 'groupBy=day'
{
  "data": {
    "tokenId": 12345,
    "deleted": false,
    "range": {
      "from": "2026-08-01T00:00:00.000Z",
      "to": "2026-08-03T00:00:00.000Z",
      "groupBy": "day",
      "timezone": "UTC"
    },
    "trafficBasis": "customer_chargeable",
    "summary": {
      "requests": 42,
      "uploadedBytes": "12000",
      "downloadedBytes": "88000",
      "totalBytes": "100000",
      "cache": {
        "hits": 12,
        "misses": 4,
        "bypasses": 2,
        "hitRate": 0.75,
        "freeUploadedBytes": "0",
        "freeDownloadedBytes": "24000",
        "freeTotalBytes": "24000",
        "savedCostUnits": "0.0324"
      }
    },
    "buckets": [
      {
        "start": "2026-08-01T00:00:00.000Z",
        "end": "2026-08-02T00:00:00.000Z",
        "requests": 42,
        "uploadedBytes": "12000",
        "downloadedBytes": "88000",
        "totalBytes": "100000",
        "cache": {
          "hits": 12,
          "misses": 4,
          "bypasses": 2,
          "hitRate": 0.75,
          "freeUploadedBytes": "0",
          "freeDownloadedBytes": "24000",
          "freeTotalBytes": "24000",
          "savedCostUnits": "0.0324"
        }
      }
    ]
  }
}

用量语义#

区间是半开的:[from, to)。时间桶按开始时间排序且是稀疏的;缺少某个时间桶表示没有已存储的聚合行,而不是API错误。

对于PPG令牌,trafficBasis为customer_chargeable,因此流量总计与向客户显示的流量一致。对于固定价格/不限流量令牌,它为observed;这些既有的流量总计仍以观测到的传输量为基准。较大的字节总数以十进制字符串给出,以便客户端保留精确值。requests是JSON整数。

缓存收益#

每个时间桶和汇总都包含cache。hits、misses和bypasses是JSON整数;hitRate为hits / (hits + misses),在没有命中也没有未命中时为0。freeUploadedBytes、freeDownloadedBytes和freeTotalBytes是非负的十进制字符串,其中freeTotalBytes等于两个方向的值相加。没有缓存遥测数据的历史时段,这些字段报告为零。

仅对PPG令牌,cache.savedCostUnits是一个非负的十进制字符串,表示按流量产生时的有效价格计算、经审计的已避免费用。不限流量令牌会刻意省略该字段,而不是设为0或null,因为没有避免任何按GB计费的客户费用。

令牌必须属于已认证的用户。未知或不属于您的令牌返回相同的404 TOKEN_NOT_FOUND响应。已删除的令牌仍会响应,并带有deleted: true,这样代理删除后仍可读取客户的最后一笔账单。

费用明细#

对于PPG令牌,请求include=charges&groupBy=hour,可在每个小时时间桶中加入已持久化的费用记录。不限流量令牌会拒绝该扩展。带版本的费用记录包含代理池的公开标识和名称、原始及计费的上传/下载字节数、参与的节点和协议、快照的基础/有效费率和折扣,以及实际扣除的确切金额。没有快照的行标记为Legacy PPG usage;API不会根据当前令牌设置来猜测其代理池或费率。

费用明细即计费记录。上传和下载都计费。reserved状态的费用可能会随该小时的延迟流量到达而增加;finished状态的费用是最终的。

域名明细#

请求include=domains,可在data中加入domainBreakdown:

{
  "domainBreakdown": {
    "limit": 150,
    "totalDestinationCount": 151,
    "displayedCount": 150,
    "truncated": true,
    "range": {
      "from": "2026-08-01T00:00:00.000Z",
      "to": "2026-08-03T00:00:00.000Z",
      "timezone": "UTC",
      "periodClamped": false,
      "endClamped": false
    },
    "items": [{
      "protocol": "tcp",
      "destination": "example.com",
      "port": 443,
      "requests": 42,
      "uploadedBytes": "12000",
      "downloadedBytes": "88000",
      "totalBytes": "100000",
      "lastSeenAt": "2026-08-01T12:00:00.000Z",
      "firstSeenAt": "2026-08-01T00:00:00.000Z"
    }],
    "other": {
      "protocol": null,
      "destination": "Other",
      "port": null,
      "requests": 1,
      "uploadedBytes": "1",
      "downloadedBytes": "2",
      "totalBytes": "3",
      "lastSeenAt": null,
      "firstSeenAt": null
    }
  }
}

响应最多包含总流量最高的150个目标地址。其余所有目标地址和遥测溢出都合并到other中;发生这种合并时,truncated会予以报告。TCP的requests是成功请求数,UDP的requests是入站数据报。域名数据按整小时UTC时间桶存储,且仅限所请求区间中最近的31天。返回的UTCrange是实际生效的时间桶区间:过去的不完整起点向下取整到所在小时,过去的不完整终点向上取整到下一个小时。被限制为当前时间的终点仍保持为该确切时间,因此响应不会声称覆盖了当前时间之后。区间被调整时,还会报告periodClamped或endClamped。

多个令牌的用量#

一次调用读取多个代理的用量,按天统计。已删除的代理也包含在内,这样您可以结算已离开的客户的最后一笔账单。

GET /api/v1/usage
Authorization: Bearer lit_...

用量列表参数#

参数 规则
from 含该时刻的规范UTC ISO-8601时间戳。
to 不含该时刻的规范UTC ISO-8601时间戳;必须晚于from。
tokenIds 代理ID,以逗号分隔或作为重复参数,最多100个。省略则包含所有代理。不属于您的ID会被跳过。格式错误的列表返回400 INVALID_TOKEN_IDS。
limit 1–100的整数;默认50。一页中的代理数量。
cursor 上一页的page.nextCursor,原样传回。

省略时间范围时,API使用当前UTC日之前的30个完整UTC日。时间范围上限为92天(超出则返回400 INVALID_TIME_RANGE);更长的时间段请分多次调用读取。此调用限制为每个API密钥每60秒10次请求(429 RATE_LIMITED),RateLimit-*和Retry-After响应头报告的就是这项限制。

用量列表示例#

curl --get 'https://litport.net/api/v1/usage' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  --data-urlencode 'from=2026-10-01T00:00:00Z' \
  --data-urlencode 'to=2026-10-03T00:00:00Z' \
  --data-urlencode 'tokenIds=12399,12400'
{
  "data": {
    "range": {
      "from": "2026-10-01T00:00:00.000Z",
      "to": "2026-10-03T00:00:00.000Z",
      "groupBy": "day",
      "timezone": "UTC"
    },
    "tokens": [
      {
        "tokenId": 12399,
        "type": "ppg",
        "deleted": false,
        "label": "Residential crawler",
        "externalRef": "customer-1042",
        "trafficBasis": "customer_chargeable",
        "summary": {
          "requests": 42,
          "uploadedBytes": "12000",
          "downloadedBytes": "88000",
          "totalBytes": "100000",
          "costUnits": "0.00045"
        },
        "buckets": [
          {
            "start": "2026-10-01T00:00:00.000Z",
            "end": "2026-10-02T00:00:00.000Z",
            "requests": 42,
            "uploadedBytes": "12000",
            "downloadedBytes": "88000",
            "totalBytes": "100000",
            "costUnits": "0.00045"
          }
        ]
      },
      {
        "tokenId": 12400,
        "type": "ppg",
        "deleted": true,
        "label": null,
        "externalRef": "customer-0977",
        "trafficBasis": "customer_chargeable",
        "summary": {
          "requests": 0,
          "uploadedBytes": "0",
          "downloadedBytes": "0",
          "totalBytes": "0",
          "costUnits": "0"
        },
        "buckets": []
      }
    ]
  },
  "page": { "nextCursor": null }
}

用量列表语义#

一页最多包含limit个代理,最新的在前,每个代理带有该范围的summary,以及每个有流量的UTC日对应一个时间桶。区间是半开的,[from, to),时间桶是稀疏的,与单个令牌相同。持续请求page.nextCursor直到其为null;一页包含的代理数量可能少于limit,因为没有用量的已删除代理会被省略。

这里绝不会出现凭证。trafficBasis、字节字符串和requests的含义与单个令牌相同。此列表不含缓存收益、域名明细或按小时的费用;这些请通过GET /tokens/{tokenId}/usage读取。

costUnits是已扣费金额,以余额单位表示的十进制字符串。按流量计费的代理在每一天和其summary中都带有它;某一天有流量但尚未记录扣费时,该时间桶的costUnits为null,仍在进行中的当前小时的扣费可能变化。套餐的代理不按GB计费,因此该值为null。

已删除的代理以deleted: true和它们当时的externalRef列出。范围内没有用量的已删除代理,只有在您于tokenIds中指明它时才会出现。现存的按流量计费代理始终会出现。套餐的代理会出现,除非它在from之前已过期。

位置#

数据中心或ISP令牌,以及城市或运营商可更改的移动令牌,会报告location字段并支持此API。哪些令牌符合条件,以及更改的行为如下:

令牌 更改方式 等待时间
数据中心/ISP,动态 随时 无
数据中心/ISP,静态 所选位置的新IP 每周一次
数据中心/ISP,静态,不在其已保存的位置 移回已保存的位置 无
多地点移动代理(付费附加项) 随时 无
标准美国共享设备 城市和运营商一起 每48小时一次
其他所有(PPG、独享设备、非美国移动代理、1天套餐,或没有端口类型的旧令牌) 不支持 无
GET /api/v1/tokens/{tokenId}/location
Authorization: Bearer lit_...
{
  "data": {
    "tokenId": 12345,
    "kind": "datacenter",
    "mode": "rotating",
    "target": { "country": "us", "region": "new-york", "city": "new-york-city" },
    "effective": {
      "country": "us", "region": "new-york", "city": "new-york-city",
      "labels": { "region": "New York", "city": "New York City" }
    },
    "status": "ready",
    "canChangeNow": true,
    "nextChangeAt": null
  }
}

kind为datacenter、isp或mobile。mode为rotating或static。target是已保存的选择;数据中心/ISP的region/city可以是"any"。effective是令牌当前所持IP的实际位置,尚未知晓时为null。status在更改传播的短时间内为pending,传播完成后为ready,令牌的套餐未在使用中时为package-inactive,而allowance-exhausted仅用于仍有流量上限的旧版“多地点”套餐。数据中心或ISP令牌还会报告另外两个值,依据其IP当前所在的位置判断:

  • fallback:代理正在使用其已保存位置之外的IP,因为该位置没有空闲IP。动态代理会在该位置有空闲IP时自动返回。静态代理会留在原处,直到您将其移回,因为IP未经请求就变化会使其所用网站上的IP白名单失效。
  • unavailable:代理的IP当前无法使用;系统正在将其迁移到可用的IP,通常需要几分钟。

fallback是较新的值,因此依据status分支处理的客户端需要处理它。对于移动令牌,unavailable仍表示目标位置当前没有可用的设备(令牌保留其最后一个,而不会丢失路由)。

列出可用位置#

GET /api/v1/tokens/{tokenId}/location/options?level=region
GET /api/v1/tokens/{tokenId}/location/options?level=city&region=new-york

数据中心/ISP:level=region,然后是level=city&region=…。移动令牌:level=city,然后是level=carrier&city=…。每个选项为{"value": …, "label": …},列表中只包含此令牌当前可用的选项。

更改位置#

数据中心/ISP:

curl -X PUT 'https://litport.net/api/v1/tokens/12345/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"region": "new-york", "city": "new-york-city"}'

移动令牌:

curl -X PUT 'https://litport.net/api/v1/tokens/98765/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"city": "seattle", "carrier": "verizon"}'

让服务器自行选择,适用于两种类型:

curl -X PUT 'https://litport.net/api/v1/tokens/12345/location' \
  -H "Authorization: Bearer $LITPORT_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"random": true}'

按该令牌类型发送对应的字段:数据中心/ISP为region和city;移动令牌为city和carrier。country可选,发送时必须为"us"。不需要也不处理前置条件请求头:最近一次提交的PUT成为令牌期望的目标,与当前已保存目标相同的PUT会成功,且不产生新的更改。

动态数据中心/ISP令牌会立即切换到匹配的IP。静态令牌会在所选位置获得新IP,并消耗其每周一次的额度;同一周内重复更改会返回409 CHANGE_LIMIT及nextChangeAt。多地点令牌立即切换,无需等待。标准美国共享设备令牌每48小时可更改一次;在此时间窗口内重复更改同样返回409 CHANGE_LIMIT。

对于任何移动令牌,城市始终保持不变:如果所选运营商在该城市没有可用的手机,代理会改用同一城市的另一家运营商,effective显示实际使用的运营商。

{"random": true}需单独发送,不带其他字段。服务器会从列出可用位置所显示的同一批值中,选择该代理此刻可以使用的位置:有其他城市时选择不同的城市;对移动代理,如果其所在城市是唯一的,则选择同一城市的另一家运营商。它绝不会选择代理当前的target。所选位置像其他任何更改一样保存为目标,检查和等待期也相同(静态数据中心/ISP代理使用其每周一次的额度,标准美国共享移动代理使用其48小时一次的额度,CHANGE_LIMIT照常带有nextChangeAt),响应中的target显示代理去了哪里。如果所选位置没有空闲IP或可用的手机,则会尝试下一个,最多三个。如果没有其他位置,或者三个位置都无法承载该代理,则返回409 LOCATION_UNAVAILABLE,且不做任何更改。

随机更改不能盲目重复:在没有等待期的情况下,每次重复都会再次移动代理。响应丢失后,请先读取GET /tokens/{tokenId}/location,然后再次发送。

移回#

POST /api/v1/tokens/{tokenId}/location/return
Authorization: Bearer lit_...

适用于status为fallback的静态数据中心或ISP令牌:会在其已保存的位置获取一个空闲IP,主机、端口、用户名和密码不变。此操作免费:不占用每周一次的额度,已保存的target也不会改变。该请求不带请求体(接受空的{})。返回与位置相同的结构,其中带有新的effective IP。IP会变化,因此目标网站上登记了旧IP的白名单将不再匹配。

动态令牌没有这样的请求:当其已保存的位置有空闲IP时,会自动返回。其他任何令牌都会返回409 NOT_SUPPORTED。

成功后再次发送会返回409 NOT_IN_FALLBACK,且不会再给第二个IP,因此在响应丢失后可以放心地重新发送该请求。

状态码 错误码 含义
400 INVALID_REQUEST_BODY 请求带有非空的请求体。
404 TOKEN_NOT_FOUND tokenId未知、不属于您或格式错误。
409 NOT_SUPPORTED 不是静态数据中心或ISP令牌,或者没有已保存的位置。
409 PACKAGE_INACTIVE 令牌或其套餐未在使用中。
409 NOT_IN_FALLBACK 令牌并未处于其已保存位置之外(成功后的重复请求会到这里),或其IP尚无法使用。未做任何更改。
409 LOCATION_UNAVAILABLE 已保存的位置目前还没有空闲IP。未做任何更改;请稍后重试。
409 CONCURRENT_CHANGE 同一时刻对该令牌进行了另一项更改。请读取位置,仅当status仍为fallback时再重新发送请求。

位置错误#

状态码 错误码 含义
400 INVALID_REQUEST_BODY 请求体中的字段与此令牌的类型不符,random不是true,或random与其他字段一起发送。
400 INVALID_LOCATION 不是受支持的美国位置或运营商,或者对标准共享设备令牌使用了"any"。
400 INVALID_LEVEL / INVALID_PARENT 选项列表:使用了此令牌不使用的level,或缺少region/city。
404 TOKEN_NOT_FOUND tokenId未知、不属于您或格式错误。
409 NOT_SUPPORTED 此令牌的位置无法更改。
409 PACKAGE_INACTIVE 令牌或其套餐未在使用中。
409 CHANGE_LIMIT 处于每周或48小时的等待期内。错误会携带nextChangeAt和与之匹配的Retry-After。
409 LOCATION_UNAVAILABLE 该处目前没有可用的IP或可用的手机,或者(使用random时)没有其他可用位置。未做任何更改。
409 CONCURRENT_CHANGE 同一时刻对该令牌进行了另一项更改。重试同一个PUT。

轮换#

PUT /api/v1/tokens/{tokenId}/rotation
Authorization: Bearer lit_...
Content-Type: application/json

{"intervalSec": 600}
{
  "data": { "tokenId": 12345, "intervalSec": 600, "options": [600, 1800, 3600], "changeable": true }
}

intervalSec必须是options之一,即令牌自身rotation字段所列出的值。动态数据中心/ISP令牌、标准美国共享设备令牌和美国独享设备的changeable为true。独享设备的options从2分钟起。“多地点”令牌始终报告其当前手机的间隔,且changeable: false,因为代理所在的手机自行设定计时器;对它的PUT也会返回409 NOT_SUPPORTED,其他任何不轮换的令牌也是如此。

轮换错误#

状态码 错误码 含义
400 INVALID_REQUEST_BODY 请求体不是严格的{"intervalSec": <integer>}。
400 INVALID_ROTATION intervalSec不在令牌的options中。
404 TOKEN_NOT_FOUND tokenId未知、不属于您或格式错误。
409 NOT_SUPPORTED 令牌不轮换,或其间隔由手机设定(多地点)。
409 PACKAGE_INACTIVE 令牌或其套餐未在使用中。

新IP#

POST /api/v1/tokens/{tokenId}/new-ip
Authorization: Bearer lit_...

在控制台中,代理上的获取新IP按钮和令牌的更换IP链接是无需代码即可实现同样操作的方式,见更换IP。此端点仅适用于数据中心和ISP令牌。独享设备通过其更换IP链接来更换IP。该请求不带请求体。新IP保持在令牌已保存的位置内。status为fallback或unavailable的令牌(位于其位置之外,或其IP已无法使用)会在其已保存的位置获得新IP(若该位置有空闲IP),否则在同一个州,再不行则在美国任意位置。返回与位置相同的结构,其中带有新的effective IP。

静态令牌消耗其每周一次的额度。服务每次尝试(包括重试)都会重用令牌自己已保存的位置。

动态令牌可随时获得新IP。新IP始终与当前IP不同,自动计时器会重新开始:下一次自动更换在此次之后rotation.intervalSec秒进行。新连接在约5秒内使用新IP;已打开的连接保持旧IP,直到重新连接。两次请求之间至少要间隔令牌rotation.options中的最小值;在此等待期内重复请求会返回409 CHANGE_LIMIT。

对静态令牌来说,这是唯一一个不能盲目重复的写操作。如果响应丢失或超时,重试之前先读取GET /tokens/{tokenId}/location:nextChangeAt晚于当前时间,说明更改已生效。在这一周内再次发送POST不会得到第二个IP;它会返回409 CHANGE_LIMIT。

对动态令牌来说,丢失的响应无法通过GET /tokens/{tokenId}/location确认:其canChangeNow和nextChangeAt针对的是位置,与这一等待期无关。在Retry-After之后再次发送POST没有影响,只会再给一个新IP。响应丢失后立刻收到409 CHANGE_LIMIT,并不能证明更改已生效,因为409 LOCATION_UNAVAILABLE的响应同样会占用等待期。

新IP错误#

状态码 错误码 含义
404 TOKEN_NOT_FOUND tokenId未知、不属于您或格式错误。
409 NOT_SUPPORTED 该令牌不是数据中心或ISP代理。
409 PACKAGE_INACTIVE 令牌或其套餐未在使用中。
409 CHANGE_LIMIT 静态:本周的更换额度已用完。动态:处于上一次请求之后的等待期内。错误会携带nextChangeAt和与之匹配的Retry-After。
409 LOCATION_UNAVAILABLE 已保存的位置目前没有其他可用的IP。未做任何更改;对动态令牌,该请求仍会占用等待期。
409 CONCURRENT_CHANGE 同一时刻对该令牌进行了另一项更改。静态:先读取位置,然后重试。动态:等待期结束后再次发送请求。

rotateUrl无需API密钥即可更换IP:在脚本或应用中向其发送GET请求,或在浏览器中打开。在浏览器标签页中作为页面打开的链接,会显示一个使用客户语言的简短页面。其他任何客户端会得到下面的JSON,而&format=json始终返回JSON,例如用于驱动真实浏览器的应用。任何持有该链接的人都能更换IP,因此请像保护密码一样保护它。控制台中链接旁的重置会生成新链接,旧链接立即失效。对动态数据中心/ISP令牌,它遵循与上文POST /tokens/{tokenId}/new-ip相同的规则:两次更换之间的等待期、在已保存的位置获得新IP,以及计时器重新开始。更换IP是介绍该链接和按钮的指南。所有JSON响应均为HTTP 200,并带有下表中的响应体:

响应体 含义
{"status": "ok"} 完成。动态数据中心/ISP令牌已获得新IP。独享设备开始更换IP。
{"error": "tooFrequent", "retryAfterSec": 4} 距上次更换时间过短。在retryAfterSec秒后再次发送。没有retryAfterSec时,该链接在一分钟内被调用超过20次,或独享设备不到一分钟前更换过IP。
{"error": "noOtherIp"} 令牌已保存的位置目前没有其他IP。未做任何更改,等待期仍然适用。
{"error": "invalidKey"} 该链接未知,或其令牌已过期、已停用,或所在套餐未在使用中。
{"error": "internalError"} 我们这边出现故障。稍后重试。