同一个 API Key 给好几个客户跑验证码识别,账单很快变成糊涂账——solve 记录都挤在一个池子里,分不清来源。CaptchaAI 的 soft_id 参数解决这个问题:带上一个标识符,用量就能按客户、按项目自动拆开统计。
soft_id 是什么,解决了什么问题
不加 soft_id 时,CaptchaAI 只知道请求总数,具体来自哪个客户区分不出来。带上 soft_id 后,每次提交都附带来源标签,后台按标签分别统计:
Without soft_id:
All solves tracked as one pool
No way to know which project/client generated usage
With soft_id:
Solve #1 ──▶ soft_id=PROJECT_A ──▶ Tracked separately
Solve #2 ──▶ soft_id=PROJECT_B ──▶ Tracked separately
Solve #3 ──▶ soft_id=CLIENT_123 ──▶ Tracked separately
可以把 soft_id 理解成请求上的“回执章”:值可以是项目代号 PROJECT_A,也可以是数字客户编号 1234,CaptchaAI 只负责原样记录、原样统计。
3 步接入:把 soft_id 加到请求里
只需在请求参数里多带一个字段,不需要改动现有识别逻辑:
import requests
API_KEY = "YOUR_API_KEY"
SOFT_ID = "1234" # Your registered soft_id
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"soft_id": SOFT_ID,
"json": 1,
})
SOFT_ID 是普通字符串参数,跟 key、method 放进同一个请求体提交即可,不需要单独调用其他接口注册或激活。
适用于所有已支持的验证码类型
不管提交的是 userrecaptcha(reCAPTCHA v2/v3)、turnstile(Turnstile)还是 base64(图片验证码),用法完全一样:
# Turnstile with soft_id
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": "SITE_KEY",
"pageurl": "https://example.com",
"soft_id": SOFT_ID,
"json": 1,
})
# Image CAPTCHA with soft_id
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": base64_image,
"soft_id": SOFT_ID,
"json": 1,
})
三个真实场景:谁在用 soft_id
场景一:出海代运营团队按客户拆分用量
国内不少海外电商代运营团队,会用同一套 CaptchaAI 账号给好几个客户的站点跑自动化脚本,都塞进同一个 API Key 就说不清每个客户消耗了多少次识别。给每个客户分配专属 soft_id,交给后台自动统计:
class AgencySolver:
"""Track CAPTCHA usage per client."""
def __init__(self, api_key, agency_soft_id):
self.api_key = api_key
self.soft_id = agency_soft_id
self.base = "https://ocr.captchaai.com"
def solve(self, method, client_tag=None, **params):
data = {
"key": self.api_key,
"method": method,
"soft_id": self.soft_id,
"json": 1,
}
data.update(params)
resp = requests.post(f"{self.base}/in.php", data=data)
task_id = resp.json()["request"]
# Log client attribution locally
if client_tag:
self._log_usage(client_tag, method, task_id)
return self._poll(task_id)
def _poll(self, task_id, timeout=120):
import time
start = time.time()
while time.time() - start < timeout:
time.sleep(5)
resp = requests.get(f"{self.base}/res.php", params={
"key": self.api_key, "action": "get",
"id": task_id, "json": 1,
})
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Solve timeout")
def _log_usage(self, client_tag, method, task_id):
import csv
import datetime
with open("client_usage.csv", "a", newline="") as f:
writer = csv.writer(f)
writer.writerow([
datetime.datetime.utcnow().isoformat(),
client_tag, method, task_id,
])
# Track usage per client
solver = AgencySolver("YOUR_API_KEY", agency_soft_id="1234")
# Client A's solves
solver.solve("userrecaptcha",
client_tag="client_acme",
googlekey="KEY", pageurl="https://acme.com",
)
# Client B's solves
solver.solve("turnstile",
client_tag="client_beta",
sitekey="KEY", pageurl="https://beta.com",
)
统一用机构的 soft_id 提交任务,再用 client_tag 打一层本地客户标签,出账单直接按 client_tag 汇总。
场景二:把 soft_id 内置进你自己的工具
如果你在做会调用 CaptchaAI 的产品或脚本,建议把 soft_id 直接写死在代码里,而不是留给使用者填——这样不管谁在用你的工具,用量都稳定归到你的合作伙伴账号名下:
class MyScraper:
"""Scraping tool with embedded CaptchaAI integration."""
SOFT_ID = "5678" # Registered when joining partner program
def __init__(self, user_api_key):
self.api_key = user_api_key
def solve_captcha(self, method, **params):
data = {
"key": self.api_key,
"method": method,
"soft_id": self.SOFT_ID, # Always include vendor ID
"json": 1,
}
data.update(params)
resp = requests.post(
"https://ocr.captchaai.com/in.php", data=data,
)
return resp.json()
SOFT_ID 是类属性,跟代码一起分发;终端用户只需提供自己的 API_KEY,不用管 soft_id。
场景三:一个账号下,多个内部项目分别记账
即便只有一个客户,把不同用途的调用拆开统计也有意义——价格监控、获客采集、QA 测试三条流水线,调用量和失败率往往差别很大,混在一起会失真:
# Different soft_ids per project
PROJECTS = {
"price_monitor": "1001",
"lead_gen": "1002",
"qa_testing": "1003",
}
def solve_for_project(project_name, method, **params):
soft_id = PROJECTS.get(project_name, "0000")
data = {
"key": API_KEY,
"method": method,
"soft_id": soft_id,
"json": 1,
}
data.update(params)
return requests.post("https://ocr.captchaai.com/in.php", data=data)
用本地日志核对用量和账单
后台的 soft_id 统计能告诉你总调用次数,但要精确到“哪个客户哪天用了多少次”,还是需要自己留一份本地日志,方便对账:
import csv
import datetime
from collections import defaultdict
class UsageTracker:
"""Track CAPTCHA solve usage for billing and analytics."""
def __init__(self, log_file="captchaai_usage.csv"):
self.log_file = log_file
self._init_log()
def _init_log(self):
try:
with open(self.log_file, "r"):
pass
except FileNotFoundError:
with open(self.log_file, "w", newline="") as f:
writer = csv.writer(f)
writer.writerow([
"timestamp", "soft_id", "client",
"method", "task_id", "status",
])
def record(self, soft_id, client, method, task_id, status="submitted"):
with open(self.log_file, "a", newline="") as f:
writer = csv.writer(f)
writer.writerow([
datetime.datetime.utcnow().isoformat(),
soft_id, client, method, task_id, status,
])
def get_summary(self, days=30):
"""Summarize usage by client over the last N days."""
cutoff = datetime.datetime.utcnow() - datetime.timedelta(days=days)
usage = defaultdict(lambda: defaultdict(int))
with open(self.log_file, "r") as f:
reader = csv.DictReader(f)
for row in reader:
ts = datetime.datetime.fromisoformat(row["timestamp"])
if ts > cutoff:
usage[row["client"]][row["method"]] += 1
return dict(usage)
# Usage
tracker = UsageTracker()
tracker.record("1234", "client_acme", "userrecaptcha", "TASK123")
summary = tracker.get_summary(days=30)
for client, methods in summary.items():
print(f"{client}: {dict(methods)}")
get_summary() 按客户和方法聚合最近 N 天的用量,可直接对着后台的 soft_id 报表核对;对不上通常是本地日志漏记了失败重试。soft_id 本身不额外收费,只是一个统计维度,不影响 CaptchaAI 按线程计费的方式。
常见问题排查
| 问题 | 可能原因 | 处理方式 |
|---|---|---|
| soft_id 没有被统计 | 参数名写错 | 确认用的是下划线 soft_id,不是连字符 soft-id |
| 控制台里看不到归因 | soft_id 还没注册 | 先通过合作伙伴计划注册这个 soft_id |
| 需要好几个 soft_id | 每个应用/项目对应一个 | 逐个单独注册,不要在多个项目里复用同一个 |
| 本地统计和后台对不上 | 本地日志漏记了失败的请求 | 成功和失败都要记录,不要只记成功 |
常见问题
不加 soft_id,识别请求还能正常提交吗?
可以,soft_id 是可选参数,不填不影响请求本身,只是这部分调用会算进“未分类”池子,没法单独统计。
soft_id 要去哪里申请?
通过 CaptchaAI 的合作伙伴/开发者计划注册,流程和申请普通 API Key 类似,不需要额外审核周期。
soft_id 可以用数字以外的字符吗?
可以,soft_id 本质上是字符串,写成 PROJECT_A、client_acme 这类项目代号比纯数字更好管理。
配置 soft_id 之后,识别速度、成功率或价格会变吗?
不会,soft_id 只用于用量归因和统计,跟识别速度、成功率、计费方式无关。
相关指南
把每一次调用都记到明处——加入 CaptchaAI 合作伙伴计划。