接入 1A1API:选对客户端入口,再发一次 hi

先分清 SDK、Codex 和 Claude Code 的地址与认证规则,再用一个独立的 Chat Completions 小请求检查文本输出。模型与费用按当前授权服务确认,不批量试错。

内容更新 2026-07-26

先看结论

Base URL 要同时匹配服务方和客户端的路径拼接规则;先检查配置,再经人工确认发一次 hi,分别核对返回结果与费用元信息。

操作步骤

  1. 先完成“准备条件”:确认当前 Key 允许目标模型的 Chat Completions 接口、费用边界与数据去向。这里只发送虚构的 hi;没有许可就停在离线检查,不注册或充值来凑验收。
  2. 按“客户端入口对照”区分实际工具。本文代码直接请求 https://1a1api.top/v1/chat/completions,不会读取或改写 Codex、Claude Code 的配置,也不能验收它们。
  3. 在只放教学文件的目录创建 1a1_check.py,粘贴下方完整代码。使用已安装、来源可信的 Python 3.10+;不要在同目录放名为 json.py、getpass.py 或 urllib.py 的文件,也不要交给未知插件代为运行。
  4. 先做离线检查:macOS/Linux 用 python3 1a1_check.py;Windows 在已有可用 Python 3 运行时及启动器时用 py -3 1a1_check.py。应只出现 CHECK_ONLY 提示;不会读取 Key、安装组件或发请求。缺少解释器则先停止,按本机维护规范处理,不运行来路不明的安装脚本。
  5. 只有本人确认目标、模型和潜在费用,才按“最小测试流程”运行带 --send 的命令;把 YOUR_MODEL_ID 替换为当前授权的文本模型 ID。再次输入 SEND-ONCE 后,在自己的可信终端隐式输入 Key,不将它交给 AI、聊天窗口或命令行参数。
  6. 检查输出的四个摘要字段,并在自己的授权控制台核对时间、模型、路径类别、状态和用量/费用元信息。脚本不显示响应正文或认证内容;参考结果见下方。若失败,停止重发,转到 /article/api-error-codes。
  7. API 小请求通过后,再决定是否配置业务客户端。改配置只合并必要字段并保留受保护的原设置;先确认客户端实际生效的凭据来源。工具调用、流式、图片、Agent 和渠道消息需另行验收,不能由这次 hi 推出已部署。

命令与示例

# 1a1_check.py — Python 3.10+;默认仅打印检查模式,不读取 Key 或联网。
import argparse
import getpass
import http.client
import json
import warnings
from urllib.error import HTTPError, URLError
from urllib.request import HTTPRedirectHandler, Request, build_opener

URL = "https://1a1api.top/v1/chat/completions"
MAX_BYTES = 65536

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        raise HTTPError(req.full_url, code, "redirect_blocked", headers, fp)

def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--send", action="store_true")
    parser.add_argument("--model", default="YOUR_MODEL_ID")
    args = parser.parse_args()
    if not args.send:
        print("CHECK_ONLY: no credential read; no request sent")
        return 0
    model = args.model.strip()
    if not model or model == "YOUR_MODEL_ID" or any(c.isspace() for c in model):
        print("STOP: choose an authorized Chat Completions model first")
        return 2
    print("Target:", URL)
    print("One paid request; input is fictional hi; no automatic retry.")
    if input("Type SEND-ONCE to continue: ").strip() != "SEND-ONCE":
        print("CANCELLED")
        return 2
    try:
        with warnings.catch_warnings():
            warnings.simplefilter("error", getpass.GetPassWarning)
            key = getpass.getpass("Key (local trusted terminal only): ")
    except getpass.GetPassWarning:
        print("STOP: hidden terminal input unavailable")
        return 2
    if not key or any(c.isspace() for c in key) or "\x00" in key:
        print("STOP: invalid credential input; value not displayed")
        return 2
    payload = {"model": model, "messages": [{"role": "user", "content": "hi"}],
               "stream": False}
    try:
        request = Request(URL, data=json.dumps(payload).encode("utf-8"),
                          headers={"Authorization": "Bearer " + key,
                                   "Content-Type": "application/json"},
                          method="POST")
        with build_opener(NoRedirect()).open(request, timeout=45) as response:
            status = response.status
            raw = response.read(MAX_BYTES + 1)
        if len(raw) > MAX_BYTES:
            print("STOP: response size exceeds local check limit")
            return 1
        result = json.loads(raw)
        choices = result.get("choices") if isinstance(result, dict) else None
        first = choices[0] if isinstance(choices, list) and choices else None
        message = first.get("message") if isinstance(first, dict) else None
        text = message.get("content") if isinstance(message, dict) else None
        has_text = isinstance(text, str) and bool(text.strip())
        normal_stop = isinstance(first, dict) and first.get("finish_reason") == "stop"
        ok = status == 200 and has_text and normal_stop and "error" not in result
        print(json.dumps({"httpStatus": status, "textPresent": has_text,
                          "normalStop": normal_stop, "passed": ok}))
        return 0 if ok else 1
    except HTTPError as error:
        print(json.dumps({"httpStatus": error.code, "passed": False}))
        error.close()
    except (URLError, TimeoutError, OSError):
        print("FAILED: network, TLS or timeout; no raw details printed")
    except http.client.HTTPException:
        print("FAILED: HTTP protocol or incomplete response; no raw details printed")
    except (ValueError, TypeError, UnicodeError):
        print("FAILED: request or response format; no raw details printed")
    return 1

if __name__ == "__main__":
    try:
        raise SystemExit(main())
    except (EOFError, KeyboardInterrupt):
        print("CANCELLED")
        raise SystemExit(2)

运行前确认四件事

  1. 有获准使用的服务账户/Key,知道其分组与用途;模型允许文本 Chat Completions,不拿仅支持另一协议的模型测试。
  2. 知道一次请求可能收费,并有适用的预算/限额。响应大小与网络超时是本地检查边界,不是模型输出或扣费上限。
  3. 接受 hi、请求元信息及认证信息发送给这个服务;没有真实客户资料。运行环境、系统代理与监控由可信管理员维护。
  4. 已具备可信 Python 3.10+ 和可以隐藏输入的本地终端。本文不负责安装解释器;Windows 的 py 仅在已具备运行时和启动器时使用,避免触发自动安装。

客户端入口对照:看工具,不只看协议

以下是 1A1API 帮助页的工具约定,不是所有兼容 API 的通用地址。版本或路径不一致时,先核对最终 endpoint;不要把完整接口路径填进 Base URL 字段。

客户端与用途服务帮助页的 Base URL认证与使用边界
OpenAI SDK:Chat Completions 或 Responseshttps://1a1api.top/v1使用该服务签发的 Key;SDK 分别拼 chat/completions 或 responses。Responses 并不自动意味着根地址。
Codex CLI:Responseshttps://1a1api.top这是服务方 Codex 页面约定。需与所装 CLI 版本、最终请求路径及认证方式一起确认,不外推桌面 App 或其他 Responses 客户端。
Claude Code CLI:Messageshttps://api.1a1api.top服务页使用 ANTHROPIC_BASE_URL 与 ANTHROPIC_AUTH_TOKEN。必须配套服务凭据,不仅改域名而保留官方登录的有效凭据。
Cursor、Cherry Studio、Anthropic SDK 或其他工具按具体客户端/版本文档不能从工具名称猜路径或复制另一工具的认证变量;先确认自定义入口和所需能力受支持。

只追加一次经确认的联网测试

下面两种平台命令只选适合自己的一条。先替换模型占位符;代码默认不会联网,--send 仍要求本人再次确认。输入是虚构 hi,不要求模型回复某个固定词。

  • macOS / Linux(已有 python3):python3 1a1_check.py --send --model "YOUR_MODEL_ID"。
  • Windows(已有 Python 3 运行时与启动器):py -3 1a1_check.py --send --model "YOUR_MODEL_ID"。
  • 脚本只尝试一个 POST,拒绝重定向,不自动重试;保留默认 TLS 校验与系统/环境代理行为,不绕过组织网络策略。
  • timeout=45 是阻塞网络操作的超时参数,不是从头到尾的绝对截止时间。64 KiB 只限制脚本读取的响应大小,不限制服务端生成量或费用。
  • 下方是脚本生成的参考摘要,不是 API 原始响应或实测记录。四项符合只证明这次文本小请求通过本地检查;服务侧费用与业务结果另查。
{
  "httpStatus": 200,
  "textPresent": true,
  "normalStop": true,
  "passed": true
}

通过、未通过各看什么

  • 离线分支只出现 CHECK_ONLY;没有终端隐藏输入能力时安全停止,不回退成明文显示 Key。
  • 联网分支 httpStatus 为 200,非空文本存在,finish_reason 为 stop,且没有 error 字段;length、content_filter 或 tool_calls 不算本次普通短文本完成。
  • 授权控制台里能核对这次请求的时间、模型与协议/路径类别,状态及用量/费用相符。记录有延迟或缺失时保持待确认,不先宣布全部正常。
  • 未改变业务客户端、全局环境或审批策略。接下来若接 Codex、Claude Code 或 Agent,必须分别核对认证、能力、权限与费用。

只交出非敏感接入摘要

用于人工或 AI 协助判断,不提供原始配置或返回体;请求 ID 只在授权支持渠道按需提供。

工具与版本:<名称、版本、操作系统>
服务签发方与认证类型:<名称、API Key 或订阅;不写凭据>
公开 Base URL:<无查询参数、无秘密>
协议及目标路径类别:<Chat Completions / Responses / Messages>
模型权限:<本人已确认 / 未确认,不附控制台截图>
检查结果:<CHECK_ONLY 或脚本四项摘要>
请求时间与时区:<时间>
费用元信息是否核对:<是 / 尚未,不附客户信息>

请只检查入口、协议、版本和凭据来源是否匹配。
有证据缺口就指出所需公开文档,不索取 Key、Token、Cookie、完整配置或日志。

不要用这些捷径代替检查

  • 把所有 Responses 客户端一律改成根地址:SDK 示例已经说明不成立,必须看具体拼接规则。
  • 将参考型号或 YOUR_MODEL_ID 原样发送:先确认本 Key 的当前模型及协议支持。
  • 把超时、响应读取上限或预算提醒当硬性费用封顶:它们不保证未扣费或分毫不超。
  • 把一次文本成功当成 Agent、图片生成或消息渠道已验收:这是不同能力和业务动作。

凭据只在自己的可信终端使用

  • 脚本不把 Key 放进命令行参数、文件或输出;进程内仍会持有它。可信终端和本机权限同样重要,不让未知插件或 AI 代输、代读。
  • 不要放真实 Key 到网页前端、截图、代码仓库或对话中;任何需要分享的片段都用 <REDACTED> 全量替换。
  • 疑似泄露先到签发方撤销并替换,检查授权用量;不要只删截图或继续观察。凭据管理主文:/article/api-key-basics。
  • 第三方服务的输入处理和日志规则要独立确认,不能继承官方直连的隐私承诺。测试使用虚构内容,不携带业务文件。

接口与安全输入依据

适合谁看

  • 已有合法的 1A1API 接入权限,需要验证一个允许 Chat Completions 的文本模型。
  • 准备配置 OpenAI SDK、Codex 或 Claude Code,担心把地址和凭据混用。
  • 希望先用虚构短文本排除基础接入问题,再接业务工具。

需要解决的问题

  • 把完整 endpoint 填成 Base URL,或不确定何时需要 /v1。
  • 模型列表里看见名称,生成时仍然报权限或路由错误。
  • 只得到 HTTP 200,却不知道是否返回文本、正常结束或走对账户。

先理解这些

  • Base URL 是基础地址,endpoint 是某个接口路径;最终请求地址取决于客户端怎么拼接。OpenAI SDK 的 Responses 和 Codex 都可采用 Responses 协议,却不必使用相同 Base URL。
  • 不同服务的 Key、地址与认证方式必须成套使用。第三方 Key 不是官方订阅凭据;改域名不应把原官方凭据一起送给新接收方。
  • 当前模型 ID、协议支持、分组权限、费用和限额以授权控制台及该协议的列表为准。帮助页中的固定型号只是示例,不代表当前 Key 可用。

遇到困难时

  • 看到 CHECK_ONLY:这是预期的离线检查,不是接口成功。只有完成授权与费用确认后才能进入 --send 分支。
  • 401/403:核对签发方、认证字段、Key 状态和模型/接口权限。不要将官方登录缓存复制成第三方配置,也不要不停换 Key。
  • 404:核对最终路径和当前客户端版本。SDK 中重复 /v1 与 Codex 使用不同 Base URL 是两种问题,不能靠同一种替换修复。
  • 429、503、超时或本地检查未通过:停止,不自动换模型或再套重试;先查授权的请求元信息。超时或脚本退出不证明服务未执行、未计费。
  • 撤回本练习只需不再运行脚本;它不保存 Key、不改客户端配置。已人工创建的临时 Key 应按使用计划撤销;其他配置只恢复自己修改的字段,不删除整个认证目录。