AI Goes API
基址:
- 线上:
https://av18.ai或https://ai.stokefuser.com - 本地:
http://localhost:3000
文档对照 app/api/**/route.ts。没有 Stripe webhook、找回密码,作品列表也没有 cursor 分页。
约定
- 除上传外,请求体为 JSON,
Content-Type: application/json。 - 上传用
multipart/form-data,字段名必须是file。 - 会话 Cookie:
ai_goes_session(HttpOnly)。POST /api/auth/register和POST /api/auth/login会Set-Cookie。之后浏览器自动带上。 - 长期 API Token:设置页生成,格式
agk_+ 64 位 hex。请求头Authorization: Bearer agk_...。明文只在创建时返回一次。 - Cookie 与 Bearer 二选一即可;有 Bearer 时优先用 Token。
- 未登录常见响应:
401{"error":"Unauthorized"}。GET /api/auth/me例外,返回{"user":null}。 - 错误体:
{"error":"..."}。上游 A2E / 生成失败时可能带details。 - 积分不足:
402{"error":"Insufficient credits"}。 POST /api/a2e/generate与POST /api/generate是同一个处理函数。
浏览器示例(登录后复用 Cookie):
curl -c cookies.txt -b cookies.txt -H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"at-least-8"}' \
https://av18.ai/api/auth/login脚本示例(设置页生成 Token 后):
curl -H "Authorization: Bearer agk_..." \
https://av18.ai/api/credits健康
GET /api/health
公开。探测进程和一次 SQLite 查询。
| 状态 | 响应 |
|---|---|
| 200 | {"ok":true} |
| 503 | {"ok":false} |
账号
POST /api/auth/register
公开。第一个注册的账号 role 为 admin,之后为 user。新用户赠送 100 积分(reason=signup)。
Body:
{ "email": "you@example.com", "password": "at-least-8" }| 字段 | 规则 |
|---|---|
email | 必填,去空格并转小写 |
password | 必填,至少 8 位 |
成功 200:
{
"user": {
"id": "clx...",
"email": "you@example.com",
"role": "admin",
"credits": 100
}
}并设置 Cookie ai_goes_session。
| 状态 | 含义 |
|---|---|
| 400 | 邮箱格式无效,或密码不足 8 位 |
| 409 | 邮箱已注册 |
POST /api/auth/login
公开。
Body:{"email":"...","password":"..."}
成功 200:{"user":{"id","email","role","credits"}},并设置 Cookie。
| 状态 | 含义 |
|---|---|
| 401 | 邮箱或密码错误 |
POST /api/auth/logout
可不登录。清空 Cookie。
成功 200:{"ok":true}
GET /api/auth/me
可不登录。
| 情况 | 响应 |
|---|---|
| 未登录 | {"user":null} |
| 已登录 | {"user":{"id","email","role","credits"}} 或用户已删时 {"user":null} |
GET /api/account/token
需登录(Cookie 或自己的 Bearer)。列出未撤销的 Token,不含明文。
成功 200:
{
"tokens": [
{
"id": "clx...",
"prefix": "agk_ab12",
"createdAt": "2026-09-13T00:00:00.000Z",
"lastUsedAt": null
}
]
}POST /api/account/token
需登录。无 body。生成一把长期 Token,明文只在这次响应里出现。
成功 200:
{ "id": "clx...", "prefix": "agk_ab12", "token": "agk_..." }DELETE /api/account/token
需登录。
Body:{"id":"clx..."}
成功 200:{"ok":true}
| 状态 | 含义 |
|---|---|
| 400 | 缺少 id |
| 404 | 不是自己的 Token,或已撤销 |
积分
GET /api/credits
需登录。当前余额 + 最近 20 条流水(新的在前)。
成功 200:
{
"credits": 130,
"transactions": [
{
"id": "clx...",
"userId": "clx...",
"amount": 30,
"balance": 130,
"reason": "checkin",
"ref": "2026-09-13",
"createdAt": "2026-09-13T00:00:00.000Z"
}
]
}reason 常见值:signup checkin plan generate refund admin。
签到
自然日按 Asia/Shanghai。每天一次,漏领不补。额度:免费 30,有效期内 Pro 60,Ultra 90。
GET /api/checkin
需登录。
成功 200:
{
"claimed": false,
"amount": 30,
"tier": "free",
"expiresAt": null,
"day": "2026-09-13"
}| 字段 | 说明 |
|---|---|
claimed | 今天是否已领 |
amount | 按当前档位,今天能领或已领的数额 |
tier | free / pro / ultra |
expiresAt | 套餐到期 ISO 时间;免费为 null |
day | 上海自然日 YYYY-MM-DD |
POST /api/checkin
需登录。无 body。
成功 200:上述字段 + credits(领取后余额)。
当天再领:409
{
"error": "Already claimed today",
"claimed": true,
"amount": 30,
"tier": "free",
"expiresAt": null,
"day": "2026-09-13"
}界面不应再加分。当天已领后再买 Pro,amount 会变成 60,但 claimed 仍为 true,不能当天再领 60。
结账
POST /api/billing/checkout
需登录。当前是 模拟支付(订单 status=mock_paid),积分立刻到账。订阅 SKU 会写档位和到期日;加量包只加积分。
Body:
{ "planId": "pro-1m" }planId:
| SKU | 类型 | 立刻到账积分 |
|---|---|---|
pro-1m | 订阅 1 个月 | 1500 |
pro-3m | 订阅 3 个月 | 4500 |
pro-1y | 订阅 12 个月 | 18000 |
ultra-1m | 订阅 1 个月 | 9000 |
ultra-3m | 订阅 3 个月 | 27000 |
ultra-1y | 订阅 12 个月 | 108000 |
topup-1800 | 加量 | 1800 |
topup-16000 | 加量 | 16000 |
成功 200:
{ "orderId": "clx...", "credits": 1630, "granted": 1500 }| 状态 | 含义 |
|---|---|
| 400 | 未知 planId |
管理
POST /api/admin/grant
需登录且 role=admin。给指定用户加积分,流水 reason=admin。
Body:
{ "email": "user@example.com", "amount": 100 }amount 必须是正数,按整数入账。
成功 200:{"email":"user@example.com","credits":200}(目标用户最新余额)
| 状态 | 含义 |
|---|---|
| 403 | 不是管理员 |
| 400 | 邮箱或金额无效 |
| 404 | 用户不存在 |
生成
POST /api/generate
需登录。先按报价扣积分,再调上游;提交失败会退款。任务立刻失败也会退(reason=refund)。
POST /api/a2e/generate 与此相同。
Body(GeneratePayload,只列真实字段):
{
"modelId": "kling-3",
"tool": "text-to-video",
"prompt": "一只猫在走路",
"name": "可选标题",
"imageUrl": "https://...",
"imageUrl2": "https://...",
"videoUrl": "https://...",
"audioUrl": "https://...",
"fileUrl": "https://...",
"pageUrl": "https://...",
"wanPrime": false,
"duration": "5",
"aspectRatio": "16:9",
"resolution": "720p",
"audio": false,
"sourceLang": "zh",
"targetLang": "en",
"gender": "female",
"userVoiceId": "voice-or-anchor-id"
}| 字段 | 说明 |
|---|---|
modelId | 目录 id,如 kling-3 wan-2-6 hailuo minimax-h3 |
tool | 模式,必须属于该模型的 modes |
prompt | 多数模型必填;见下表 |
| 媒体 URL | 先 POST /api/a2e/upload 得到 |
tool 取值:text-to-video image-to-video text-to-image image-edit talking-photo talking-video face-swap head-swap cloth-swap motion-transfer upscale caption-removal voice-clone voice-tts dubbing avatar-train avatar-speak product-avatar first-last-frames reference。
必填(服务端校验):
| 条件 | 要求 |
|---|---|
| 目录要求提示词 | prompt 非空 |
voice-tts | prompt、userVoiceId |
avatar-speak | audioUrl、userVoiceId |
image-to-video 且模型没有 inputs | imageUrl |
first-last-frames | imageUrl 与 imageUrl2 |
reference 且 modelId=wan-3-0 | 至少一种参考;fileUrl 与 pageUrl 不能同时有;pageUrl 必须以 http 开头 |
其他 reference | imageUrl |
其余带 inputs 的模型 | 标记 required 的媒体字段必须有值 |
配音 sourceLang / targetLang 仅允许:zh en ja ko es fr de。非法时分别回落到 zh / en。
成功 200:
{
"id": "upstream-task-id",
"cost": 25,
"task": {
"id": "upstream-task-id",
"provider": "kling-3",
"tool": "text-to-video",
"status": "processing",
"rawStatus": "...",
"prompt": "...",
"name": "...",
"mediaUrls": [],
"account": "you@example.com"
},
"raw": {}
}task.status:processing completed failed unknown。
| 状态 | 含义 |
|---|---|
| 400 | 模型/模式不支持,或缺提示词/素材 |
| 402 | 积分不足 |
上传
POST /api/a2e/upload
需登录。multipart/form-data,字段 file。
- 最大 50MB
- 允许:
image/*video/*audio/*,以及 pdf / doc / docx / ppt / pptx / xls / xlsx / txt / md / key / pages / numbers
成功 200:{"url":"https://..."}(把这个 URL 填进 generate 的媒体字段)
| 状态 | 含义 |
|---|---|
| 400 | 没有 file、超过 50MB、或不支持的类型 |
任务与作品
轮询和列表会 hydrate 进行中的任务;失败会按规则退积分(同一任务不重复退)。
GET /api/a2e/task
需登录。Query:
| 参数 | 说明 |
|---|---|
provider | 提交时的 modelId |
id | 上游任务 id(a2eTaskId) |
必须是当前用户自己的任务。
成功 200:{"task":{...},"raw":null}。task 可能为 null。
| 状态 | 含义 |
|---|---|
| 400 | 缺少 provider 或 id |
| 404 | 不是自己的任务 |
GET /api/a2e/assets
需登录。当前用户最近 80 条任务(hydrate 后)。
成功 200:{"tasks":[...]}
GET /api/a2e/records
需登录。Query 均可选:
| 参数 | 说明 |
|---|---|
tool | 按模式筛 |
provider | 按 modelId 筛 |
pageSize | 默认 18,限制在 1–50 |
成功 200:{"tasks":[...]}
没有下一页 cursor。
GET /api/account/history
需登录。任务最多 50 条,流水最多 50 条。进行中的任务会先 hydrate。
成功 200:
{
"email": "you@example.com",
"credits": 130,
"jobs": [
{
"id": "clx...",
"a2eTaskId": "upstream-id",
"createdAt": "2026-09-13T00:00:00.000Z",
"provider": "kling-3",
"tool": "text-to-video",
"creditsCharged": 25,
"status": "processing",
"error": "可选",
"prompt": "...",
"name": "..."
}
],
"transactions": [
{
"id": "clx...",
"createdAt": "2026-09-13T00:00:00.000Z",
"amount": -25,
"balance": 105,
"reason": "generate",
"ref": "kling-3"
}
]
}| 状态 | 含义 |
|---|---|
| 404 | 会话用户在库中不存在 |
上游探测
这两个接口 不鉴权,读的是服务器配置的 A2E 账号,不是当前登录用户。
GET /api/a2e/status
| 情况 | 响应 |
|---|---|
| 未配置 token | {"configured":false} |
| token 可用 | {"configured":true,"ok":true} |
| token 失败 | 4xx/5xx + error |
GET /api/a2e/credits
| 情况 | 响应 |
|---|---|
| 未配置 | {"configured":false,"coins":null,"diamonds":null} |
| 已配置 | {"configured":true,"coins":123,"diamonds":0} |
鉴权速查
| 接口 | 鉴权 |
|---|---|
GET /api/health | 无 |
POST /api/auth/register login logout | 无 |
GET /api/auth/me | 无(未登录返回 user: null) |
GET /api/a2e/status GET /api/a2e/credits | 无(工作室 A2E 账号) |
GET/POST/DELETE /api/account/token | Cookie 或 Bearer |
其余 /api/* | Cookie 或 Authorization: Bearer;/api/admin/grant 还要 admin |