# APIstable > Multimodal API platform preview. English and 简体中文 documentation. > 多模型 API 平台预览。真实供应商与支付尚未接入。 ## Current availability / 当前可用范围 - GET /v1/models and POST /v1/quotes are public preview endpoints. Quotes do not reserve credits. - GET /v1/tasks, GET /v1/tasks/{id}, and GET /v1/balance require a valid API key with usage:read and a connected database. - POST /v1/tasks and POST /v1/chat/completions require generations:write. Live execution currently returns HTTP 503 provider_not_configured. There is no real successful generation or credit charge. - The website’s explicitly labeled demo workflow is separate from real provider execution. - Current HTTP fields and implemented responses are defined in OpenAPI. Live acceptance, SSE, callback verification, full provider mapping, and paid execution are later integration work. - [OpenAPI specification / 接口规范](https://0.0.0.0:3000/openapi.json) - [Your first request / 发起第一条请求](https://0.0.0.0:3000/docs): From one API key to a clear, traceable generation flow. - [Authentication / 认证与密钥](https://0.0.0.0:3000/docs/authentication): Website sessions and application API keys serve different purposes. - [List models / 模型目录](https://0.0.0.0:3000/docs/models): Discover exact model IDs, capabilities, and availability. - [Get a quote / 获取报价](https://0.0.0.0:3000/docs/quotes): See eligible channel prices and the maximum credit reservation. - [Create a task / 创建生成任务](https://0.0.0.0:3000/docs/create-task): Submit asynchronous image, video, or music work. - [Query a task / 查询任务](https://0.0.0.0:3000/docs/query-task): Read each result as it finishes, with its own status and cost. - [Multiple results / 一次生成多个结果](https://0.0.0.0:3000/docs/outputs): One request. Up to four independent image or video results. - [Routing & fallback / 路由与失败回退](https://0.0.0.0:3000/docs/fallback): Lower-cost routes first. Explicit permission for official fallback. - [Credits & billing / 积分与计费](https://0.0.0.0:3000/docs/credits): Buy credits in USD. See exactly how each result is charged. - [Music works & assets / 音乐作品与资产](https://0.0.0.0:3000/docs/music): A generated work can contain audio, cover art, and lyrics. - [Callbacks & polling / 回调与轮询](https://0.0.0.0:3000/docs/webhooks): Generation state, credit settlement, and delivery are separate. - [Errors & idempotency / 错误与幂等](https://0.0.0.0:3000/docs/errors): Recover safely without duplicating generations or charges. - [LLM & streaming / LLM 与流式输出](https://0.0.0.0:3000/docs/llm): A scoped Chat Completions interface with explicit stream behavior. ## Core contract / 核心约定 - USD purchases credits; generation consumption uses credits. Preview prices are illustrative. - Image/video output_count defaults to 1 and allows 1–4 independent target items. This is a quantity, not a guarantee of simultaneous execution. - Music native works/assets are not multiplied by output_count. Music and LLM currently require output_count=1. - fallback defaults to false. Planned initial live routing is a compatible low-cost route, then an authorized official route after a confirmed eligible failure; at most two attempts per item. - Canonical parameters must be mapped without silent deletion or degradation. If official fallback cannot satisfy all parameters, fallback=true must be rejected before live acceptance. - Charge each item by its final successful channel. Official success costs more; parent tasks can contain mixed channels. - max_credits caps the entire maximum reservation. A lower cap rejects the entire request before generation. - Example only: four items reserve 240; two low-cost successes at 20, one official success at 60, one failure charge 100 and release 140. - Unknown upstream results require reconciliation, not duplicate generation. Fetching an already-generated asset may be retried without generating again. - After a final release, a late result must not silently recharge the account. ## Your first request / 发起第一条请求 From one API key to a clear, traceable generation flow. 从一套 API 密钥,到可追踪、可核对的生成流程。 POST /v1/tasks ### Start with the preview / 先了解当前预览 APIstable is being built in two stages: the website, account system, and execution architecture first; real model providers next. The model catalog and prices currently illustrate the contract. They are not a claim that paid inference is available. APIstable 分两步建设:先完成网站、账户与执行架构,再接入真实模型供应商。当前模型目录与价格用于展示接口约定,不代表付费推理已经可用。 Examples on these pages describe the API preview. A provider-not-configured response is expected until a route is enabled. Copying a code example does not execute it or spend credits. 本页示例说明 API 预览契约。渠道未启用时,应返回供应商尚未配置的错误。复制代码不会执行请求或扣积分。 ### What works in this build / 当前版本的实际行为 | Endpoint / 端点 | Current behavior / 当前行为 | | --- | --- | | GET /v1/models / GET /v1/models | Public preview catalog; no key required. / 公开预览目录,无需密钥。 | | POST /v1/quotes / POST /v1/quotes | Public input validation and sample pricing; no key required and no credit reservation. / 公开参数校验与示例报价,无需密钥,不冻结积分。 | | GET /v1/balance / GET /v1/balance | Requires a valid key with usage:read and a connected database. / 需要 usage:read 权限的有效密钥和可用数据库。 | | GET /v1/tasks and /v1/tasks/{id} / GET /v1/tasks 与 /v1/tasks/{id} | Reads stored account tasks with usage:read; an unknown ID returns 404. / 使用 usage:read 读取账户存储任务,未知 ID 返回 404。 | | POST /v1/tasks and /v1/chat/completions / POST /v1/tasks 与 /v1/chat/completions | After authentication and applicable validation: HTTP 503 provider_not_configured; no live generation or credit charge. / 认证及适用校验后返回 HTTP 503 provider_not_configured,不真实生成或扣费。 | ### 1. Create an API key / 1. 创建 API 密钥 Sign in and open Console → API Keys. Save the complete key when it is created; it is only revealed once. Use a separate key for each app or environment. 登录后进入控制台 → API Keys。创建时立即保存完整密钥,它只显示一次。建议每个应用或环境使用独立密钥。 ``` export APISTABLE_BASE_URL="https://api.example.com" export APISTABLE_API_KEY="YOUR_API_KEY" export APISTABLE_IDEMPOTENCY_KEY="YOUR_UNIQUE_OPERATION_KEY" ``` Note: Replace the example origin with your APIstable deployment. API keys belong in your server environment, never in browser code, query strings, or public repositories. 说明:将示例域名替换为实际部署地址。密钥只放在服务端环境变量中,不能写入浏览器代码、URL 或公开仓库。 ### 2. Quote, then submit / 2. 估价并提交 Choose an exact model ID and validate the input. A quote shows the eligible low-cost and official routes, the price per result, and the maximum reservation for the whole request. Direct API clients may submit without a separate quote call; the server still calculates and validates the price. 选择精确 Model ID 并校验输入。报价展示合格的低价/官方渠道、每个结果的价格与整次最高冻结积分。API 客户端可以不单独请求报价,但服务端仍会计算并校验价格。 For images and videos, output_count creates 1–4 result items. fallback is off by default. When enabled, each item can independently try the official route after a confirmed eligible failure. 图片和视频使用 output_count 创建 1–4 个结果项。fallback 默认关闭;开启后,每项在明确可回退失败时可独立尝试官方渠道。 ### 3. Keep the task ID / 3. 保存任务 ID An accepted media request returns HTTP 202 and a stable task_id. Keep it and query that task instead of submitting again. A network timeout does not tell you whether the supplier accepted the generation. 媒体请求受理后返回 HTTP 202 和稳定的 task_id。保存 ID 并查询原任务,不要再次盲目提交。网络超时不能证明供应商未受理。 - Poll at a sensible interval and respect Retry-After. Check queued, running, falling_back, and reconciliation_required as non-final states. / 合理间隔轮询并遵守 Retry-After。queued、running、falling_back、reconciliation_required 均不是终态。 - Read each item, including successful results in a partially completed task. Download files before expires_at. / 逐项读取结果;即使其他项尚未结束,也可获取已成功项。在 expires_at 前下载文件。 - A failed notification does not invalidate a completed generation or repeat its charge. / 通知失败不改变已完成生成,也不能导致再次扣费。 Example only / 仅为示例: ```sh curl -X POST https://0.0.0.0:3000/v1/tasks \ -H "Authorization: Bearer $APISTABLE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $APISTABLE_IDEMPOTENCY_KEY" \ -d '{ "model": "prism-image-2", "input": { "prompt": "A sculptural chair in warm afternoon light", "resolution": "1024" }, "output_count": 4, "fallback": true, "max_credits": 240 }' ``` ## Authentication / 认证与密钥 Website sessions and application API keys serve different purposes. 网站会话与应用 API 密钥各司其职。 ### Use a Bearer key / 使用 Bearer 密钥 External applications authenticate with an API key in the Authorization header. Browser access to your developer console uses a login session instead. A login cookie is not a replacement for your application key. 外部应用在 Authorization 请求头中携带 API 密钥。浏览器进入控制台使用登录会话。登录 Cookie 不能替代应用的 API 密钥。 ``` Authorization: Bearer YOUR_API_KEY Content-Type: application/json ``` ### Account and key boundaries / 账户与密钥边界 Every operation belongs to an account. A key can only access that account’s resources and the actions allowed by its scopes. Guessing another task ID never grants access. 每个操作都归属一个账户。密钥只能访问该账户且符合操作 scope 权限的资源,知道其他账户的任务 ID 也不能获取权限。 Current scopes include generations:write and usage:read. Revoking a key blocks subsequent authenticated calls. Before paid provider execution opens, key budgets must also include settled spending and outstanding reservations; a configured budget field alone is not enforcement. 当前 scope 包含 generations:write 与 usage:read。撤销密钥阻止后续认证调用。真实收费开放前,密钥预算还须计入已消费与未释放冻结;配置了预算字段本身不等于已执行限制。 ### Rotate without losing history / 轮换密钥并保留历史 - Create a replacement key, update your server, verify access, then revoke the old key. / 创建新密钥、更新服务端并验证,然后撤销旧密钥。 - Revocation does not cancel in-flight tasks or refund completed work. Use the console or another authorized key to follow existing tasks. / 撤销不会取消在途任务,也不会返还已完成费用;可通过控制台或其他有效密钥追踪原任务。 - Never include a full key when sharing logs or asking for help. Share the request ID instead. / 分享日志或寻求帮助时不要包含完整密钥,请提供 Request ID。 ## List models / 模型目录 Discover exact model IDs, capabilities, and availability. 查看精确的模型 ID、能力与可用状态。 GET /v1/models ### Use an exact model ID / 使用精确的模型 ID A model name is a display label. The model ID identifies a callable version or operation, such as text-to-image, image editing, or music continuation. Do not infer compatibility from a similar display name. 模型名称用于展示,Model ID 标识可调用的版本或操作,例如文生图、图片编辑或音乐续写。不能根据相似名称推断兼容性。 Preview entries currently use illustrative model names. Select an enabled model only after its real provider, input schema, and price rules have been verified. 当前预览目录使用示例模型名称。正式调用需选择已验证供应商、输入规范和价格规则的启用模型。 ### Read capabilities before sending / 调用前检查能力 | Field / 字段 | What to check / 检查内容 | | --- | --- | | modality / modality | Image, video, music, or LLM. / 图片、视频、音乐或 LLM。 | | input schema / 输入规范 | Required inputs, defaults, enums, and combinations. / 必填参数、默认值、枚举和组合约束。 | | availability / 可用状态 | Preview and maintenance entries are not live routes. / 预览和维护模型不等于真实可用渠道。 | | fallback support / fallback 能力 | Whether an official route supports this exact input. / 官方渠道是否支持当前完整输入。 | ### Versions and changes / 版本与变更 Accepted requests keep their model schema, route, and price snapshots. A later price edit must not retroactively change a running task. New models should include documentation and examples before becoming available. 已受理请求保留模型规范、路由和价格快照。之后的调价不能改变运行中任务。新模型应先具备文档和示例,再标记可用。 Example only / 仅为示例: ```sh curl https://0.0.0.0:3000/v1/models \ -H "Authorization: Bearer $APISTABLE_API_KEY" ``` ## Get a quote / 获取报价 See eligible channel prices and the maximum credit reservation. 查看合格渠道价格与整次最高冻结积分。 POST /v1/quotes ### Quote the complete input / 为完整参数报价 The server normalizes defaults, filters incompatible channels, and applies each remaining channel’s pricing formula. Duration, resolution, audio, quality, and output_count may all change the total. 服务端先补齐默认值、过滤不兼容渠道,再应用各渠道计价公式。时长、分辨率、音频、质量和 output_count 都可能改变总价。 The maximum reservation covers one successful route per result item, not the sum of every possible failed attempt. A quote is an estimate of accepted limits, not a promise that a preview model will run. 最高冻结覆盖每个结果项的一条成功渠道,不累加全部可能的失败尝试。报价说明受理上界,不保证预览模型可以真实运行。 ### Understand the upper bound / 理解费用上限 ``` { "is_preview": true, "model": "prism-image-2", "input": { "prompt": "A sculptural chair in warm afternoon light", "resolution": "1024" }, "output_count": 4, "estimated_credits": 80, "max_reserved_credits": 240, "channel_quotes": [ { "channel_type": "third_party", "credits": 80 }, { "channel_type": "official", "credits": 240 } ], "price_version": "preview-2026-10-29", "live_available": false } ``` Note: channel_quotes[].credits is the total for the whole batch on that route, not a per-item price. This endpoint returns an unreserved preview estimate, not a quote_id or a locked purchase offer. 说明:channel_quotes[].credits 是整批使用该渠道的总价,不是单项价格。此端点返回未冻结的预览估价,不签发 quote_id,也不是已锁定的购买要约。 ### Set max_credits / 设置 max_credits max_credits is your cap for the entire request. If the server’s maximum reservation is higher, it rejects the whole submission before any generation. It does not silently reduce output_count or divide a smaller budget between items. max_credits 是整次请求的费用上限。如果服务端最高冻结超过它,必须在生成前拒绝整批;不能静默减少 output_count,也不在各项之间动态分配不足预算。 Example only / 仅为示例: ```sh curl -X POST https://0.0.0.0:3000/v1/quotes \ -H "Authorization: Bearer $APISTABLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "prism-image-2", "input": { "prompt": "A sculptural chair in warm afternoon light", "resolution": "1024" }, "output_count": 4, "fallback": true, "max_credits": 240 }' ``` ## Create a task / 创建生成任务 Submit asynchronous image, video, or music work. 提交异步图片、视频或音乐生成。 POST /v1/tasks ### Request body / 请求参数 | Parameter / 参数 | Type / 类型 | Behavior / 规则 | | --- | --- | --- | | model / model | string · required / 字符串 · 必填 | Exact model and operation ID. / 精确模型/操作 ID。 | | input / input | object · required / 对象 · 必填 | Validated against that model’s schema. / 按当前模型规范校验。 | | output_count / output_count | integer · default 1 / 整数 · 默认 1 | Images/videos only; 1–4 target items. / 仅图片/视频,目标结果项 1–4。 | | fallback / fallback | boolean · default false / 布尔值 · 默认 false | Authorizes eligible official fallback. / 授权符合条件的官方回退。 | | max_credits / max_credits | non-negative integer · optional / 非负整数 · 可选 | Maximum total reservation you accept. / 可接受的整次最高冻结。 | ### Planned live acceptance / 真实接入后的受理契约 When live execution is enabled, successful acceptance atomically records the operation, result items, credit reservation, and durable scheduling record. HTTP 202 means work is accepted, not that a model has finished. 真实执行启用后,受理成功会原子记录父操作、结果项、冻结积分和持久调度记录。HTTP 202 表示已受理,不表示模型已经完成。 With output_count=4, you receive one task ID containing four stable items. The worker schedules each item within account and provider limits. There is no guarantee that all four start simultaneously. output_count=4 返回一个包含四个稳定结果项的 task_id。Worker 在账户和供应商限制内调度,不保证四项同时开始。 Note: During this build, real provider execution is not connected. A request must not manufacture a successful model output or a completed paid generation. 说明:当前建设阶段尚未连接真实供应商。接口不能伪造生成成功或已完成的付费结果。 ### Planned idempotent acceptance / 计划中的幂等受理 Once live task acceptance is enabled, send Idempotency-Key and retain it with the input. In this build, POST /v1/tasks rejects live execution before creating an operation, so the header does not yet produce a stored operation. Reusing it with the same input refers to the original operation; changing quantity, fallback, or the credit cap should return a conflict. Deliberately generating again requires a new key and a new paid operation. 真实任务受理启用后,提交 Idempotency-Key 并与输入一起保存。当前 POST /v1/tasks 在创建操作前拒绝真实执行,尚不会因该请求头产生存储操作。同键同输入引用原操作;改变数量、fallback 或费用上限应返回冲突。主动重新生成需新幂等键和新付费操作。 Example only / 仅为示例: ```sh curl -X POST https://0.0.0.0:3000/v1/tasks \ -H "Authorization: Bearer $APISTABLE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $APISTABLE_IDEMPOTENCY_KEY" \ -d '{ "model": "prism-image-2", "input": { "prompt": "A sculptural chair in warm afternoon light", "resolution": "1024" }, "output_count": 4, "fallback": true, "max_credits": 240 }' ``` ## Query a task / 查询任务 Read each result as it finishes, with its own status and cost. 逐项获取完成结果、状态和费用。 GET /v1/tasks/YOUR_TASK_ID ### Follow the whole lifecycle / 追踪完整生命周期 | State / 状态 | Meaning / 含义 | | --- | --- | | queued / running / queued / running | Waiting for capacity or generating. / 等待容量或生成中。 | | falling_back / falling_back | An eligible failed item is switching routes. / 明确可回退失败项正在切渠道。 | | reconciliation_required / reconciliation_required | The upstream result is unknown; do not resubmit. / 上游结果不明,不要重复提交。 | | succeeded / succeeded | All target items succeeded. / 全部目标项成功。 | | partially_succeeded / partially_succeeded | All items are final, and some succeeded. / 全部项已终态,其中部分成功。 | | failed / cancelled / failed / cancelled | Final failure, or a confirmed cancellation where supported. / 明确失败,或已支持且确认的取消。 | ### Read individual items / 读取独立结果项 The same parent can contain low-cost and official successes. Never assume the final item’s channel applies to every result. This simplified example omits output URLs, errors, and timestamps. 同一父请求可以同时包含低价渠道和官方成功项,不能把最后一项的渠道应用到全部结果。以上简例省略输出 URL、错误与时间字段。 ``` { "task_id": "task_example", "status": "partially_succeeded", "output_count": 4, "counts": { "succeeded": 3, "failed": 1, "cancelled": 0, "pending": 0 }, "billing": { "initial_reserved_credits": 240, "charged_credits": 100, "released_credits": 140, "remaining_reserved_credits": 0 }, "items": [ { "index": 0, "item_id": "item_1", "status": "succeeded", "final_channel_type": "third_party", "charged_credits": 20 }, { "index": 1, "item_id": "item_2", "status": "succeeded", "final_channel_type": "third_party", "charged_credits": 20 }, { "index": 2, "item_id": "item_3", "status": "succeeded", "final_channel_type": "official", "charged_credits": 60 }, { "index": 3, "item_id": "item_4", "status": "failed", "final_channel_type": null, "charged_credits": 0 } ] } ``` ### Poll without creating extra work / 轮询而不重复生成 Query the existing task ID at intervals, honor Retry-After, and add backoff when a task takes longer. Read already completed items while other items are running. Do not hold a new generation request open as a polling mechanism. 间隔查询原 task_id、遵守 Retry-After,长任务适当退避。其他项运行时仍可读取完成项。不要通过反复创建生成请求进行查询。 Download before the returned expires_at. File expiry does not change the historical success state or automatically refund credits. 在返回的 expires_at 前下载文件。文件过期不改变历史成功状态,也不会自动退积分。 Example only / 仅为示例: ```sh curl https://0.0.0.0:3000/v1/tasks/YOUR_TASK_ID \ -H "Authorization: Bearer $APISTABLE_API_KEY" ``` ## Multiple results / 一次生成多个结果 One request. Up to four independent image or video results. 一次请求,最多四个独立图片或视频结果。 ### output_count is a quantity / output_count 表示数量 Images and videos accept an integer from 1 to 4, defaulting to 1. It is the number of target results, not a promise of four simultaneous connections. Invalid counts are rejected before work starts. 图片/视频接受 1–4 的整数,默认 1。这是目标结果数,不是保证四条连接同时运行;非法数量在受理前拒绝。 The initial implementation splits the request into individual provider calls. A single item may contain a video and its thumbnail, but it still counts as one generated result. 初期把请求拆成独立供应商调用。一个结果项可以含视频与封面,仍只算一个生成结果。 ``` Operation: output_count = 4 ├─ Item 0 → low-cost success ├─ Item 1 → low-cost failure → official success ├─ Item 2 → low-cost success └─ Item 3 → low-cost failure → official failure ``` ### Same parameters, independent work / 相同参数,独立执行 All items receive the same normalized input. A fixed seed stays fixed and may produce identical results. If no seed is provided, follow the model’s random behavior; diversity is not guaranteed. 各项接收同一份规范化输入。固定 seed 会原样保留,可能产生相同结果;省略 seed 则遵循模型随机规则,不保证多样性。 Successful items are never rerun just because another item fails. Eligible failures can use their own fallback inside the original operation. After the parent is final, an explicit retry creates a new operation with a new quote. 其他项失败不能让成功项重跑。符合条件的失败项可在原父操作内独立 fallback。父操作终态后主动重做属于新操作,需重新报价。 ### Capacity and accounting / 配额与统计 - A four-result call counts as one API operation, four target items, and however many provider attempts actually ran. / 四结果调用统计为一次 API 操作、四个目标项,以及实际发生的供应商尝试。 - Each active item consumes execution capacity. Accepted items may queue when the provider concurrency limit is reached. / 每个活跃项占执行容量,供应商并发达到上限时已受理项可排队。 - Credits are reserved for all items before acceptance and settled per item, using its final successful route. / 受理前冻结全部目标项积分,每项按最终成功渠道独立结算。 ## Routing & fallback / 路由与失败回退 Lower-cost routes first. Explicit permission for official fallback. 低价优先,明确授权后再使用官方回退。 ### Fallback is opt-in / fallback 需要明确开启 fallback defaults to false. In the first release, each image/video item can try one eligible low-cost channel and, with fallback enabled, one official channel. Each item has at most two generation attempts. fallback 默认 false。首期每个图片/视频结果项先尝试一个合格低价渠道,开启后可再尝试一次官方,每项最多两次生成尝试。 With fallback off, an unavailable low-cost route does not silently become a more expensive official call. With fallback on, the official route must support the full input before acceptance. 关闭 fallback 时,低价不可用不能静默改成更贵官方调用。开启时,受理前必须确认官方支持完整输入。 ### Compatibility before price / 先兼容,再比价 Providers can use different field names, units, enums, and supported combinations for the same model. APIstable maps a versioned public schema to each eligible provider. Renaming duration_seconds to seconds is a mapping; dropping audio or changing resolution is not. 同一模型在不同供应商处可能有不同字段、单位、枚举和组合能力。APIstable 将版本化公开规范映射到合格渠道。duration_seconds 改名为 seconds 可以是映射;删除音频或改变分辨率不是。 | Requested capability / 请求能力 | Channel behavior / 渠道处理 | | --- | --- | | 5 seconds at 720p / 5 秒、720p | Accept only channels supporting the exact combination. / 只保留支持完整组合的渠道。 | | Audio enabled / 开启音频 | Exclude channels that cannot produce audio. / 过滤无法输出音频的渠道。 | | Fixed seed / 固定 seed | Do not silently remove or substitute it. / 不能静默删除或替换。 | | Official route incompatible / 官方渠道不兼容 | Reject fallback=true before acceptance. / 受理前拒绝 fallback=true。 | ### A timeout is not a safe failure / 超时不等于可以回退 A confirmed rejection before acceptance or an eligible terminal provider failure can trigger fallback. An unknown submission, running generation, content-policy rejection, or invalid input cannot be treated as a free pass to submit elsewhere. 确认未受理的错误或符合条件的上游终态失败可以触发回退。未知提交、运行中任务、内容拒绝或非法参数不能直接改投其他渠道。 Unknown results enter reconciliation. If a final decision releases the credits, a late success cannot silently recharge the account. 未知结果进入核对。若最终处理已释放积分,迟到成功不能静默重新扣费。 ## Credits & billing / 积分与计费 Buy credits in USD. See exactly how each result is charged. 美元购买积分,逐项核对结果费用。 GET /v1/balance ### Purchased, reserved, available / 购买、冻结与可用 Payment orders record USD and the number of credits issued. Model consumption is recorded in Credits. Purchased credits are not API usage. Your available balance is the ledger balance minus outstanding reservations. 支付订单记录美元与到账积分,模型消费记为 Credits。购买积分不计入 API 用量。可用积分等于账面积分减去未释放冻结。 Pricing shown during preview is illustrative. The production exchange rate, payment channel, and active channel prices must be published before paid execution is enabled. 预览价格仅为示例。正式兑换比例、支付渠道和各渠道实际费率应在开放收费前发布。 ### Read your balance / 读取账户余额 GET /v1/balance requires usage:read. It returns balance_credits, reserved_credits, and available_credits. A new account may correctly return zero. The endpoint never creates trial credits or runs a payment. GET /v1/balance 需要 usage:read,返回 balance_credits、reserved_credits 与 available_credits。新账户返回零是正常情况,端点不会创建试用积分或执行支付。 ``` { "balance_credits": 0, "reserved_credits": 0, "available_credits": 0 } ``` ### Four results, one clear total / 四个结果,一笔清晰合计 | Result / 结果 | Charge / 实扣 | Released / 释放 | | --- | --- | --- | | Low-cost success / 低价成功 | 20 Credits / 20 积分 | 40 Credits / 40 积分 | | Low-cost success / 低价成功 | 20 Credits / 20 积分 | 40 Credits / 40 积分 | | Official success / 官方成功 | 60 Credits / 60 积分 | 0 Credits / 0 积分 | | Both attempts failed / 两次尝试均失败 | 0 Credits / 0 积分 | 60 Credits / 60 积分 | | Total / 240 initially reserved / 合计 / 初始冻结 240 | 100 Credits / 100 积分 | 140 Credits / 140 积分 | Note: Example only. Failed attempts are platform costs; they are not added to the user’s bill. Each result item has at most one final consumption entry. 说明:仅为示例。失败尝试是平台成本,不额外计入用户账单。每个结果项最多一笔最终消费。 ### Prices are locked at acceptance / 受理时锁定价格 - Each channel has its own parameter-based price, including rounding, minimum units, and applicable surcharges. / 每渠道独立按参数计价,包含取整、最低单位及适用附加项。 - Official success uses the disclosed official rate; low-cost success uses the low-cost rate. A later price edit cannot increase an accepted request’s cap. / 官方成功按已披露官方价,低价成功按低价;之后调价不能提高已受理上限。 - Unknown items retain only their own reservation. Known successful and failed siblings can settle or release independently. / 未知项只保留自身冻结,已明确成功或失败的其他项可独立结算或释放。 - LLM stream interruption and native music bundles use their own published metering rules, not the image/video rule by assumption. / LLM 流式中断与音乐原生组合使用各自已发布计量契约,不能直接套用图片/视频规则。 Example only / 仅为示例: ```sh curl https://0.0.0.0:3000/v1/balance \ -H "Authorization: Bearer $APISTABLE_API_KEY" ``` ## Music works & assets / 音乐作品与资产 A generated work can contain audio, cover art, and lyrics. 一个生成作品可以包含音频、封面与歌词。 ### Count works, not file URLs / 按作品理解结果,不按 URL 数量 Music providers may return several works from one native generation. A work can contain an audio file, cover image, lyrics, and metadata. Those assets are parts of the work, not independent generations. 音乐供应商可能在一次原生生成中返回多个作品。一部作品可以包含音频、封面、歌词与元数据;这些资产是作品的组成,不是独立生成次数。 Keep the provider-defined bundle clear in the model page and price rule. A task returning two tracks must not be misreported as two user API calls. 模型页面与计价规则必须说明供应商原生组合。一次任务返回两首音乐,不能记为两次用户 API 调用。 ``` { "works": [ { "work_id": "work_example", "title": "Evening light", "assets": [ { "type": "audio", "url": "https://media.example.com/audio.mp3" }, { "type": "cover", "url": "https://media.example.com/cover.webp" }, { "type": "lyrics", "text": "Illustrative lyric content" } ] } ] } ``` Note: This is a conceptual preview, not a generated result. Actual output fields are finalized per model before provider integration. 说明:这是概念预览,不是真实生成结果;具体输出字段在各模型接入前锁定。 ### No automatic output_count multiplier / 不自动套用 output_count The new 1–4 output_count field applies to images and videos only. It does not multiply native music bundles. Music continuation, lyric creation, and song generation have distinct operation IDs and rules. 新增 1–4 的 output_count 仅用于图片与视频,不倍增音乐原生组合。音乐续写、歌词生成和歌曲生成使用不同操作 ID 与规则。 ### Partial works and delivery / 部分作品与交付 Per-work status, asset availability, and the task’s billing status must remain distinguishable. A missing thumbnail must not silently trigger another full music generation. Retry asset retrieval when a file transfer fails. 每个作品状态、资产可用性和任务计费状态需独立表达。缺少封面不能静默触发整次音乐重新生成;文件转存失败只重试资产获取。 Partial-success billing for a native multi-work task is model-specific and must be published before that model becomes billable. 原生多作品任务的部分成功计费按模型定义,必须在该模型开放收费前发布。 ## Callbacks & polling / 回调与轮询 Generation state, credit settlement, and delivery are separate. 生成状态、积分结算与通知投递独立处理。 ### Two different callback directions / 区分两种回调方向 Provider callbacks notify APIstable about an upstream task. Customer webhooks notify your application about a platform operation. They are different endpoints and use separate credentials and verification. 供应商回调通知 APIstable 上游任务状态;用户 Webhook 通知你的应用平台操作结果。两者端点、凭据与校验方式独立。 Callback support is part of the provider integration stage. Do not assume a signed production webhook is active merely because a task preview contains notification fields. 回调支持属于供应商接入阶段。不能因为任务预览有通知字段,就假定生产签名 Webhook 已启用。 ### Make receivers idempotent / 接收端保持幂等 - Verify the documented signature against the original request body before trusting an event. / 按文档针对原始请求体验证签名,再信任事件。 - Deduplicate by event ID and tolerate retries or out-of-order delivery. Query the authoritative task when unsure. / 按事件 ID 去重,容忍重试与乱序;不确定时查询权威任务状态。 - Acknowledge accepted events promptly, then process your application work in a background task. / 确认接收后尽快响应,后续应用处理放到后台。 - A failed customer notification does not regenerate media or change settled credits. / 用户通知失败不会重新生成媒体,也不改变已结算积分。 ### Polling remains a recovery path / 轮询保留为恢复路径 Providers without reliable callbacks can be polled. APIstable records the upstream task ID before scheduling later checks. A missed callback, a worker restart, or a file-download retry must not create another paid generation. 缺少可靠回调的供应商可以轮询。APIstable 保存上游 ID 后安排后续检查。漏回调、Worker 重启或文件下载重试都不能直接产生另一笔生成。 Your app can also poll the public task endpoint. Use a bounded wait and backoff; a timeout means your app stopped waiting, not that the upstream operation was cancelled. 你的应用也可轮询公开任务端点。设置等待上限并退避;停止等待不代表上游任务已取消。 ## Errors & idempotency / 错误与幂等 Recover safely without duplicating generations or charges. 安全恢复,避免重复生成和收费。 ### Handle the cause, not just HTTP status / 按原因处理,不只看 HTTP 状态 | Category / 类别 | What to do / 处理方式 | | --- | --- | | Authentication / permission / 认证 / 权限 | Check your key and model scope. Do not automatically retry. / 检查密钥与模型权限,不自动重试。 | | Invalid input / unsupported capability / 参数错误 / 能力不支持 | Correct the input. Never silently remove fields. / 修正输入,不静默删除字段。 | | Insufficient credits / cap too low / 积分不足 / 上限过低 | Review quantity, fallback, and the quote before a new submission. / 重新提交前检查数量、fallback 与报价。 | | Provider not configured / 供应商尚未配置 | Expected for preview models. No real successful output is available. / 预览模型可能返回此错误,暂无真实成功输出。 | | Upstream result unknown / 上游结果未知 | Keep the task ID and query; do not recreate the task. / 保留任务 ID 并查询,不重复创建。 | | Rate limit / 限流 | Respect Retry-After and use bounded backoff. / 遵守 Retry-After 并有限退避。 | ### One operation, one idempotency key / 一次操作,一个幂等键 Use one stable Idempotency-Key for recovery of a particular request. The fingerprint includes model, normalized input, output_count, fallback, and max_credits. The same key with different business input is a conflict. 恢复同一请求时使用稳定 Idempotency-Key。指纹包含模型、规范化输入、output_count、fallback 和 max_credits;同键不同业务输入属于冲突。 Idempotency keys are not API credentials. They prevent duplicate business acceptance, not unauthorized access. A user-requested regeneration is a new operation with a new key. 幂等键不是认证凭据;它防止重复受理,不提供访问权限。用户主动重新生成是新操作,应使用新键。 ### Give support a traceable ID / 用可追踪 ID 排错 Keep request_id, task_id, item_id, timestamp, and a sanitized error. Never send full API keys or provider credentials. Logs show the operation, each result item, its attempts, and the credit outcome. 保留 request_id、task_id、item_id、时间与脱敏错误。不要发送完整密钥或供应商凭据。日志展示父操作、各结果项、尝试与积分结果。 ## LLM & streaming / LLM 与流式输出 A scoped Chat Completions interface with explicit stream behavior. 明确兼容范围与流式行为的 Chat Completions 接口。 POST /v1/chat/completions ### Compatibility is per model / 兼容能力按模型公布 Chat Completions is the planned compatibility surface. Check messages, tools, structured output, vision, context limits, and usage support for the exact model. Do not infer complete OpenAI compatibility from the endpoint name. 计划提供 Chat Completions 兼容接口。应逐模型确认 messages、tools、结构化输出、视觉、上下文与 usage 支持,不能从端点名称推断完全兼容 OpenAI。 Real LLM providers are not connected in this build stage. The example documents the intended request; it must not return invented model text as a live completion. 当前阶段尚未接入真实 LLM 供应商。示例说明预期请求,不应将虚构文本当作真实模型返回。 ### Streaming changes recovery / 流式输出影响恢复策略 - Before visible content is sent, an eligible confirmed failure may use an authorized fallback. / 尚未向客户端发送可见内容时,符合条件的明确失败可使用已授权 fallback。 - After text, a tool call, or other visible SSE data is sent, do not restart on another supplier and concatenate a second answer. / 发送文本、工具调用或其他可见 SSE 后,不能换供应商重启并拼接第二份答案。 - A client disconnect is not automatically free. Record known usage and resolve unknown metering according to the model’s published contract. / 客户端断开不自动免费;记录已知用量,未知计量按该模型已发布契约核对。 - Tools are instructions for your application. The platform must not repeat a tool action while recovering a stream. / 工具调用由你的应用执行;平台恢复流时不能重复触发工具动作。 ### Keep platform extensions explicit / 明确平台扩展字段 If an SDK rejects custom fields such as fallback, use its supported extra-body mechanism or plain HTTP. Use only valid SDK options. The 1–4 image/video output_count field is not an LLM generation multiplier. 若 SDK 不接受 fallback 等扩展字段,使用该 SDK 支持的 extra-body 机制或普通 HTTP,不写无效选项。图片/视频的 output_count 不自动扩展为 LLM 生成数量。 Example only / 仅为示例: ```sh curl -X POST https://0.0.0.0:3000/v1/chat/completions \ -H "Authorization: Bearer $APISTABLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "nova-chat-4", "messages": [ { "role": "user", "content": "Describe this platform in one sentence." } ], "stream": true, "fallback": false }' ```