Node.js · Virtual Try-On API
Virtual Try-On API Node.js-ympäristössä
Virallista @photta/node-pakettia ei vielä ole — etkä tarvitse sellaista. Node 18+ sisältää natiivin `fetch`-tuen, ja 20 rivin apufunktio vie sinut ensimmäiseen mallikuvaan noin viidessä minuutissa.
Yhdellä lauseella
Aseta `PHOTTA_API_KEY` ympäristömuuttujiin, kirjoita pieni `phottaFetch()`-apufunktio osoitteeseen `https://ai.photta.app/api/v1` otsakkeella `Authorization: Bearer photta_live_xxx`, lähetä POST osoitteeseen `/tryon/apparel` ja pollata `/tryon/apparel/:id` 3 sekunnin välein kunnes `status === 'completed'` — yleensä 1.5–4 minuutissa.
Päivitetty · 2026-04-19
Ensimmäinen pyyntösi
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);Mitä odottaa
Typical completion
1.5–4min
2K / 4K credits
5 / 7
Aspect ratios
5
Product types
6
Miten se toimii
Virtual Try-On API Node.js-ympäristössä
Viisi vaihetta, noin viisi minuuttia rekisteröitymisestä ensimmäiseen kuvaan.
- 01
Vaihe 1
Rekisteröidy ja generoi avain
Luo tili osoitteessa ai.photta.app. Avaa Developers-osio, klikkaa Generate API key ja ota live-avain talteen. Se alkaa `photta_live_` -tunnisteella.
- 02
Vaihe 2
Tallenna avain ympäristömuuttujiin, älä koodiin
Lisää `PHOTTA_API_KEY=...` `.env`-tiedostoon ja lataa se `process.env`-kautta. Älä koskaan tallenna avainta versionhallintaan tai käytä sitä `'use client'` -tiedostossa — se vuotaa selaimeen.
- 03
Vaihe 3
Kirjoita pieni fetch-apufunktio
Yksi 20 rivin kääre `fetch()`-kutsun ympärillä hoitaa perus-URL:n, Authorization-otsakkeen, JSON-rungon ja virheiden käsittelyn. Tämä on ainoa abstraktio, jonka tarvitset ennen virallista SDK:ta.
- 04
Vaihe 4
Lähetä sovitus ja pollata
POST osoitteeseen `/tryon/apparel` tiedoilla `product_type`, `product_images`, `mannequin_id`, `pose_id`, `resolution` ja `aspect_ratio`. API palauttaa tunnuksen välittömästi. Pollata `/tryon/apparel/:id` 3 sekunnin välein.
- 05
Vaihe 5
Tallenna lopputulos
Vastaus sisältää `output_url` ja `thumbnail_url`. Hae tavut kerran ja tallenna omaan objektitallennustilaasi — osoitteet ovat vakaita, mutta tuotteesi ei pitäisi riippua Phottan CDN:stä renderöinnissä.
Koodi alusta loppuun
Copy, paste, done.
Four snippets — install prerequisites, wrap the REST call, submit + poll, then handle the errors that actually happen in production.
# 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// 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;
}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);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;
}Miksi tämä muoto
Miksi apufunktio voittaa kirjaston — toistaiseksi
- 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
Mitä se ei tee
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
Muiden kehittäjien kysymyksiä
Questions other developers ask
Onko olemassa virallista Photta Node.js SDK:ta?+
Ei vielä. Tie-kartassa SDK:t tulevat käyttöasteen mukaan: Python 10 asiakkaan jälkeen, Node.js 20:n. Siihen asti suositeltu tapa on natiivi REST, ja tämän sivun 20 rivin funktio vastaa täysin virallista asiakasohjelmaa.
Mitä Node.js-versioita tuetaan?+
Kaikkia, jotka tukevat natiivia `fetch`-funktiota — eli Node 18 ja uudemmat. Node 16:ssa voit käyttää `node-fetch`-polyfillausta. Muu koodi on puhdasta ECMAScript 2020 -standardia (async/await, template literals).
Miten tunnistaudun Node-ympäristöstä?+
Lähetä `Authorization: Bearer photta_live_xxx` jokaisessa pyynnössä. Käytä ympäristömuuttujia `process.env.PHOTTA_API_KEY`. API ei tue vielä OAuth-asiakastunnuksia tai istuntopohjaista tunnistautumista.
Miten käsittelen 1.5–4 minuutin generointiajan?+
Sovitustehtävä on täysin asynkroninen. POST palauttaa tunnuksen ja tilan `processing`. Pollata `GET /tryon/apparel/:id` 3–5 sekunnin välein. Aseta yläraja yrityksille (esim. 120 kertaa), jotta palvelimesi ei jää jumiin ikuisesti.
Voinko kutsua API:a Next.js-sovelluksessa?+
Kyllä — reitinkäsittelijöistä (`app/**/route.ts`), server actioneista tai middlewaresta. Pidä avain palvelimella; älä koskaan tuo apufunktiota `'use client'` -tiedostoon. Jos työ kestää yli Vercel-funktioiden aikarajan, siirrä pollaus jonoon (Inngest, Trigger.dev, BullMQ).
Miten API ilmoittaa virheistä?+
Muut kuin 2xx-vastaukset sisältävät JSON-rungon, jossa on `error`-objekti: `type`, `code`, `message` ja pyyntötunnus. Yleiset: 400 virheellinen pyyntö, 402 liian vähän krediittejä, 429 nopeusrajoitus (sisältää `retry_after`-tiedon). 5xx-virheet voi yrittää uudelleen.
Node.js · Virtual Try-On API
Luo tili ja hanki API-avain
Aseta `PHOTTA_API_KEY` ympäristömuuttujiin, kirjoita pieni `phottaFetch()`-apufunktio osoitteeseen `https://ai.photta.app/api/v1` otsakkeella `Authorization: Bearer photta_live_xxx`, lähetä POST osoitteeseen `/tryon/apparel` ja pollata `/tryon/apparel/:id` 3 sekunnin välein kunnes `status === 'completed'` — yleensä 1.5–4 minuutissa.