用 curl 把图片变成 GLB
一段简短的 Bash 流程就能提交图片、持续查看同一个任务并下载 GLB。无需专用 TO3D CLI;生成与绑骨是两个独立任务。
已于 2026 年 9 月 27 日核验
开始之前
在控制台创建 API key 并放入环境变量。图片 URL 必须能被服务访问;image-to-3d 接受 URL 或 base64 的 PNG、JPEG、GIF,大小上限为 128 MB。
- 每个请求都使用 x-api-key 请求头。
- 生成任务返回 202,并从 pending 进入 processing,随后变为 succeeded、failed 或 canceled。
- 如果提供商没有完成任务,failed 或 canceled 任务会自动退款。
export TO3D_KEY='your_api_key'
export TO3D_IMAGE_URL='https://example.com/photo.png'
BASE='https://api.to3d.app'提交一张图片
把图片 URL POST 到 Trellis。先保存返回的 id;轮询和下载都使用这个 id,不会创建新的付费任务。
- 发送 task_type image-to-3d。
- 将图片 URL 放在 input.image 中。
- 把响应 id 当作不透明值处理,完全按返回内容保存。
TASK_JSON=$(curl -sS --fail-with-body "$BASE/api/trellis/tasks" \
-H "x-api-key: $TO3D_KEY" -H 'Content-Type: application/json' \
-d "$(jq -cn --arg image "$TO3D_IMAGE_URL" '{task_type: "image-to-3d", input: {image: $image}}')")
TASK_ID=$(jq -er '.id' <<<"$TASK_JSON")
printf 'Task: %s\n' "$TASK_ID"轮询并下载 GLB
使用同一个任务 id 查询状态。成功响应包含 output.model_file,这是无需 API key 也能下载的持久 URL。
- 每次检查之间等待 5 秒,并按你的任务设置循环上限。
- 循环超时后不要重新提交;稍后检查原始任务 id。
- 交给查看器或引擎前,检查文件开头四个字节是否为 glTF。
MODEL_URL=''
for ((attempt = 0; attempt < 120; attempt++)); do
STATUS_JSON=$(curl -sS --fail-with-body "$BASE/api/trellis/tasks/$TASK_ID" -H "x-api-key: $TO3D_KEY")
STATUS=$(jq -er '.status' <<<"$STATUS_JSON")
case "$STATUS" in
succeeded) MODEL_URL=$(jq -er '.output.model_file' <<<"$STATUS_JSON"); break ;;
failed|canceled) jq '{id,status,error}' <<<"$STATUS_JSON" >&2; exit 1 ;;
pending|processing) sleep 5 ;;
esac
done
[ -n "$MODEL_URL" ] || { echo "Timed out; keep the task id" >&2; exit 1; }
curl -fsSL "$MODEL_URL" -o model.glb
[ "$(head -c 4 model.glb)" = glTF ]可选:为结果绑骨
绑骨是对已下载 GLB 的第二次请求。只有需要 humanoid 骨架时才创建 Skin Tokens 任务,并用同样模式轮询。
- 向 /api/skin_tokens/tasks 发送 task_type rig。
- 将 input.model 设置为 GLB URL 或 base64 GLB,并选择 original、mixamo 或 ue5 骨骼名称。
- 绑骨端点会在自己的任务完成后返回 output.model_file。
curl -sS --fail-with-body "$BASE/api/skin_tokens/tasks" \
-H "x-api-key: $TO3D_KEY" -H 'Content-Type: application/json' \
-d '{"task_type":"rig","input":{"model":"https://storage.to3d.app/tasks/example/model.glb","bone_names":"mixamo"}}'失败与超时
临时 503 或本地轮询超时都不是重新创建任务的理由。先查询原始 id,再读取状态和错误详情。
- 对临时 HTTP 请求使用退避重试,同时保持相同的任务 id。
- 400 表示请求结构或输入无效;401 表示密钥缺失或无效。
- 任务的 404 响应只对创建该任务的账户开放。
curl -sS "$BASE/api/trellis/tasks/$TASK_ID" -H "x-api-key: $TO3D_KEY" | jq '{id,status,output,error}'