奇画 AI

开发文档

OpenAI / Anthropic SDK 直接换 base_url 即可调用,也可以把多模态任务接入自己的创作流程。

Base URL: https://qihuaai.com/v1. 所有请求和响应都是 JSON (流式除外), 计费单位为 credits.

认证

在 开发者 Key 页面创建 API Key (以 qh_ 开头, 明文只显示一次). 每个请求都带上请求头:

http
Authorization: Bearer qh_your_api_key

Key 只保存在服务端的哈希里, 丢失后无法找回, 只能撤销后重建. 不要把 Key 写进前端代码或公开仓库. 写操作 (生成, 对话) 建议带 Idempotency-Key 请求头, 网络重试时不会重复扣费.

Chat Completions (OpenAI 兼容)

POST /v1/chat/completions, 请求体与 OpenAI 一致, model 填模型目录中的 id. 响应额外带 qihua 字段 (call_id, request_id, user_charged_credits).

非流式

bash
curl https://qihuaai.com/v1/chat/completions \
  -H "Authorization: Bearer $QIHUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4",
    "messages": [{"role": "user", "content": "用一句话介绍你自己"}]
  }'
python
from openai import OpenAI

client = OpenAI(base_url="https://qihuaai.com/v1", api_key="qh_your_api_key")
resp = client.chat.completions.create(
    model="deepseek-v4",
    messages=[{"role": "user", "content": "用一句话介绍你自己"}],
)
print(resp.choices[0].message.content)

流式 (SSE)

传 "stream": true 后按 Server-Sent Events 返回 chat.completion.chunk, 以 data: [DONE] 结束. 传 "stream_options": {"include_usage": true} 时, 结束前会多一个 choices 为空的 chunk, 带 usage 和本次实际扣费 qihua.user_charged_credits. 中途断开连接时按已生成的内容计费, 不会多扣.

bash
curl -N https://qihuaai.com/v1/chat/completions \
  -H "Authorization: Bearer $QIHUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4",
    "stream": true,
    "stream_options": {"include_usage": true},
    "messages": [{"role": "user", "content": "写一首关于秋天的短诗"}]
  }'
python
from openai import OpenAI

client = OpenAI(base_url="https://qihuaai.com/v1", api_key="qh_your_api_key")
stream = client.chat.completions.create(
    model="deepseek-v4",
    messages=[{"role": "user", "content": "写一首关于秋天的短诗"}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:
        print("\nusage:", chunk.usage)

流式过程中发生错误时, 会收到一条 data: {"error": {"code", "message"}} 后紧跟 data: [DONE].

Anthropic Messages

POST /v1/messages 兼容 Anthropic Messages 格式 (仅文本内容, 暂不支持 tool use). 认证同样使用 Authorization: Bearer, 因此 SDK 中请用 auth_token 参数而不是 api_key. 流式时按 Anthropic 事件 (message_start, content_block_delta, message_stop ...) 返回.

bash
curl https://qihuaai.com/v1/messages \
  -H "Authorization: Bearer $QIHUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "system": "你是一名简洁的助手",
    "messages": [{"role": "user", "content": "解释一下什么是 SSE"}]
  }'
python
from anthropic import Anthropic

# base_url is the API root: the SDK appends /v1/messages itself.
client = Anthropic(base_url="https://qihuaai.com", auth_token="qh_your_api_key")
with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "解释一下什么是 SSE"}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

模型目录

GET /v1/catalog/models?type=chat|image|video|audio 返回当前可用模型, 含 param_schema (参数名, 类型, 枚举, 默认值, 上限) 和计费单位 billing_unit. GET /v1/catalog/models/{id}/lanes 返回该模型的线路: 售价 sell_price (credits), 24 小时成功率 success_rate_24h, 中位耗时 p50_ms, 熔断状态 breaker_state.

bash
curl "https://qihuaai.com/v1/catalog/models?type=video" -H "Authorization: Bearer $QIHUA_API_KEY"
curl "https://qihuaai.com/v1/catalog/models/seedance-2.5/lanes" -H "Authorization: Bearer $QIHUA_API_KEY"

同一模型可能有多条线路. 请求中可用 lane_id 指定线路, 或用 strategy 自动选择: cheapest (最便宜), stable (成功率优先), balanced (默认).

价格预估

POST /v1/pricing-estimate 不扣费, 返回本次请求将收取的 credits 和当前余额. 使用 API Key 调用时, 结果已考虑该 Key 的锁定线路.

bash
curl https://qihuaai.com/v1/pricing-estimate \
  -H "Authorization: Bearer $QIHUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "seedance-2.5", "params": {"prompt": "雨夜街道", "duration": "5"}, "strategy": "cheapest"}'
json
{
  "model": "seedance-2.5",
  "lane_id": "seedance-b",
  "strategy": "cheapest",
  "unit": "per_second",
  "unit_price": "4",
  "units": "5",
  "lines": [{"component": "per_second", "units": "5", "unit_price": "4"}],
  "credits": 20,
  "balance_credits": 5000,
  "enough_balance": true
}

图片 / 视频 / 音频生成

POST /v1/media/generate, 请求体 {"model", "params", "lane_id"?, "strategy"?}, params 按模型的 param_schema 填写. 图片和语音合成同步返回结果; 视频返回任务, 需要轮询. 生成失败时预扣的 credits 全额退回.

bash
curl https://qihuaai.com/v1/media/generate \
  -H "Authorization: Bearer $QIHUA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"model": "seedance-2.5", "params": {"prompt": "雨夜街道上漂流的纸船", "duration": "5"}}'
json
{"task_id": "0192...", "model": "seedance-2.5", "lane_id": "seedance-a", "status": "pending",
 "estimated_completion_seconds": 180, "estimated_cost_credits": 25}

用 GET /v1/tasks/{task_id} 轮询, 建议间隔不低于 10 秒, 直到 status 为 succeeded 或 failed. 成功时 output 中包含结果地址 (video_url / urls / audio_url), actual_cost_credits 为实际扣费.

python
import time
import requests

API = "https://qihuaai.com/v1"
headers = {"Authorization": "Bearer qh_your_api_key"}

task = requests.post(
    f"{API}/media/generate",
    headers=headers,
    json={"model": "seedance-2.5", "params": {"prompt": "雨夜街道上漂流的纸船", "duration": "5"}},
    timeout=60,
).json()

while task["status"] not in ("succeeded", "failed"):
    time.sleep(10)
    task = requests.get(f"{API}/tasks/{task['task_id']}", headers=headers, timeout=30).json()

print(task["status"], task.get("output"), task.get("actual_cost_credits"))

错误码

非 2xx 响应统一为下面的结构, 排查问题时请提供 request_id:

json
{"error": {"code": "INSUFFICIENT_CREDITS", "message": "...", "message_zh": "...", "request_id": "...", "details": {}}}
codeHTTP说明
INVALID_REQUEST400参数缺失或不合法, 详情见 error.details.field.
MODEL_NOT_FOUND400模型不存在或已下线.
UNAUTHORIZED401缺少或无效的 API Key.
INSUFFICIENT_CREDITS402余额不足, 请充值后重试.
PLAN_REQUIRED403Key 的模型白名单不包含该模型, 或套餐不支持.
KEY_REVOKED403Key 已撤销.
BLOCKED403账号被限制使用.
FORBIDDEN403无权执行该操作, 例如 Key 已锁定线路却指定了其他线路或模型.
TASK_NOT_FOUND404任务不存在或不属于当前账号.
IDEMPOTENCY_CONFLICT409同一 Idempotency-Key 的请求仍在处理中或请求体不同.
MODEL_REJECTED422上游模型拒绝了该请求 (内容审核).
RATE_LIMITED429超出每分钟请求数或 Key 的每日额度, 见 Retry-After 响应头.
DAILY_VIDEO_QUOTA_EXCEEDED429今日视频生成次数已用完.
INTERNAL_ERROR500服务内部错误, 请带上 request_id 联系客服.
UPSTREAM_ERROR502上游生成失败, 本次未扣费.
UPSTREAM_UNAVAILABLE503所选线路暂时不可用, 稍后重试或换线路.
UPSTREAM_TIMEOUT504上游超时, 本次未扣费.

限流与额度

  • 每个 API Key 默认 60 次/分钟, 可在 Key 设置中调整 (1-10000). 超出返回 429 RATE_LIMITED, 带 Retry-After (秒) 响应头, 请按它退避重试.
  • 每日额度: 按 UTC 自然日统计该 Key 已扣费和进行中的预估费用, 超出返回 429 RATE_LIMITED, details.scope 为 api_key_daily_credit_limit.
  • 模型白名单: 设置后该 Key 只能调用名单内的模型, 其他模型返回 403 PLAN_REQUIRED.
  • 锁定线路: 该 Key 只能使用指定线路及其所属模型, 请求中指定其他 lane_id 或模型返回 403 FORBIDDEN.
  • 视频生成另有每日次数上限, 超出返回 429 DAILY_VIDEO_QUOTA_EXCEEDED.