Node.js · 虚拟试穿 API

Node.js 虚拟试穿 API

目前还没有 @photta/node 包 —— 您也不需要它。Node 18+ 原生内置了 `fetch`,只需 20 行辅助代码,大约五分钟即可生成您的第一张模特图。

一句话介绍

在环境变量中设置 `PHOTTA_API_KEY`,编写一个简单的 `phottaFetch()` 辅助函数调用 `https://ai.photta.app/api/v1` 并携带 `Authorization: Bearer photta_live_xxx`,向 `/tryon/apparel` 发送 POST(包含产品图 URL、模特 ID 和姿势 ID),然后每 3 秒轮询一次 `/tryon/apparel/:id` 直至 `status === 'completed'` —— 通常在 1.5–4 分钟内完成。

已更新 · 2026-04-19

发起首次请求

Node.jsPythoncURLcURL
import { phottaFetch } from "./photta.js";

// 1. Submit the job — returns a generation ID immediately.
const created = await phottaFetch("/tryon/apparel", {
  method: "POST",
  body: JSON.stringify({
    product_type: "dress",
    product_images: ["https://example.com/dress.jpg"],
    mannequin_id: "mnq_athena_ts",
    pose_id: "pose_standing_front",
    resolution: "2K",
    aspect_ratio: "3:4",
  }),
});
const generationId = created.data.id;

// 2. Poll every 3 seconds until processing completes. Typical
// completion is 1.5–4 minutes; put an upper bound so a stuck
// job can't hang your request forever.
const pollInterval = 3000;
const maxAttempts = 120;     // 120 × 3s = 6 minutes
let result;

for (let i = 0; i < maxAttempts; i++) {
  result = await phottaFetch(`/tryon/apparel/${generationId}`);
  if (result.data.status === "completed") break;
  if (result.data.status === "failed") {
    throw new Error(result.data.error_message);
  }
  await new Promise((r) => setTimeout(r, pollInterval));
}

console.log("Result:", result.data.output_url);

预期效果

Typical completion

1–3min

2K / 4K credits

4 / 6

Styles

2

Batch-ready

yes

工作原理

Node.js 虚拟试穿 API

五个步骤,从注册到生成首张图片约五分钟。

  1. 01

    步骤 1

    注册并生成密钥

    在 ai.photta.app 创建账户。打开仪表盘的 Developers 部分,点击 Generate API key 获取 live 密钥。它以 `photta_live_` 开头,后跟 32 位十六进制字符。

  2. 02

    步骤 2

    将密钥存入 env,而非源码

    将 `PHOTTA_API_KEY=...` 添加到 `.env`(或您平台的密钥库)中,并通过 `process.env` 加载。切勿提交密钥;切勿在标有 `'use client'` 的文件中导入它 —— 否则打包工具会将其暴露到浏览器端。

  3. 03

    步骤 3

    编写简单的 fetch 辅助函数

    一个 20 行左右的 `fetch()` 封装即可处理基础 URL、Authorization 请求头、JSON 请求体和错误规范化。在官方 SDK 发布前,这是您唯一需要的抽象。

  4. 04

    步骤 4

    提交试穿任务并轮询

    向 `/tryon/apparel` 发送 POST,包含 `product_type`、`product_images`、`mannequin_id`、`pose_id`、`resolution` 和 `aspect_ratio`。API 会立即返回任务 ID。每 3 秒轮询一次 `/tryon/apparel/:id` 直至 `status === 'completed'`。

  5. 05

    步骤 5

    持久化结果

    完成后的数据包含 `output_url` 和 `thumbnail_url`。请获取字节流并存入您自己的对象存储 —— URL 是稳定的,但您的产品不应依赖 Photta 的 CDN 进行渲染。

端到端代码

Copy, paste, done.

Four snippets — install prerequisites, wrap the REST call, submit + poll, then handle the errors that actually happen in production.

01No SDK required — use native fetch in Node 18+
bash
# Node 18+ ships fetch natively. No install step needed.
node --version   # ensure v18 or later

# Optional: keep your API key out of source control
echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .env
02Wrap the REST call in a tiny client helper
javascript
// photta.js — a 20-line wrapper you can reuse across your app.
const PHOTTA_BASE_URL = "https://ai.photta.app/api/v1";

export async function phottaFetch(path, init = {}) {
  const res = await fetch(`${PHOTTA_BASE_URL}${path}`, {
    ...init,
    headers: {
      "Authorization": `Bearer ${process.env.PHOTTA_API_KEY}`,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });
  const body = await res.json();
  if (!res.ok) {
    const err = new Error(body?.error?.message ?? res.statusText);
    err.status = res.status;
    err.code = body?.error?.code;
    throw err;
  }
  return body;
}
03Submit a try-on job and poll until it lands
javascript
import { phottaFetch } from "./photta.js";

// 1. Submit the job — returns a generation ID immediately.
const created = await phottaFetch("/tryon/apparel", {
  method: "POST",
  body: JSON.stringify({
    product_type: "dress",
    product_images: ["https://example.com/dress.jpg"],
    mannequin_id: "mnq_athena_ts",
    pose_id: "pose_standing_front",
    resolution: "2K",
    aspect_ratio: "3:4",
  }),
});
const generationId = created.data.id;

// 2. Poll every 3 seconds until processing completes. Typical
// completion is 1.5–4 minutes; put an upper bound so a stuck
// job can't hang your request forever.
const pollInterval = 3000;
const maxAttempts = 120;     // 120 × 3s = 6 minutes
let result;

for (let i = 0; i < maxAttempts; i++) {
  result = await phottaFetch(`/tryon/apparel/${generationId}`);
  if (result.data.status === "completed") break;
  if (result.data.status === "failed") {
    throw new Error(result.data.error_message);
  }
  await new Promise((r) => setTimeout(r, pollInterval));
}

console.log("Result:", result.data.output_url);
04Handle 402 credit exhaustion and 429 rate limits
javascript
try {
  await phottaFetch("/tryon/apparel", {
    method: "POST",
    body: JSON.stringify({ /* … */ }),
  });
} catch (err) {
  if (err.status === 402) {
    // Out of credits — surface a top-up CTA to the user.
    // err.code === "insufficient_credits"
  } else if (err.status === 429) {
    // Rate-limited. Honour the Retry-After header.
    const retryAfter = err.retryAfter ?? 30;
    await new Promise((r) => setTimeout(r, retryAfter * 1000));
    // Then retry…
  } else if (err.status >= 500) {
    // Server-side issue — backoff + retry.
  }
  throw err;
}

设计初衷

为什么现阶段辅助函数优于客户端库

  • Node 18+ ships native fetch — no runtime deps required
  • Same helper works inside Next.js route handlers, API routes, server actions and edge functions
  • Keep API keys in env; never import the helper from a 'use client' module or the bundler will leak them
  • Works with any queue/cron: BullMQ, Inngest, Trigger.dev, Vercel Cron, Cloudflare Queues

功能边界

Honest caveats

  • No official @photta/node SDK yet — REST is the only path today
  • No built-in webhook delivery; polling is the documented pattern (3–5s interval)
  • Bearer token lives in env; the API doesn't support OAuth client credentials yet

开发者常见问题

Questions other developers ask

有官方的 Photta Node.js SDK 吗?+

目前还没有。Photta 文档明确计划在达到用户阈值后发布 SDK:Python 需 10 个 API 用户,Node.js 需 20 个。在此之前,推荐路径是直接使用 cURL、Node 原生 fetch 或 Python requests。本页面的 20 行辅助函数功能上等同于您最常用端点的客户端。

支持哪些 Node.js 版本?+

任何支持原生 `fetch` 的版本 —— 即 Node 18 及更高版本。在 Node 16 上,您需要使用 `node-fetch` 进行 polyfill 或升级环境。其余代码为标准的 ECMAScript 2020(async/await, 模板字符串, 动态导入),无其他运行时要求。

如何在 Node 中进行认证?+

在每个请求中发送 `Authorization: Bearer photta_live_xxx`。生产环境密钥以 `photta_live_` 开头,沙盒模式上线后将使用 `photta_test_`。将其存入环境变量并加载。API 目前暂不支持 OAuth 客户端凭据或基于 session 的认证。

如何处理 1.5–4 分钟的生成窗口?+

试穿端点是完全异步的。POST 请求会立即返回任务 ID 且 `status: 'processing'`。每 3–5 秒轮询一次 `GET /tryon/apparel/:id` 直至 `status` 变为 `completed` 或 `failed`。请务必设置尝试次数上限(如 3 秒一次,共 120 次),防止脚本无限挂起。

我可以在 Next.js 中调用 API 吗?+

可以 —— 在 route handler (`app/**/route.ts`)、server action (`'use server'`) 或中间件中调用。请务必在服务器端保留 API 密钥;严禁在 `'use client'` 文件中导入辅助函数。对于超过 Vercel 函数超时的任务,建议将轮询交给队列(Inngest, Trigger.dev, BullMQ),并将任务 ID 返回给浏览器,由前端查询您的状态端点。

API 如何返回错误?+

非 2xx 响应包含一个 JSON 请求体,其中包含 `error` 对象:`type`、`code`、`message` 以及用于技术支持的请求 ID。常见情况:400 invalid_request_error 会在 `param` 中指出错误字段;402 insufficient_credits 包含 `required` 和 `available` 计数;429 rate_limit_exceeded 包含 `retry_after` 秒数。5xx 错误可以尝试指数退避重试。

Node.js · 虚拟试穿 API

创建账户并获取 API 密钥

在环境变量中设置 `PHOTTA_API_KEY`,编写一个简单的 `phottaFetch()` 辅助函数调用 `https://ai.photta.app/api/v1` 并携带 `Authorization: Bearer photta_live_xxx`,向 `/tryon/apparel` 发送 POST(包含产品图 URL、模特 ID 和姿势 ID),然后每 3 秒轮询一次 `/tryon/apparel/:id` 直至 `status === 'completed'` —— 通常在 1.5–4 分钟内完成。

Node.js 虚拟试穿 API — Photta | Photta