文档

API 接入文档

IWKey 统一网关的接入指南:可用模型、快速开始、调用入口、代码示例、SDK 配置与常见问题。

文本调用 · cURL
curl https://iwkey.com/v1/chat/completions \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-5-5", "messages": [ {"role": "user", "content": "Hello"} ] }'
视频模型任务 · cURL
curl https://iwkey.com/videos/v1/videos/generations \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0", "prompt": "A cinematic product shot", "duration": 5, "resolution": "480p", "aspect_ratio": "16:9" }'

01文本与视频模型,一个 Key 接入

统一查看 Claude、ChatGPT 与视频模型的调用入口、模型 ID 获取方式和状态;完整目录见 模型页面。

接口定义见 /docs/openapi.json;模型详情以实时 /v1/models 与 模型市场 为准。

curl · List models
curl https://iwkey.com/v1/models \ -H "Authorization: Bearer $IWKEY_KEY"

最后更新:2026-10-13

02三步接入

STEP 01

申请 API Key

登录控制台,创建 API Key。

STEP 02

选择调用入口

文本模型替换 SDK base URL;视频模型用 /videos/v1/videos/generations 提交任务。

STEP 03

查看结果与用量

文本请求实时返回;视频模型按任务轮询,完成后可下载结果,并进入使用记录汇总。

最后更新:2026-09-04

03调用入口

GET

/v1/models

接入前查询当前可调用模型 ID。ChatGPT 模型 ID 以此列表为准。

POST

/v1/chat/completions

OpenAI 兼容入口。完成 base URL 替换后,OpenAI SDK、Cursor、Codex CLI、opencode、LangChain 可走此入口。

POST

/v1/messages

Anthropic Messages 原生入口。Claude Code 与 Anthropic SDK 可直接切换到 IWKey base URL。

POST

/videos/v1/videos/generations

视频模型异步任务入口。提交 prompt、时长、清晰度和画幅后返回 job_id 与 poll_url。

GET

/videos/v1/videos/jobs/{job_id}

优先请求提交响应返回的 poll_url;该地址用于查询任务状态、完成结果、失败原因和视频下载地址。

POST

/videos/api/v3/contents/generations/tasks

火山方舟原生格式的视频模型入口。model 可直接填官方 ID(doubao-seedance-2-0-260128 / doubao-seedance-2-0-fast-260128 / doubao-seedance-2-5-260628);顶层不支持的参数会明确报错,不会静默丢弃。

GET

/videos/api/v3/contents/generations/tasks/{id}

方舟原生格式的任务查询入口,返回方舟状态枚举(queued / running / succeeded / failed / cancelled / expired)。成功时 content.video_url 为生成引擎官方直链(有效期通常约 24 小时),与标准接口的 video_url 完全一致;若该任务有平台副本,会额外附带 content.platform_video_url 与 content.platform_expires_at(本平台保存 7 天;这两个字段为本平台额外返回,方舟原生格式中没有)。

已经在用火山方舟原生请求格式的开发者,可以直接使用上面的方舟兼容入口;与方舟原生的具体差异见视频模型 API 接入指南「方舟兼容入口:与方舟原生的差异」。

最后更新:2026-09-24

04进阶场景示例

文本高级能力与视频模型异步任务示例,每个场景给出 cURL / Python / JavaScript 三种写法。

cURL · 流式响应(SSE)
curl -N https://iwkey.com/v1/chat/completions \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-5-5", "messages": [{"role": "user", "content": "写一首关于云的短诗"}], "stream": true }'
Python · 流式响应
from openai import OpenAI client = OpenAI(base_url="https://iwkey.com/v1", api_key="$IWKEY_KEY") stream = client.chat.completions.create( model="claude-opus-5-5", messages=[{"role": "user", "content": "写一首关于云的短诗"}], stream=True, ) for chunk in stream: print(chunk.choices[0].delta.content or "", end="")
JavaScript · 流式响应
import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://iwkey.com/v1", apiKey: process.env.IWKEY_KEY, }); const stream = await client.chat.completions.create({ model: "claude-sonnet-5-5", messages: [{ role: "user", content: "写一首关于云的短诗" }], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0].delta.content ?? ""); }
cURL · 视频模型异步任务
# 1. Submit job and capture the returned poll_url POLL_URL=$(curl -sS https://iwkey.com/videos/v1/videos/generations \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0", "prompt": "A cinematic product shot on a clean studio desk", "duration": 5, "resolution": "480p", "aspect_ratio": "16:9" }' | jq -r '.poll_url') # 2. Poll the exact URL returned by the API curl "$POLL_URL" \ -H "Authorization: Bearer $IWKEY_KEY"
cURL · 火山方舟原生格式
# 1. 提交任务(方舟原生结构:content 数组 + ratio 字段) TASK_ID=$(curl -sS https://iwkey.com/videos/api/v3/contents/generations/tasks \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2-0-260128", "content": [ { "type": "text", "text": "A cinematic product shot on a clean studio desk" } ], "duration": 5, "resolution": "480p", "ratio": "16:9" }' | jq -r '.id') # 2. 查询任务(成功时 content.video_url = 官方直链约 24h; # 有平台副本时另有 content.platform_video_url,本平台保存 7 天) curl "https://iwkey.com/videos/api/v3/contents/generations/tasks/$TASK_ID" \ -H "Authorization: Bearer $IWKEY_KEY"
Python · 视频模型异步任务
import os import time import requests headers = { "Authorization": f"Bearer {os.environ['IWKEY_KEY']}", "Content-Type": "application/json", } job = requests.post( "https://iwkey.com/videos/v1/videos/generations", headers=headers, json={ "model": "doubao-seedance-2.0", "prompt": "A cinematic product shot on a clean studio desk", "duration": 5, "resolution": "480p", "aspect_ratio": "16:9", }, ) job.raise_for_status() poll_url = job.json()["poll_url"] while True: result = requests.get(poll_url, headers=headers) result.raise_for_status() data = result.json() if data["status"] in {"completed", "failed", "cancelled", "timeout"}: print(data) break time.sleep(5)
JavaScript · 视频模型异步任务
const headers = { Authorization: `Bearer ${process.env.IWKEY_KEY}`, "Content-Type": "application/json", }; const submit = await fetch("https://iwkey.com/videos/v1/videos/generations", { method: "POST", headers, body: JSON.stringify({ model: "doubao-seedance-2.0", prompt: "A cinematic product shot on a clean studio desk", duration: 5, resolution: "480p", aspect_ratio: "16:9", }), }); const job = await submit.json(); while (true) { const res = await fetch(job.poll_url, { headers }); const result = await res.json(); if (["completed", "failed", "cancelled", "timeout"].includes(result.status)) { console.log(result); break; } await new Promise((resolve) => setTimeout(resolve, 5000)); }
视频任务参数参考
参数 类型 说明
model string doubao-seedance-2.0 / doubao-seedance-2.0-fast / doubao-seedance-2.5 / MiniMax-H3
prompt string 文本描述,必填
duration integer 时长(秒),doubao-seedance-2.0 / doubao-seedance-2.0-fast 与 MiniMax-H3 为 4–15,doubao-seedance-2.5 为 4–30
resolution string 按模型取值:doubao-seedance-2.0 为 480p / 720p / 1080p / 4k;doubao-seedance-2.0-fast 为 480p / 720p;doubao-seedance-2.5 为 480p / 720p / 1080p;MiniMax-H3 为 768p / 2k
image_urls array ≤9(doubao-seedance-2.5 ≤30) 参考图片。每项可以是 URL 字符串(默认角色 = first_frame,图生视频)或对象 {"url":"…","role":"first_frame|last_frame|reference_image"}
video_urls array ≤3(doubao-seedance-2.5 ≤10) 参考视频
audio_urls array ≤3(doubao-seedance-2.5 ≤10) 参考音频;doubao-seedance-2.5 可单独使用;doubao-seedance-2.0、doubao-seedance-2.0-fast、MiniMax-H3 不能单独使用,必须搭配 role:"reference_image" 的图片或 video_urls;首帧/尾帧图片不能与音频同时使用
generate_audio boolean 输出是否带音频,默认 false
cURL · 含参考图与音频
curl https://iwkey.com/videos/v1/videos/generations \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0", "prompt": "产品展示视频,柔和灯光,镜头缓慢推进", "duration": 5, "resolution": "720p", "image_urls": [ {"url": "https://example.com/product.jpg", "role": "reference_image"} ], "audio_urls": ["https://example.com/bgm.mp3"], "generate_audio": true }'

计费:提交时预扣,成功后按实际用量结算,多退少补;失败全额退款。

出片链接说明
字段 说明
video_url 生成引擎官方原始出片链接,约 24 小时有效(有效期以 expires_at 为准)。
platform_video_url 平台存储链接,自生成完成起保留 7 天,到期后文件删除且不可恢复。未启用平台存储或无副本时为 null,此时用 video_url。
platform_expires_at platform_video_url 的到期时间。
cURL · 工具调用(Function Calling)
curl https://iwkey.com/v1/chat/completions \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-opus-5-5", "messages": [{"role": "user", "content": "杭州天气怎么样?"}], "tools": [{ "type": "function", "function": { "name": "get_weather", "parameters": { "type": "object", "properties": {"city": {"type": "string"}} } } }] }'
Python · 工具调用
from openai import OpenAI client = OpenAI(base_url="https://iwkey.com/v1", api_key="$IWKEY_KEY") resp = client.chat.completions.create( model="claude-opus-5-5", messages=[{"role": "user", "content": "杭州天气怎么样?"}], tools=[{ "type": "function", "function": { "name": "get_weather", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, }, }, }], ) print(resp.choices[0].message.tool_calls)
JavaScript · 工具调用
import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://iwkey.com/v1", apiKey: process.env.IWKEY_KEY, }); const resp = await client.chat.completions.create({ model: "claude-sonnet-5-5", messages: [{ role: "user", content: "杭州天气怎么样?" }], tools: [{ type: "function", function: { name: "get_weather", parameters: { type: "object", properties: { city: { type: "string" } }, }, }, }], }); console.log(resp.choices[0].message.tool_calls);

平台采用官方标准模型 ID,推理强度通过 API 参数 控制——Anthropic 用 thinking 对象,OpenAI 用 reasoning_effort。

Anthropic Claude · 启用 Extended Thinking
curl https://iwkey.com/v1/messages \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-opus-5-5", "max_tokens": 16000, "thinking": { "type": "adaptive", "display": "summarized" }, "output_config": { "effort": "high" }, "messages": [{ "role": "user", "content": "解释量子纠缠的机制" }] }' # Claude Opus 5.5 / Sonnet 5 / Fable 5.1:thinking 用 "adaptive",推理深度由 output_config.effort 控制(low / medium / high / xhigh / max)
Python · Anthropic SDK
import anthropic client = anthropic.Anthropic( base_url="https://iwkey.com", api_key="$IWKEY_KEY", ) resp = client.messages.create( model="claude-opus-5-5", max_tokens=16000, thinking={"type": "adaptive", "display": "summarized"}, output_config={"effort": "high"}, messages=[{"role": "user", "content": "解释量子纠缠的机制"}], ) for block in resp.content: if block.type == "thinking": print("[思考过程]", block.thinking[:200], "...") elif block.type == "text": print("[回答]", block.text)
OpenAI · reasoning_effort 参数
curl https://iwkey.com/v1/chat/completions \ -H "Authorization: Bearer $IWKEY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-6-sol", "reasoning_effort": "high", "messages": [{ "role": "user", "content": "解释量子纠缠的机制" }] }' # reasoning_effort: "low" | "medium" | "high"(默认 medium) # 适用于 gpt-6-sol 等支持推理的模型;查 /v1/models 确认当前可用 ID
Python · OpenAI SDK
from openai import OpenAI client = OpenAI(base_url="https://iwkey.com/v1", api_key="$IWKEY_KEY") resp = client.chat.completions.create( model="gpt-6-sol", reasoning_effort="high", messages=[{"role": "user", "content": "解释量子纠缠的机制"}], ) print(resp.choices[0].message.content)

最后更新:2026-09-29

05各客户端配置示例

Claude Code

Claude 全系
⚠ ANTHROPIC_BASE_URL 只到主机名 https://iwkey.com,不要加 /v1(与 OpenAI 接口不同;加了会拼成 /v1/v1/messages → 404)
# 设置环境变量后直接启动 export ANTHROPIC_BASE_URL=https://iwkey.com export ANTHROPIC_API_KEY=your-iwkey-key claude

Cursor

Claude + ChatGPT
⚠ Base URL 须带 /v1(OpenAI 协议入口,Cursor 直接拼接 /chat/completions;与 Claude Code 的 ANTHROPIC_BASE_URL 不带 /v1 不同)
# Settings → Models → Override OpenAI Base URL Base URL: https://iwkey.com/v1 API Key: your-iwkey-key # Claude 可直接填模型 ID(如 claude-sonnet-5-5);ChatGPT 模型 ID 先查 /v1/models

Anthropic Python SDK

Claude 全系
import anthropic client = anthropic.Anthropic( base_url="https://iwkey.com", api_key="your-iwkey-key", ) msg = client.messages.create( model="claude-opus-5-5", max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], )

OpenAI Python SDK

Claude + ChatGPT
# model 换名即切 provider from openai import OpenAI client = OpenAI( base_url="https://iwkey.com/v1", api_key="your-iwkey-key", ) # Claude resp = client.chat.completions.create( model="claude-opus-5-5", messages=[{"role": "user", "content": "Hello"}], ) # ChatGPT — 同一个 client,具体模型 ID 先查 /v1/models resp = client.chat.completions.create( model="gpt-6-sol", messages=[{"role": "user", "content": "Hello"}], )

视频模型 API

Seedance / 视频任务
# 标准 HTTP 调用:提交任务后轮询 poll_url curl https://iwkey.com/videos/v1/videos/generations \ -H "Authorization: Bearer your-iwkey-key" \ -H "Content-Type: application/json" \ -d '{"model":"doubao-seedance-2.0","prompt":"A product video","duration":5,"resolution":"480p","aspect_ratio":"16:9"}'

Codex CLI

ChatGPT 系(Responses API)
⚠ base_url 只到 /v1,不要加 /chat/completions,否则 Codex 会拼出错误路径导致 404
⚠ 模型用 gpt-6-sol,Codex 走 Responses API(非 chat/completions),需在 config.toml 声明 wire_api = "responses"
# ~/.codex/config.toml model = "gpt-6-sol" model_provider = "iwkey" [model_providers.iwkey] name = "IWKey" base_url = "https://iwkey.com/v1" wire_api = "responses" env_key = "IWKEY_KEY"
export IWKEY_KEY="sk-你的令牌" codex

opencode

Claude + ChatGPT
⚠ options.baseURL 须带 /v1(@ai-sdk/openai-compatible 直接拼接 /chat/completions,不会自动补 /v1)
# ~/.config/opencode/opencode.json { "$schema": "https://opencode.ai/config.json", "provider": { "iwkey": { "npm": "@ai-sdk/openai-compatible", "name": "IWKey", "options": { "baseURL": "https://iwkey.com/v1", "apiKey": "{env:IWKEY_KEY}" }, "models": { "claude-sonnet-5-5": { "name": "Claude Sonnet 5" }, "gpt-6-sol": { "name": "GPT-6 Sol" } } } } }
# 设置环境变量后运行 /connect 存凭据,provider id 填 "iwkey" export IWKEY_KEY="your-iwkey-key" opencode # TUI 内:/connect → Other → 粘贴 Key,provider id 填 "iwkey" # 完成后 /models 选择上面配置的模型

LangChain

Claude 全系
from langchain_anthropic import ChatAnthropic llm = ChatAnthropic( base_url="https://iwkey.com", api_key="your-iwkey-key", model="claude-opus-5-5", )

最后更新:2026-10-13

06视频模型

视频生成是异步任务,支持参考素材与素材库,接入规范见独立文档:/docs/video-model/(共用 API Key 与入口域名)。

  1. 1三分钟跑通第一条视频
  2. 2参考图
  3. 3素材库:真人形象的唯一通道
  4. 4人物命名与位置语法
  5. 5接口参考
    1. 5.1提交生成任务 · POST /videos/v1/videos/generations
    2. 5.2提交前估价 · POST /videos/v1/videos/generations/estimate
    3. 5.3查询任务 · GET /videos/v1/videos/jobs/{job_id}
    4. 5.4任务列表 · GET /videos/v1/videos/jobs
    5. 5.5消费统计 · GET /videos/v1/videos/jobs/stats
    6. 5.6导出 · GET /videos/v1/videos/jobs/export.csv
    7. 5.7素材库
    8. 5.8上传接口(视频工作台专用,API 接入通常不需要)
    9. 5.9方舟兼容入口:与方舟原生的差异
  6. 6错误码
    1. 6.1业务与参数类错误码
    2. 6.2鉴权与服务端错误码
    3. 6.3重试建议
  7. 7归属与隔离边界
  8. 8配额与限制
  9. 9常见接入问题

最后更新:2026-10-20

07账户余额查询

在发起调用前、或在你自己的调度服务里查一下余额:余额不足时提前预警,避免请求中途因余额不足被拒。只读,查询不收费。

GET https://iwkey.com/v1/usage

api.infwave.com 同样可用。鉴权用你调用模型的同一把 API Key:Authorization: Bearer <你的密钥>(也接受 x-api-key 请求头)。

curl 示例 · 查询余额
curl https://iwkey.com/v1/usage \ -H "Authorization: Bearer <你的 API Key>"
响应示例(普通 Key,数值为演示,仅列常用字段)
{ "isValid": true, "mode": "unrestricted", "planName": "钱包余额", "balance": 61.66, "remaining": 61.66, "unit": "USD", "usage": { "today": { "requests": 12, "total_tokens": 48210, "actual_cost": 0.42 }, "total": { "requests": 1893, "total_tokens": 9120000, "actual_cost": 38.34 }, "rpm": 0, "tpm": 0 } }

返回什么取决于这把 Key:同一个接口,下面三种 Key 返回的含义不同,接入前先确认你用的是哪一种。

Key 类型返回内容
普通 Key账户的钱包余额:planName 为「钱包余额」,balance / remaining 是余额,unit 为 USD
设了额度上限或速率限制的 Key这把 Key 自身的剩余额度,不是账户余额
订阅套餐分组的 Key套餐剩余额度,以及日 / 周 / 月已用量、对应上限和到期时间

三种情况都会附带 usage:今日与累计的请求数、token 数和费用,以及 rpm、tpm。

查询频率:余额变化不快,建议每小时查询一次即可。

用程序调用必须设置 User-Agent:用 Python 等程序调用时,请求头里要带上 User-Agent,否则请求可能被 Cloudflare 拦截(返回 403,或直接连接失败);curl 不受影响。下面的示例脚本已经带上。

余额提醒

余额偏低时提前收到通知,避免调用因余额不足中断。用定时任务每小时调用一次上面的接口,余额低于你设定的线时,把提醒发到你自己的飞书群、钉钉群、企业微信群、手机短信或 Telegram 等通道。示例只用 Python 标准库,通过环境变量 NOTIFY_CHANNEL 在飞书、钉钉、企业微信、Telegram 之间切换;短信需要接入你们自己的短信服务商,见下表。

平台先准备环境变量
飞书(feishu)在群里添加「自定义机器人」,复制 webhook 地址;机器人如果开启了「签名校验」,同时复制密钥FEISHU_WEBHOOK;开了签名校验再加 FEISHU_SECRET
钉钉(dingtalk)在群里添加「自定义机器人」,复制 webhook 地址;安全设置如果选了「加签」,同时复制密钥DINGTALK_WEBHOOK;选了加签再加 DINGTALK_SECRET
企业微信(wecom)在群里添加「群机器人」,复制 webhook 地址WECOM_WEBHOOK
短信在阿里云短信、腾讯云短信等服务商开通,先申请短信签名和模板,审核通过后才能发送。示例未内置短信,把示例里的发送函数换成服务商的发送接口即可按服务商要求(如密钥、签名、模板 ID、接收手机号)
Telegram(telegram)用 @BotFather 创建机器人拿到 token,把机器人加进目标群或私聊,取得 chat_id。国内服务器直连 Telegram 通常不通,需要能访问 Telegram 的网络TG_BOT_TOKEN、TG_CHAT_ID

另需设置 IWKEY_KEY(你调用模型的 API Key);LOW_USD / CRIT_USD 为偏低线 / 告急线(美元),默认 40 / 10。webhook 地址和 bot token 等同于密码,不要外传。示例读取的是 balance:普通 Key 是账户钱包余额;设了额度上限的 Key 读到的是这把 Key 的剩余额度,提醒线请按此理解;订阅套餐分组的 Key 返回结构不同,本示例不适用。示例的行为:偏低、告急各提醒一次,同一档不重复;充值后回到偏低线的 1.2 倍以上才算恢复;查询失败不当作余额不足,连续 3 次失败会提醒「监控断了」;消息发送失败不记账,下一轮重试。建议用 crontab 每小时运行一次:0 * * * *。

Python 示例 · 余额低于阈值时推送到群(飞书 / 钉钉 / 企业微信 / Telegram)
#!/usr/bin/env python3 """IWKey 余额提醒:每小时查一次余额,低于你设的线就推送到飞书 / 钉钉 / 企业微信 / Telegram。只用 Python 标准库。 环境变量: IWKEY_KEY 调用模型用的 API Key NOTIFY_CHANNEL feishu / dingtalk / wecom / telegram,四选一 飞书:FEISHU_WEBHOOK(机器人开了签名校验再加 FEISHU_SECRET) 企业微信:WECOM_WEBHOOK 钉钉:DINGTALK_WEBHOOK(机器人开了加签再加 DINGTALK_SECRET) Telegram:TG_BOT_TOKEN、TG_CHAT_ID LOW_USD / CRIT_USD 偏低线 / 告急线(美元),默认 40 / 10 定时运行(crontab,每小时一次): 0 * * * * /usr/bin/python3 /path/to/balance_alert.py >> balance_alert.log 2>&1 行为:偏低、告急各提醒一次;查询失败不当作余额不足,连续 3 次失败提醒「监控断了」。""" import base64 import hashlib import hmac import json import os import time import urllib.parse import urllib.request from pathlib import Path API = "https://iwkey.com/v1/usage" KEY = os.environ.get("IWKEY_KEY", "") CHANNEL = os.environ.get("NOTIFY_CHANNEL", "feishu") # feishu / wecom / dingtalk / telegram LOW = float(os.environ.get("LOW_USD", "40")) CRIT = float(os.environ.get("CRIT_USD", "10")) STATE = Path(os.environ.get("STATE_FILE", str(Path.home() / ".iwkey_balance_alert.json"))) TIERS = ["正常", "偏低", "告急"] UA = "balance-alert/1.0" # 必须带 User-Agent,否则可能被 Cloudflare 拦截(403 / 连接失败) def http_json(url, payload=None, headers=None): data = json.dumps(payload).encode() if payload is not None else None h = {"User-Agent": UA, **(headers or {})} if data: h["Content-Type"] = "application/json" req = urllib.request.Request(url, data=data, headers=h) with urllib.request.urlopen(req, timeout=15) as r: return json.loads(r.read().decode()) def query_balance(): data = http_json(API, headers={"Authorization": f"Bearer {KEY}"}) usd = float(data.get("balance", data.get("remaining"))) return usd, f"${usd:.2f}" def send_once(text): if CHANNEL == "feishu": # 飞书自定义机器人 webhook payload = {"msg_type": "text", "content": {"text": text}} secret = os.environ.get("FEISHU_SECRET") if secret: # 机器人开了「签名校验」才需要 ts = str(int(time.time())) key = f"{ts}\n{secret}".encode() payload["timestamp"] = ts payload["sign"] = base64.b64encode(hmac.new(key, b"", hashlib.sha256).digest()).decode() return http_json(os.environ["FEISHU_WEBHOOK"], payload).get("code") == 0 if CHANNEL == "wecom": # 企业微信群机器人 webhook res = http_json(os.environ["WECOM_WEBHOOK"], {"msgtype": "text", "text": {"content": text}}) return res.get("errcode") == 0 if CHANNEL == "dingtalk": # 钉钉群自定义机器人 webhook url = os.environ["DINGTALK_WEBHOOK"] secret = os.environ.get("DINGTALK_SECRET") if secret: # 机器人开了「加签」才需要 ts = str(int(time.time() * 1000)) digest = hmac.new(secret.encode(), f"{ts}\n{secret}".encode(), hashlib.sha256).digest() url += f"&timestamp={ts}&sign={urllib.parse.quote_plus(base64.b64encode(digest))}" res = http_json(url, {"msgtype": "text", "text": {"content": text}}) return res.get("errcode") == 0 if CHANNEL == "telegram": # Telegram bot(国内服务器通常连不上) url = f"https://api.telegram.org/bot{os.environ['TG_BOT_TOKEN']}/sendMessage" return http_json(url, {"chat_id": os.environ["TG_CHAT_ID"], "text": text}).get("ok") is True raise SystemExit("NOTIFY_CHANNEL 只能是 feishu / wecom / dingtalk / telegram") def notify(text): for i in range(3): try: if send_once(text): return True print("消息被拒收,稍后重试") except Exception as e: print(f"消息发送异常:{type(e).__name__}") # 只打印异常类型,不打印网址,避免 token 进日志 time.sleep(2 ** i) return False def load_state(): try: return json.loads(STATE.read_text()) except Exception: return {"tier": 0, "fails": 0, "down_alerted": False} def main(): if not KEY: raise SystemExit("请先设置 IWKEY_KEY") st = load_state() try: usd, shown = query_balance() except Exception as e: st["fails"] += 1 print(f"查询失败(第 {st['fails']} 次):{type(e).__name__}") if st["fails"] >= 3 and not st["down_alerted"]: if notify("【IWKey 余额监控】已连续 3 次查不到余额,监控可能中断,请检查网络或 API Key。"): st["down_alerted"] = True STATE.write_text(json.dumps(st)) return st["fails"], st["down_alerted"] = 0, False tier = 2 if usd < CRIT else 1 if usd < LOW else 0 if tier > st["tier"]: # 跌进更差的一档才提醒,同一档不重复提醒 line = CRIT if tier == 2 else LOW msg = (f"【IWKey 余额{TIERS[tier]}】当前可用余额 {shown}," f"已低于{TIERS[tier]}线 ${line:.0f},请及时充值,以免调用中断。") if notify(msg): st["tier"] = tier # 发送成功才记账,失败下轮重试 elif tier < st["tier"] and (tier > 0 or usd >= LOW * 1.2): # 回到偏低线的 1.2 倍以上才算恢复,避免在线附近反复提醒 st["tier"] = tier if tier == 0: notify(f"【IWKey 余额已恢复】当前可用余额 {shown}。") print(f"余额 ${usd:.2f},档位 {TIERS[st['tier']]}") STATE.write_text(json.dumps(st)) if __name__ == "__main__": main()

最后更新:2026-10-12

08常见问题

返回格式和官方 API 一致吗?
一致。响应体透传上游原生字段(Anthropic 的 request_id、OpenAI 的 id 与 system_fingerprint)。文本请求不留存提示词和回答正文,完整边界见 透明度页面。
计费方式是什么?
文本模型按 token 用量计费;视频模型按模型与时长计费。登录控制台后可查看实时余额、用量明细,可按模型/日期/Key 筛选查看。支持对公转账 + 增值税发票。
你们会存储我的 prompt 和 response 吗?
文本请求与响应正文不存数据库。视频模型属于异步任务,任务参数、状态、成本、结果地址和失败原因会保留用于任务追踪与计费;完整边界以 透明度页面 为准。
支持 Streaming 吗?
文本模型支持 Anthropic 原生 SSE streaming 和 OpenAI 兼容 streaming,在请求中设置 "stream": true 即可。视频模型不是 streaming 响应;提交任务后应优先请求响应中的 poll_url,当前地址为 /videos/v1/videos/jobs/{job_id}。
视频模型怎么调用?
使用同一个 API Key 调用 POST /videos/v1/videos/generations,提交后会返回 job_id 和 poll_url。任务完成后可在轮询响应或「视频模型使用记录」里查看结果、下载地址和失败原因。
如何启用推理增强(Extended Thinking / reasoning_effort)?
平台只提供官方标准模型 ID,不提供 -thinking/-high/-low 等后缀变体。推理强度由 API 参数控制:
  • Anthropic Claude:claude-opus-5-5、claude-sonnet-5-5、claude-fable-5-1 在请求体加 "thinking": {"type": "adaptive"},用 "output_config": {"effort": "high"} 调推理深度(可选 low/medium/high/xhigh/max)。
  • OpenAI(推理模型):在请求体加 "reasoning_effort": "high"(可选 low/medium/high)。支持模型:gpt-6-sol 等,查 GET /v1/models 确认。
完整示例见代码示例 → 推理增强(Thinking) 标签。
如何启用提示缓存(Prompt Caching)?
💡 提示缓存(Prompt Caching):Claude 模型支持提示缓存,对重复的长上下文(system prompt、Agent 循环、代码库上下文等)可节省最高约 90% 的输入费用。启用方式:使用 Anthropic 原生 /v1/messages 格式,并在消息/系统提示中标记 cache_control 断点。注意:OpenAI 兼容的 /v1/chat/completions 格式不支持 Claude 提示缓存,每次请求按全价输入计费。
和直连 Anthropic / OpenAI API 有什么区别?
文本接口与 Anthropic / OpenAI 官方格式兼容,支持 Streaming 和 Tool Calling;视频模型走 IWKey 的异步任务接口。同一个 Key、余额和使用记录打通,支持人民币对公结算与增值税发票。

最后更新:2026-10-08