3D 生成POST
根据参考图片生成三维模型文件。任务异步执行,完成后从私有存储下载模型文件。
POST https://api.tokentosea.com/v1/3d/generations
提交一个 3D 生成任务,接口返回 202 和结果信封。平台在后台查询厂商任务,完成后把模型文件转存到私有存储,并按次结算。
前提:全能密钥或模型密钥,账户可用余额足以覆盖一次调用。Python 示例需要 pip install requests,Node.js 示例需要 Node.js 18+。
支持的型号#
| 服务商 | 型号 | 说明 |
|---|---|---|
| 豆包 | doubao-seed3d-2-0-260328 | Seed3D 2.0,按成功请求计费 |
以 GET /v1/models 为准。只支持 JSON 请求。
请求体#
请求体使用方舟内容生成任务的原生格式,除 model 外原样转发给厂商。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 必填 | doubao-seed3d-2-0-260328 |
content | array | 必填 | 内容项数组:一个参考图项与一个文本参数项 |
content[].type | string | 必填 | image_url 或 text |
content[].image_url.url | string | 图片项必填 | 参考图 URL,厂商需能公网访问 |
content[].text | string | 可选 | 生成参数,以命令行标志书写,例如 --subdivisionlevel medium --fileformat glb。可用标志与取值以火山方舟文档中该型号的说明为准 |
响应#
提交后返回 202:
202 响应
{ "id": "result_…", "run_id": "cm2…", "status": "upstream_pending" }完成后 GET /v1/results/{key} 或 GET /v1/tasks/{id} 返回:
完成后的结果(节选)
{
"id": "result_…",
"status": "succeeded",
"billing_status": "succeeded",
"output": {
"model": "doubao-seed3d-2-0-260328",
"data": [{ "url": "https://…?sign=…", "asset_id": "asset_…", "mime_type": "model/gltf-binary" }]
}
}文件格式取决于 --fileformat;mime_type 为实际检测到的类型(例如 GLB 为 model/gltf-binary,压缩包为 application/zip)。url 最多 300 秒内有效,过期后用 GET /v1/assets/{asset_id}/download-url 重新获取,文件保留 30 天。
示例#
REQUEST_KEY="$(uuidgen)"
curl https://api.tokentosea.com/v1/3d/generations \
-H "Authorization: Bearer $TOKENTOSEA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $REQUEST_KEY" \
-d '{
"model": "doubao-seed3d-2-0-260328",
"content": [
{"type": "text", "text": "--subdivisionlevel medium --fileformat glb"},
{"type": "image_url", "image_url": {"url": "https://example.com/object.png"}}
]
}'
# 查询进度
curl "https://api.tokentosea.com/v1/results/$REQUEST_KEY" \
-H "Authorization: Bearer $TOKENTOSEA_API_KEY"import os
import time
import uuid
import requests
API = "https://api.tokentosea.com/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["TOKENTOSEA_API_KEY"]}
IMAGE_URL = "https://example.com/object.png"
request_key = str(uuid.uuid4())
submitted = requests.post(
API + "/3d/generations",
headers={**HEADERS, "Idempotency-Key": request_key},
json={
"model": "doubao-seed3d-2-0-260328",
"content": [
{"type": "text", "text": "--subdivisionlevel medium --fileformat glb"},
{"type": "image_url", "image_url": {"url": IMAGE_URL}},
],
},
timeout=120,
)
if submitted.status_code != 202:
raise RuntimeError(f"{submitted.status_code}: {submitted.text}")
while True:
time.sleep(10)
result = requests.get(API + "/results/" + request_key, headers=HEADERS, timeout=30).json()
if result["status"] in ("succeeded", "failed"):
break
if result["status"] == "failed":
raise RuntimeError(result.get("error"))
asset = result["output"]["data"][0]
with open("model.glb", "wb") as file:
file.write(requests.get(asset["url"], timeout=300).content)
print("saved model.glb", asset["mime_type"])import { randomUUID } from 'node:crypto';
import { writeFile } from 'node:fs/promises';
const API = 'https://api.tokentosea.com/v1';
const headers = { Authorization: `Bearer ${process.env.TOKENTOSEA_API_KEY}` };
const IMAGE_URL = 'https://example.com/object.png';
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const requestKey = randomUUID();
const submitted = await fetch(`${API}/3d/generations`, {
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json', 'Idempotency-Key': requestKey },
body: JSON.stringify({
model: 'doubao-seed3d-2-0-260328',
content: [
{ type: 'text', text: '--subdivisionlevel medium --fileformat glb' },
{ type: 'image_url', image_url: { url: IMAGE_URL } },
],
}),
});
if (submitted.status !== 202) throw new Error(`HTTP ${submitted.status}: ${await submitted.text()}`);
let result;
do {
await sleep(10_000);
result = await (await fetch(`${API}/results/${requestKey}`, { headers })).json();
} while (!['succeeded', 'failed'].includes(result.status));
if (result.status === 'failed') throw new Error(JSON.stringify(result.error));
const asset = result.output.data[0];
await writeFile('model.glb', Buffer.from(await (await fetch(asset.url)).arrayBuffer()));
console.log('saved model.glb', asset.mime_type);错误#
| 状态码 | code | 原因与处理 |
|---|---|---|
422 | endpoint_not_verified | 型号未开放本接口 |
4xx | provider_http_<状态码> | 厂商拒绝(例如参数标志无效、图片不可访问),未扣费 |
任务提交后的失败体现在结果的 status: "failed" 中,未成功生成的任务不扣费。