# Tripo API 规范(实测契约) 本文档记录 `tripocli` 在真实生产环境(studio.tripo3d.ai / api.tripo3d.ai)**实测验证过**的接口契约, 供接入方与其它 Agent 参考。带 ⚠️ 的都是踩过的坑,按实测结果书写,不是推测。 --- ## 一、鉴权 ### 1. 请求头(业务接口必带) ```http Accept: application/json Content-Type: application/json Origin: https://studio.tripo3d.ai Referer: https://studio.tripo3d.ai/ Authorization: Bearer x-tripo-device-id: ``` ⚠️ **缺少 `Origin`/`Referer` 会返回 `403 code=1017 Access denied: invalid domain`**(实测)。 ### 2. Cookie 换 JWT ``` GET /v2/studio/studio/whoami?tokenizeAs=default_jwt ``` - 鉴权:**必须用 Cookie**(`ory_kratos_session`)。⚠️ 实测**用 Bearer JWT 调这个接口会 401**。 - 响应关键字段:`tokenized`(即后续使用的 JWT,**有效期约 15 分钟**)、`expires_at`(会话到期)、`id`、`identity.traits.email`。 - Cookie `ory_kratos_session` 有效期约 **30 天**。 - ⚠️ 短时间内高频调用该接口偶发瞬时 `401`,需重试。 --- ## 二、账户 | 功能 | 方法与路径 | 说明 | |---|---|---| | 积分/会员 | `GET /v2/studio/user/profile/payment` | `data.wallet.total_credit`、`expiring_credit`、`expiring_date`;`data.member.type`、`valid_until` | | 试用额度 | `POST /v2/studio/operation/quota`(body `{}`) | `data.quota.generation.*`、`data.quota.uv_edit.*` | | 资产列表 | `GET /v2/studio/assets/v2` | ⚠️ 需要 `asset_type=mine`(实测 `model`/`personal`/`team` 等都报 `invalid asset type`)+ `type=model` | --- ## 三、生成接口 三者返回结构一致:`data.{task_id, project_id, operator_id, is_nsfw}`。 ### 1. 文生 3D ``` POST /v2/studio/operation/text_to_model ``` | 字段 | 类型 | 说明 | |---|---|---| | `prompt` | string | 必填 | | `model_version` | string | 高精度 `v3.1-20260211` / `v3.0-20250812` / `v2.5-20250123`;智能网格 `Nexus-v2.0-20260801`(P2.0,实测可用)/ `Nexus-v1.0-20260214` | | `face_limit` | int | 高精度默认 2000000;智能网格常用 25000 | | `quad` | bool | 智能网格一般 true | | `texture` / `pbr` / `delight` | bool | 默认 true | | `texture_quality` | string | `standard` / `detailed` | | `texture_alignment` | string | `original_image` | | `geometry_quality` | string | `detailed` | | `smart_poly` | bool | 智能网格模式 true | | `t_pose` | bool | 人形角色 T-Pose | | `visibility` | string | `shareable` / `private` | | `model_count` | int | 1 / 2 / 4(⚠️ 多候选时 `project.model_url` 只给一个) | ### 2. 图生 3D(⚠️ 必须带审核结果) ``` POST /v2/studio/storage/temporary_token # body: {"client":"aws","format":"png|jpg|webp"} → sts_ak / sts_sk / session_token / host / resource_bucket / resource_uri PUT https://{bucket}.{host}/{resource_uri} # AWS SigV4 直传(region us-west-2) POST /v2/studio/audit/image # body: {"image": {"bucket","key"}} → {"data":{"result":"pass"}} POST /v2/studio/operation/image_to_model ``` `image` 对象**必须**包含审核结果与来源,否则一律返回 `11002 Image audit result not found`: ```json { "image": { "bucket": "tripo-data", "key": "tripo-studio///input.webp", "image_audit_result": "pass", "image_source": "upload" }, "model_version": "v3.1-20260211", "face_limit": 2000000, "quad": false, "texture": true, "pbr": true, "delight": true, "texture_alignment": "original_image", "texture_quality": "detailed", "geometry_quality": "detailed", "smart_poly": false, "visibility": "shareable" } ``` ### 3. 多视角图生 3D ``` POST /v2/studio/operation/multiview_to_model ``` ⚠️ `image` 必须是**恰好 4 个**已审核图片对象的数组(前/左/右/后);少于 4 个返回 `1004 Invalid parameter(s)`,未审核返回 `11002`。 ### 4. 导入自己的模型(上传 glb/obj/fbx/stl) ``` POST /v2/studio/storage/temporary_token # body: {"client":"aws","format":"glb|obj|fbx|stl"} PUT https://{bucket}.{host}/{resource_uri} # AWS SigV4 直传(同图片) POST /v2/studio/operation/import_user_model ``` ⚠️ body 是**嵌套**的,`model` 里放 S3 对象(实测): ```json { "format": "glb", "model": {"bucket": "tripo-data", "key": "tripo-studio///input.glb"}, "name": "my_model.glb", "transform_matrix": [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1], "use_original_uv": true } ``` → `data.{project_id, operator_id}`(随后可用 progress 轮询;实测导入成功后可下载)。 ⚠️ **`transform_matrix`** 是 4x4 矩阵(前端在导入对话框里让用户转模型用的「找到最佳角度」),CLI 用单位矩阵即可。 ⚠️ 导入会**丢弃自定义材质与多层节点层级**(界面明确提示);个别模型(如 Tripo 自己导出的带材质 glb)服务端处理会失败(`9104` / `Internal algorithm error`),换标准 obj/glb 即可。 ### 5. 部件名(`part_name_list`)来自模型文件,不在接口里 `remesh` / `pbr` / `texture_model` 的 `part_name_list` 取的是**模型里的节点名**: 未拆分为单个 `tripo_node_`,智能分割后为每个部件一个 `tripo_part_`。 ⚠️ 项目详情接口**不返回**部件名,前端是**下载 GLB 后解析 `nodes[].name`** 得到的; `tripocli` 用同样办法(纯标准库解析 GLB 的 JSON chunk),读不到时回退到 `tripo_node_`。 ### 6. 批量图生 3D ``` POST /v2/studio/operation/batch_image_to_model ``` ⚠️ 字段名是 **`image`**(数组,不是 `images`,写错返回 `type mismatch for field "image"`);响应 `data` 是**数组**,每项 `{project_id, operator_id}`。 --- ## 四、任务与项目 | 功能 | 方法与路径 | |---|---| | 进度轮询 | `POST /v2/studio/progress`,body `{"ids":[""]}` → `[{status, progress, left_time, point_cloud_model_url}]`,`status ∈ running/success/failed` | | 项目详情 | `GET /v2/studio/project/detail/v3/?locale=zh-CN` → `data.model_url`、`cover_image`、`operator.{operator_id, status, model_version, is_textured, ...}` | ⚠️ 轮询偶发裸 `502`,需重试而非中断。 --- ## 四、文生图(参考图生成) ``` POST /v2/studio/image/gen_image_v2 { "if_upload": true, "sketch_to_render": false, "t_pose": false, "amount": 4, // 1-4 "model_version": "gemini_3.1_flash_image_preview", "prompt": "a cute cartoon wooden barrel", "resolution": "1K", // 实测 1K/2K/4K 有效,8K 报 400 "scale": "1:1" // 1:1 16:9 9:16 4:3 3:4 } → {"task_id": ..., "asset_id": ..., "remaining_free_count": 96} POST /v2/studio/image/get_image_asset {"asset_id": "..."} → {status, type:"generate_image", output:{data:[{bucket,key,url}]}} ``` 图片模型 `model_version`(在页面逐个选中并抓包确认): | 界面名 | model_version | |---|---| | Nano Banana 2(默认) | `gemini_3.1_flash_image_preview` | | Nano Banana Pro | `gemini_3_pro_image_preview` | | GPT Image 2 | `gpt_image_2` | | GPT Image 2.5 | `gpt_image_2.5_sunburst` | | Midjourney v8.2 | `midjourney` | > 异步:先 `gen_image_v2` 拿 `asset_id`,再轮询 `get_image_asset` 直到 `status=success`。 ### 图片侧其它接口(实测) | 功能 | 方法与路径 | 说明 | |---|---|---| | 模板清单 | `GET /v2/studio/image/available_templates` | 返回 `{templates:[{template_id,title,description,category,secondary_tag,tag}]}`。**模板是客户端的提示词+参数预设**,请求体里没有 `template_id`(实测),CLI 只用来列清单 | | 单图→多视角图 | `POST /v2/studio/image/gen_multiview` | body `{image, model_version, amount, resolution, scale}`(`image` 需先上传+审核)。结果 `get_image_asset` 的 `type="multiview_images"`,`output.data` 为 4 张(实测出图 4 张) | | 图片资产 | `POST /v2/studio/image/image_assets` | body `{page_num,page_size}` | | 图片放大 | `POST /v2/studio/image/upscale` | 需 `asset_id`(实测:只给 image 报 `field "asset_id" is not set`) | | 图片拆分 | `POST /v2/studio/image/split` | — | | 重新生成 | `POST /v2/studio/image/re_gen_image` / `re_gen_multiview` | — | | 批量删除 | `POST /v2/studio/image/batch_delete` | — | --- ## 五、后处理算子 ⚠️ **通用规则**:每个算子都会为项目新建一个 operator;**必须等上一个算子 `success` 之后**才能对同一项目再提交, 否则返回 `2021 the status of task is not success`。 ⚠️ **`part_name_list`**:`remesh` / `pbr_generate` / `texture_model` 都需要它,值为 `["tripo_node_<项目当前 operator_id>"]`。缺它时请求会被接受,但任务在 **100% 处失败**(实测)。 | 功能 | 路径 | 关键字段 | |---|---|---| | 重拓扑 | `POST /v2/studio/operation/remesh` | `bake:true`、`face_limit`、`quad`、`smart_poly:false`、`model_version:"default"`、`part_name_list` | | 绑定前检查 | `POST /v2/studio/operation/pre_rig_check` | `project_id`(`model_version` 可选)→ `{check_success, riggable, rig_type}` | | 骨骼绑定 | `POST /v2/studio/operation/rigging_model` | `project_id`、`rig_type:"biped"`、`spec`、`model_version`。⚠️ **spec 有 5 个值**(取自前端数据表 + 实测核对):`mixamo` / `actorcore`(界面对应 ActorCore)/ `unreal`(UE5 Mannequin)/ `unity`(Unity Humanoid Compatible)/ `vrm`(VRM 1.0 Humanoid) | | 动画重定向 | `POST /v2/studio/operation/retarget_model` | ⚠️ 动作用 `animations` **数组**:`["preset:biped:afraid"]`;+ `project_id`、`rig_type:"biped"`、`model_version:"default"`。⚠️ **动画结果不在顶层 `project.model_url`**(那是 `rigging` 算子的带网格绑骨模型),而在 `project.operator.retarget[]` 数组中(按 `operator_id` 匹配取 `model_url`);且该 GLB 仅含 65 根骨骼动画轨道(约 100–500KB,不含 Mesh),在 Three.js / Godot 中需与 `rigging` 本体 SkinnedMesh 配合播放 | | 3D 风格化 | `POST /v2/studio/operation/stylize` | `project_id`、`model_version`、`style`(实测 `"clay"` 黏土风可用) | | 取消任务 | `POST /v2/studio/operation/cancel` | `operator_id`、`scene`(仅允许 `"workspace"` 或 `"assets"`)、`operation_type`(20 种枚举:`text_to_model`/`image_to_model`/`multiview_to_model`/`ai_segmentation`/`ai_completion`/`mesh_fill`/`modification`/`skeleton_adjustment`/`texture_generation`/`pre_rig_check`/`rigging`/`retarget`/`stylize`/`export`/`retexture`/`apply_texture`/`pbr`/`remesh`/`texture_upscaler`/`image_edit_to_model`) | | 重命名项目 | `POST /v2/studio/operation/update_name` | `project_id`、`name`(成功返回 `null`) | | 图文生 3D(已废弃) | `POST /v2/studio/operation/image-prompt-model` | ⚠️ 服务端已下线,固定返回 `code=2040 This endpoint is no longer accepting requests` | | 智能分割 | `POST /v2/studio/operation/ai_segmentation` | ⚠️ `model_version` 用**分割模型自己的版本** `v2.0-20260430`(传项目版本会 `1001`);`segmentation_granularity:"balanced"`(界面「标准」;粗略/精细取值未确认) | | 纹理生成 | `POST /v2/studio/operation/texture_model` | `texture_quality`、`texture_alignment`、`part_name_list`(⚠️ 已贴图模型会失败) | | 重贴图(魔法笔刷) | `POST /v2/studio/operation/retexture_generate` / `apply_retexture` / `get_retexture` / `get_retexture_images` | ⚠️ **纯交互式**:body 需在 3D 画布上涂抹出的遮罩快照(`snapshot()` → `matrix` + 涂抹区域)+ `magicBrushPrompt:{text,weight}`,且要求模型**已贴图**、未分割、未超清。CLI 未封装 | | 纹理放大 | `POST /v2/studio/operation/texture_upscaler` | ⚠️ 字段是 `texture_quality:"detailed"`(不是 `texture_resolution`,写错会 `1001`);+ `model_version` | | PBR | `POST /v2/studio/operation/pbr_generate` | `project_id`、`model_version`、`part_name_list` | | 智能 UV | 见下方三步 | 上下文驱动 | | 部件补全 | `POST /v2/studio/operation/mesh_fill` / `ai_completion` | `part_names`(数组)、`model_version`。部件名 = 模型 GLB 的节点名(`tripo_part_`),实测可用 | | 网格编辑 | `POST /v2/studio/operation/local_edit` | `project_id`、`source_operator_id`、`bbox:[[min],[max]]`(归一化 -1..1)、`face_limit`。⚠️ 仅**智能网格(Nexus)** 且未贴图/未绑定/未分割/未 PBR 的模型可用(界面据此隐藏「编辑」页) | ### 智能 UV(三步,实测) ``` POST /v2/studio/operation/uv_edit/generate {project_id, current_operator_id, action:"generate"} → 生成 UV 候选(新 operator) POST /v2/studio/operation/uv_edit/apply {project_id, current_operator_id, candidate_operator_id} → 保存/应用候选 POST /v2/studio/operation/uv_edit/context {project_id, current_operator_id} → 查询当前处于哪一步 ``` ⚠️ 只 `generate` 不 `apply`,上下文会停在「待保存」,再调 `generate` 报 `2046 UV Edit action no longer matches the context`。另外要求网格为低模(约 ≤8 万三角面)。 > 说明:`ai_segmentation` / `texture_upscaler` 等对**不同模型**可能服务端失败,属模型相关行为,与请求字段无关。 ### 动作预设清单(无接口,来自前端静态表) 服务端**没有**提供预设目录接口,实测: - `POST /v2/studio/motion/list_assets`(body `{}`)→ 返回的是**用户自己的动画资产**(`{active_tasks, assets}`),不是预设目录; - `POST /v2/studio/operation/get_user_operation_context` `{"record_type":"recent_retarget_motions"}` → 只返回**最近用过**的:`{preset:[...], generated:[...]}`。 完整目录在 studio 前端 chunk(`BLST4mg6.js`)的静态表里,已提取到 `tripo/data/motions.json`: - 格式 `preset::`,`rig_type ∈ {biped, aquatic, quadruped, hexapod, octopod, serpentine}` - **biped 97 个**,其余体型各 1 个(`walk`/`march`) - 预览图:`https://tripo-public.tripo3d.ai/studio_riging_data//.avif` 用 `tripocli animate --list` 查看全部。 ### 文字生成动作(AI 动画,实测三段式) ``` 1) POST /v2/studio/motion/generate {"segments": [{"duration_seconds": 5, "prompt": "让角色挥手打招呼"}]} → {task_id, status:"queued"} (segments 是数组 → 支持多阶段动作) 2) POST /v2/studio/motion/get_task {"task_id": "..."} → 轮询直到 status="success",取 asset_id(即 motion_asset_id) 3) POST /v2/studio/operation/retarget_model {"motion_asset_id": "", "model_version":"default", "project_id": "...", "rig_type": "biped"} → 把动作套到模型上 ``` 其它已验证接口:`POST /v2/studio/motion/list_assets`(我的动作资产)、`/motion/get_asset`、 `/motion/list_active_tasks`(正在跑的任务)。 --- ## 六、导出与下载 ``` POST /v2/studio/operation/export body: {project_id, operator_id, format:"fbx|gltf|obj|stl|usdz|3mf", name, model_version} → data.{operator_id, operation_id} # 异步,用 progress 轮询 POST /v2/studio/operation/download_with_name body: {operator_id, file_name} → data.model_url # 带 Content-Disposition 的签名直链 ```