# World Labs 3D 世界生成中转接口兼容要求 本文档用于说明我方系统接入 World Labs 3D 世界生成功能时,对第三方中转服务的接口兼容要求。 ## 核心原则 我方系统会按照 World Labs 官方 API 协议发起请求: ```text {baseUrl} + /marble/v1/... ``` 中转服务需要兼容官方路径、请求体、响应体和错误格式。请不要要求我方把 `baseUrl` 配置成某个完整接口地址。 正确示例: ```text http://your-proxy-domain.com ``` 错误示例: ```text http://your-proxy-domain.com/marble/v1/worlds:generate ``` ## 我方请求方式 我方后台会在请求中携带: ```http WLT-Api-Key: {配置的 API Key} Accept: application/json Content-Type: application/json ``` 中转服务应支持 `WLT-Api-Key` 请求头。如果中转服务内部自行管理官方 Key,也可以将该字段作为租户标识或鉴权凭据,但不应要求我方改成其他 header。 ## 必须兼容的接口 ### 1. 准备上传素材 ```http POST {baseUrl}/marble/v1/media-assets:prepare_upload ``` 请求体示例: ```json { "file_name": "input.jpg", "extension": "jpg", "kind": "image", "metadata": { "mime_type": "image/jpeg", "uploaded_from": "canvas_world_mode" } } ``` 响应必须包含可用的上传信息: ```json { "media_asset": {}, "upload_info": { "upload_url": "https://...", "upload_method": "PUT", "required_headers": {} } } ``` 要求: - `upload_url` 必须可由我方服务器直接访问。 - `upload_method` 如为 `PUT`,必须支持 `PUT` 上传文件二进制。 - `required_headers` 中返回的 header,我方会原样带上。 - 上传成功时,上传地址必须返回 `2xx`。 ### 2. 创建世界生成任务 ```http POST {baseUrl}/marble/v1/worlds:generate ``` 请求体示例: ```json { "display_name": "", "model": "marble-1.1", "permission": { "public": false }, "world_prompt": { "type": "image", "image_prompt": { "source": "media_asset", "media_asset_id": "media_asset_id_here" } } } ``` 响应需兼容官方 operation 结构,至少包含: ```json { "operation_id": "task-id", "done": false, "metadata": { "progress": { "status": "RUNNING" } } } ``` 要求: - `operation_id` 必须稳定,后续查询状态必须使用同一个 id。 - 不要在创建成功但任务未完成时返回业务失败。 - 如果余额不足、Key 无效,应返回明确 HTTP 状态码和错误信息。 ### 3. 查询任务状态 ```http GET {baseUrl}/marble/v1/operations/{operation_id} ``` 运行中响应示例: ```json { "operation_id": "task-id", "done": false, "metadata": { "progress": { "status": "RUNNING", "description": "World generation in progress" } } } ``` 成功响应示例: ```json { "operation_id": "task-id", "done": true, "error": null, "metadata": { "progress": { "status": "SUCCEEDED" }, "world_id": "world-id" }, "response": { "world_id": "world-id", "world_marble_url": "https://marble.worldlabs.ai/world/...", "assets": { "mesh": { "collider_mesh_url": "https://cdn.marble.worldlabs.ai/.../model.glb" }, "imagery": { "pano_url": "https://cdn.marble.worldlabs.ai/.../rgb_0.png" }, "thumbnail_url": "https://cdn.marble.worldlabs.ai/.../thumbnail.webp", "splats": { "spz_urls": { "100k": "https://cdn.marble.worldlabs.ai/...100k.spz", "150k": "https://cdn.marble.worldlabs.ai/...150k.spz", "500k": "https://cdn.marble.worldlabs.ai/...500k.spz", "full_res": "https://cdn.marble.worldlabs.ai/...full.spz" } } } } } ``` 失败响应示例: ```json { "operation_id": "task-id", "done": true, "error": { "message": "Insufficient account balance" } } ``` 要求: - `done=false` 表示任务仍在运行。 - `done=true` 且 `error=null` 表示任务成功。 - `done=true` 且 `error.message` 存在表示任务失败。 - 不要把运行中的任务返回为 HTTP 404。 - 不要因为任务未完成就返回 `Operation not found`。 ### 4. 查询世界详情 ```http GET {baseUrl}/marble/v1/worlds/{world_id} ``` 当 `operations` 成功响应中资产不完整时,我方会调用该接口补充详情。响应应包含与 `response` 内 world 对象兼容的数据结构。 ## 错误码要求 建议按以下语义返回: | 场景 | HTTP 状态码 | message 示例 | | --- | --- | --- | | API Key 缺失或无效 | `401` | `Unauthorized` | | 权限不足 | `403` | `Forbidden` | | 余额不足 | `402` 或 `403` | `Insufficient account balance` | | 请求体错误 | `400` | `Invalid request body` | | 任务不存在 | `404` | `Operation not found` | | 上游超时 | `504` | `Upstream timeout` | | 上游异常 | `502` | `Upstream error` | 响应体建议: ```json { "message": "Insufficient account balance" } ``` 或: ```json { "error": { "message": "Insufficient account balance" } } ``` ## 超时与稳定性要求 - `prepare_upload` 建议 30 秒内返回。 - `worlds:generate` 建议 60 秒内返回 operation,而不是等待生成完成。 - `operations/{id}` 建议 10 秒内返回当前状态。 - 生成任务本身可异步运行,前端会轮询状态。 - 同一个 `operation_id` 多次查询必须返回同一个任务状态,不应随机切换账号或路由。 ## 上传地址要求 `prepare_upload` 返回的 `upload_url` 可以是官方签名地址,也可以是中转服务自己的上传地址,但必须满足: - 我方服务器可直接访问。 - 支持返回的 `upload_method`。 - 支持上传原始文件二进制。 - 上传成功返回 `2xx`。 - 上传完成后,后续 `worlds:generate` 使用的 `media_asset_id` 必须可用。 ## 安全要求 - 不要在错误信息中返回完整官方 API Key。 - 日志中建议只记录 Key 前后少量字符,例如 `sk-****abcd`。 - 中转服务如保存官方 Key,应加密存储。 - 上传 URL 如有签名,应设置合理过期时间。 - 不要允许用户通过 `baseUrl` 或 path 注入访问内网地址。 ## 我方验收用例 中转服务上线前,请至少通过以下链路: 1. `POST /marble/v1/media-assets:prepare_upload` 返回 `media_asset_id` 和可上传 URL。 2. 使用返回的 `upload_url` 上传图片,返回 `2xx`。 3. `POST /marble/v1/worlds:generate` 返回稳定 `operation_id`。 4. `GET /marble/v1/operations/{operation_id}` 在运行中返回 `done=false`。 5. 任务完成后返回 `done=true`、`error=null`、`world_id` 和资产 URL。 6. 资产 URL 中至少应包含 thumbnail、pano、mesh 或 spz 中的一种,最好完整返回。 7. `GET /marble/v1/worlds/{world_id}` 可返回完整 world 详情。 ## 配置示例 我方系统中的 API 地址应填写中转根地址: ```text http://23.169.168.133:8080 ``` 最终我方会请求: ```text http://23.169.168.133:8080/marble/v1/media-assets:prepare_upload http://23.169.168.133:8080/marble/v1/worlds:generate http://23.169.168.133:8080/marble/v1/operations/{operation_id} http://23.169.168.133:8080/marble/v1/worlds/{world_id} ``` 如果切回官方接口,配置为: ```text https://api.worldlabs.ai ``` 最终请求: ```text https://api.worldlabs.ai/marble/v1/media-assets:prepare_upload https://api.worldlabs.ai/marble/v1/worlds:generate https://api.worldlabs.ai/marble/v1/operations/{operation_id} https://api.worldlabs.ai/marble/v1/worlds/{world_id} ``` ## 结论 中转服务需要做的是兼容 World Labs 官方 API 协议,而不是要求我方修改接口路径。只要中转根地址完整支持 `/marble/v1/...`,我方系统就可以在官方接口和中转接口之间无缝切换。