开发者文档
生成 API 文档 用生成 API,在你自己的代码里调用本站的模型创建生成任务。每个请求写明模型和它的输入;返回的是一个生成任务,你跟进它直到结束,结果文件从本站下载。本页上的模型、价格、限额和错误码都是本站当前实际执行的。
通过 API 创建生成任务需要买过付费积分包或有有效的付费订阅,而且只扣付费积分。账号的任何密钥都可以查询、列出和下载。
快速开始 在 API 密钥页创建一把密钥,只放在你的服务器上,并设成 API_KEY。下面的示例用 seed-audio-1.0 创建一个生成任务,查询到它结束,再下载第一个文件。
每个新请求发送一个新的 Idempotency-Key。请求没有收到回复时,用同一个键和同样的请求体再发一次:你拿到的是第一次请求创建的任务,只扣一次费。
cURL 复制代码 export API_ORIGIN='https://demo.freshapp.ai'
export API_KEY='sk_YOUR_API_KEY'
curl --fail-with-body "$API_ORIGIN/api/v1/generations" \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-1001' \
-d '{"model":"seed-audio-1.0","input":{"prompt":"黎明时分悬崖上的灯塔,海面平静,光线柔和。"}}'
# Read it every 5 to 10 seconds until its status ends.
curl --fail-with-body "$API_ORIGIN/api/v1/generations/GENERATION_ID" \
-H "Authorization: Bearer $API_KEY"
# A delivered output's url is a signed link: no key needed.
curl --fail-with-body -o result "OUTPUT_URL"
TypeScript 客户端 复制代码 import { createClient } from './open-api-client';
const client = createClient({
baseUrl: "https://demo.freshapp.ai",
apiKey: process.env.API_KEY, // on your server only
});
const generation = await client.create(
{
"model": "seed-audio-1.0",
"input": {
"prompt": "黎明时分悬崖上的灯塔,海面平静,光线柔和。"
}
},
{ idempotencyKey: "order-1001" }
);
const done = await client.wait(generation.id);
for (const output of done.outputs)
if (output.status === 'delivered') {
const file = await client.download(output);
// file.body is the output, as output.content_type says
}
React hook 复制代码 import { createClient } from './open-api-client';
import { useGeneration } from './open-api-react';
// In a browser on this site: no key, the visitor's own session.
const client = createClient();
export function Progress({ id }: { id: string }) {
const { generation, error, done } = useGeneration(client, id);
if (error) return <p>{String(error)}</p>;
return <p>{generation?.status ?? '…'}{done ? ' ✓' : ''}</p>;
}
密钥和权限 每个请求都在 Authorization: Bearer 里带上 API 密钥页创建的密钥。密钥是 sk_ 加 43 个字母、数字、连字符或下划线,只在创建和轮换时显示一次。带了 Authorization 的请求只按这把密钥判断,不会改用旁边的登录状态。
密钥要么只读(查列表、查任务、下载),要么还能生成(创建和取消)。只读密钥尝试创建或取消时得到 403 insufficient_scope,什么都不会写入。
密钥可以带一个由地址和网段组成的 IP 白名单:从其他地址发来的请求得到 403 ip_not_allowed。给密钥更多权限、调高上限或放宽白名单需要最近重新登录过;收紧则不需要。
轮换密钥会立刻生成新值,旧值马上失效。作废密钥后它永久失效:还没提交给模型的任务会被取消并退回积分,已经在运行的任务照常完成。
只有有付费资格的账号才能通过 API 创建任务(否则是 403 not_eligible),而且 API 只扣付费积分(不够时是 402 insufficient_credits)。赠送积分和签到积分只留给网站使用。
生成 API 接口 所有路径都在本站上。请求体和响应体都是 JSON,结果文件除外。
https://demo.freshapp.ai
方法 路径 需要的权限 作用 POST /api/v1/generationsgenerations:write创建生成任务。必须带 Idempotency-Key;返回 202 和这个任务。 GET /api/v1/generationsgenerations:read账号的生成任务,最新的在前,按页返回(limit、cursor、module)。文本任务只能按编号查询。 GET /api/v1/generations/{id}generations:read账号的一个生成任务,包括它的输出、积分和结束原因。 POST /api/v1/generations/{id}/cancelgenerations:write取消还没提交给模型的任务,并退回它的积分。 GET, HEAD /api/media/{id}generations:read (或签名链接)一个输出的文件,最多支持一个字节范围。签名链接不需要密钥,从任何地址都能打开。
模型和价格 本站已启用的模型,按 API 的写法列出:把编号填进 model,把字段填进 input。请求在创建时预留它最贵的可能结果,结束后按实际交付的部分收费。
模型编号 名称 类型 价格 单次最多 输入字段 seed-audio-1.0Seed Audio 1.0 音频 每分钟 75 积分; 交付结果时至少 10 积分 150 积分 prompt (必填), voice, audio_references, image_url, output_format, sample_rate, speed, volume, pitch, multilingual
幂等键 创建生成任务必须带 Idempotency-Key 请求头,由 1 到 128 个字母、数字、点、冒号、下划线或连字符组成。建议用你自己系统里的编号,比如订单号,这样同一件事总是用同一个键。
同一个键加同样的请求,不管发多少次都返回同一个任务,只扣一次费。同一个键加不同的请求会得到 409 idempotency_conflict,不会创建任何任务。
超时或连接中断并不代表请求失败。请用同一个键和同样的请求体再发一次,并在收到回复之前一直保留这两样。5xx、429 和 408 也一样处理:按 Retry-After 等待,然后原样再发一次。
状态和轮询 用 GET /api/v1/generations/{id} 查询任务:开始时每 5 秒一次,之后最长每 10 秒一次,直到状态结束。遇到 429 时,Retry-After 会告诉你什么时候再查。
状态 含义 queued已接受,等待提交给模型。这时还可以取消。 processing已提交给模型,或者正在保存文件和结算。 succeeded全部输出都已交付,积分已结算。 partially_succeeded部分输出已交付并收费,其余部分的积分已退回。 failed什么都没交付;error 说明原因,预留的积分已退回。 canceled提交之前被取消(由你取消,或因为密钥被作废);积分已退回。
billing.reserved_credits 是创建任务时预留的积分。结算后,charged_credits 是实际收取的积分,refunded_credits 是退回的积分;结算之前两者都是 null,held_credits 显示正在占用的积分。
等待人工核对的任务会在 review 里显示核对开始的时间,核对结束前积分一直占用;核对后任务继续,或者积分退回。
结果文件 每个已交付的输出都有一个本站上的 url。用密钥查询时,它是一个签名链接,一小时内不带密钥、从任何地址都能打开,可以直接交给下载工具。超过一小时后,再查一次任务就能拿到新的链接。
用密钥本身请求 GET /api/media/{id} 也能拿到文件,但受这把密钥的白名单限制。两种方式都支持 HEAD 和一个字节范围(Range: bytes=0-1023),并且不会跳转到别的网站。
输入里引用的文件(比如一段音频样本或一张图片)必须是这个账号在网站上上传的、本站自带的样本,或者来自本站允许的来源的链接;其他引用在预留积分之前就会被拒绝。
限额 下面每一项都是本站当前执行的限额,每次拒绝都会说明碰到了哪一项。
一次请求最多预留 150 积分,即已启用模型中最贵一次请求的费用。可以给密钥设得更低,请求里的 max_credits 能为这一次再调低;超过时返回 400 request_limit_exceeded。 每把密钥每个 UTC 日最多花 5,000 积分,可以自己设置,最高 1,000,000;超过后这把密钥得到 429 key_daily_limit_exceeded,直到下一个 UTC 日。 一个账号的所有密钥加上它授权的 AI 客户端,每个 UTC 日合计最多花 10,000 积分,可以为账号另设上限;超过后返回 429 account_daily_limit_exceeded。 每把密钥和每个账号每分钟最多创建和取消 20 次、查询和下载 240 次;超过后返回 429 rate_limited,并带 Retry-After。 一个账号同时运行的生成任务最多 2 个;再创建会得到 429 too_many_active。 请求体最多 32 KiB 的 JSON;更大的返回 413 request_too_large。 错误码 错误的格式是 {"error": {"code": …, "message": …}}。code 一定是下表中的一个,message 是写给开发者的英文说明。429 和 503 会在 Retry-After 里给出需要等待的秒数。失败或被取消的任务会在 error 字段里带上标为任务错误的码之一。
HTTP 错误码 含义 怎么处理 401 invalid_credentialAPI 密钥缺失、格式不对、不存在、已作废或已被替换。 检查 API 密钥、它的权限和白名单。 401 credential_revoked请求进行中密钥被作废或轮换;被作废密钥排队中的任务会被取消并退回积分。 检查 API 密钥、它的权限和白名单。 403 insufficient_scope这把密钥不能做这件事:错误里的 required_scope 写明了需要的权限。 检查 API 密钥、它的权限和白名单。 403 ip_not_allowed不能从这个地址使用这把密钥:它不在密钥的 IP 白名单里。 检查 API 密钥、它的权限和白名单。 401 unauthorized网站的登录已失效:请重新登录。 修改请求后再发送。 403 invalid_origin网站请求必须来自本站自身。 修改请求后再发送。 403 forbidden请求没有可信的客户端地址。 联系本站客服。 400 invalid_request请求格式不对:JSON、请求头(Idempotency-Key、Content-Type)或查询参数有误。 修改请求后再发送。 400 invalid_input输入不符合模型的字段,或者模型无法使用它。 修改请求后再发送。 413 request_too_large请求体太大。 修改请求后再发送。 409 idempotency_conflict这个 Idempotency-Key 已经用于另一个不同的请求。 修改请求后再发送。 404 model_unavailable模型不存在或当前不可用。 修改请求后再发送。 404 not_found这个账号下没有这个路径、任务或文件。 修改请求后再发送。 405 method_not_allowed这个路径不支持该方法;Allow 列出了支持的方法。 修改请求后再发送。 409 not_cancelable任务已经提交给模型,或者已经结束。 修改请求后再发送。 409 not_ready文件还没准备好。 按 Retry-After 等待后再发送。 410 expired文件已过保存期,已被删除。 修改请求后再发送。 400 request_limit_exceeded这个请求的费用会超过它的 max_credits,或超过密钥或本站的单次上限。 修改请求后再发送。 403 not_eligible通过 API 生成需要付费账号。 购买积分包或套餐:API 只扣付费积分。 403 email_unverified需要先验证账号的邮箱才能生成。 修改请求后再发送。 402 insufficient_credits积分不足:API 只扣付费积分。 购买积分包或套餐:API 只扣付费积分。 403 generation_restricted因多次内容违规,这个账号的生成暂停;ends_at 写明暂停到什么时候。 联系本站客服。 403 trial_paused这个账号有几次试用输出超出了试用限制,网站试用暂停;ends_at 写明暂停到什么时候。不用试用的请求照常进行。 修改请求后再发送。 429 key_daily_limit_exceeded已达到这把密钥的每日花费上限。 按 Retry-After 等待后再发送。 Retry-After:到下一个 UTC 日。 429 account_daily_limit_exceeded已达到账号通过 API 的每日花费上限。 按 Retry-After 等待后再发送。 Retry-After:到下一个 UTC 日。 429 rate_limited短时间内请求太多。 按 Retry-After 等待后再发送。 Retry-After:限流窗口的剩余时间。 429 too_many_active账号正在运行的任务太多。 按 Retry-After 等待后再发送。 Retry-After:30 秒。 429 too_many_under_review账号有一些任务在等待人工核对。 按 Retry-After 等待后再发送。 Retry-After:3,600 秒。 503 busy本站当前运行的任务太多。 按 Retry-After 等待后再发送。 Retry-After:30 秒。 503 paused生成暂时停止。 按 Retry-After 等待后再发送。 Retry-After:60 秒。 503 temporarily_unavailable请求暂时无法完成。 用同一个 Idempotency-Key 原样再发一次。 Retry-After:60 秒。 503 api_unavailable本站暂未开放生成。 按 Retry-After 等待后再发送。 Retry-After:60 秒。 503 retry请求进行中有内容发生了变化,比如密钥的设置。 用同一个 Idempotency-Key 原样再发一次。 Retry-After:60 秒。 503 unavailable文件暂时无法访问。 按 Retry-After 等待后再发送。 Retry-After:60 秒。 500 internal_error本站出了问题。 用同一个 Idempotency-Key 原样再发一次。 400 request_failed请求被拒绝,但没有对应的专门错误码。 联系本站客服。 400 captcha_required请完成网站的安全验证。 修改请求后再发送。 403 captcha_failed网站的安全验证没有通过。 修改请求后再发送。 503 captcha_unavailable网站的安全验证暂时不可用。 按 Retry-After 等待后再发送。 Retry-After:60 秒。 400 reference_unavailable引用的上传文件已不存在,或不属于这个账号。 修改请求后再发送。 413 reference_too_large引用的上传文件合计不能超过 10 MB。 修改请求后再发送。 503 reference_storage_unavailable引用文件的存储暂时不可用。 按 Retry-After 等待后再发送。 Retry-After:60 秒。 409 storage_quota_exceeded账号的存储空间已满。 联系本站客服。 任务里 canceled任务在提交前被取消;积分已退回。 修改请求后再发送。 任务里 submission_expired任务没能按时提交;积分已退回。 用同一个 Idempotency-Key 原样再发一次。 任务里 model_busy模型繁忙;积分已退回。 按 Retry-After 等待后再发送。 任务里 content_rejected内容安全检查拒绝了输入或输出。 修改请求后再发送。 任务里 result_expired结果没能按时保存。 联系本站客服。 任务里 generation_failed生成失败。 联系本站客服。 任务里 delivery_failed结果没能交付;积分已退回。 联系本站客服。 任务里 trial_limit_exceeded网站试用的输出超出了试用限制,没有交付;积分已退回。 修改请求后再发送。
TypeScript 客户端和 React hook TypeScript 客户端 open-api-client.ts 不需要任何其他包,可以在服务器、Worker 和浏览器里运行。在服务器上传入 baseUrl 和 apiKey;在本站的浏览器页面里两者都不传,请求会使用访客自己的登录状态。
create 会发送 Idempotency-Key(你给的,或者新生成的随机值),遇到连接中断、5xx、429 或 408 时用同一个请求重发,并按 Retry-After 等待。放弃时,错误里带着这个键,你可以稍后用它重发。传入 store(比如 localStorage)后,刷新页面也会沿用第一次的键。
wait 会一直查询任务直到结束:开始时间隔 5 秒,之后最长 10 秒,中止时立刻停下。download 下载一个输出的文件,只对本站自己的未签名链接带上密钥。
React hook open-api-react.ts 用客户端的 wait 跟进一个任务,组件卸载时停止。下载这两个文件,放在同一个目录下,并把扩展名改成 .ts。
文件下载