Node.js · Virtual Try-On API
Virtual Try-On API i Node.js
Det finnes ingen @photta/node-pakke ennå — og du trenger den ikke. Node 18+ har native `fetch`, og en 20-linjers helper tar deg til ditt første modellbilde på ca. fem minutter.
Kort fortalt
Sett `PHOTTA_API_KEY` i miljøvariabler, skriv en liten `phottaFetch()`-helper som kaller `https://ai.photta.app/api/v1` med `Authorization: Bearer photta_live_xxx`, POST til `/tryon/apparel` med en bilde-URL, mannequin_id og pose_id, og poll deretter `/tryon/apparel/:id` hvert 3 sekunder til `status === 'completed'` — vanligvis innen 1.5–4 minutes.
Oppdatert · 2026-04-19
Din første forespørsel
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);Hva du kan forvente
Typical completion
1.5–4min
2K / 4K credits
5 / 7
Aspect ratios
5
Product types
6
Slik fungerer det
Virtual Try-On API i Node.js
Fem steg, ca. fem minutter fra registrering til første bilde.
- 01
Steg 1
Registrer deg og generer en nøkkel
Opprett en konto på ai.photta.app. Åpne Developers-seksjonen i dashbordet, klikk på Generate API key, og kopier live-nøkkelen. Den starter med `photta_live_` etterfulgt av 32 hex-tegn.
- 02
Steg 2
Lagre nøkkelen i miljøvariabler, ikke i kildekoden
Legg til `PHOTTA_API_KEY=...` i `.env` (eller plattformens secret store) og last den via `process.env`. Aldri sjekk inn nøkkelen; aldri importer den i en fil merket med `'use client'` — pakkeverktøyet vil da inkludere den i nettleseren.
- 03
Steg 3
Skriv en liten fetch-helper
En 20-linjers wrapper rundt `fetch()` håndterer base-URL, Authorization-header, JSON og feilhåndtering. Dette er den eneste abstraksjonen du trenger før en offisiell SDK lanseres.
- 04
Steg 4
Send inn en prøve-jobb og poll
POST til `/tryon/apparel` med `product_type`, `product_images`, `mannequin_id`, `pose_id`, `resolution` og `aspect_ratio`. API-et returnerer en genererings-ID umiddelbart. Poll `/tryon/apparel/:id` hvert 3 sekunder til `status === 'completed'`.
- 05
Steg 5
Lagre resultatet
Responsen inkluderer `output_url` og `thumbnail_url`. Hent bildedataene én gang og lagre dem i din egen lagringsløsning — URL-ene er stabile, men produktet ditt bør ikke være avhengig av Phottas CDN for visning.
Kode, ende-til-ende
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;
}Hvorfor dette formatet
Hvorfor en helper er bedre enn et bibliotek — enn så lenge
- 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
Hva det ikke gjør
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
Spørsmål andre utviklere stiller
Questions other developers ask
Finnes det en offisiell Photta Node.js SDK?+
Ikke ennå. Phottas dokumentasjon planlegger SDK-er etter visse terskler: Python når ti API-brukere er ombord, Node.js ved tjue. Inntil da er den dokumenterte metoden rå REST via cURL, Nodes native fetch, eller Pythons requests-bibliotek. 20-linjers-helperen på denne siden tilsvarer en klient for endepunktene du vil bruke mest.
Hvilke Node.js-versjoner støttes?+
Alle versjoner som støtter native `fetch` — som betyr Node 18 og nyere. På Node 16 må du enten bruke en polyfill som `node-fetch` eller oppgradere. Resten av koden er standard ECMAScript 2020 (async/await, template literals), så det er ingen andre krav til runtime.
Hvordan autentiserer jeg fra Node?+
Send `Authorization: Bearer photta_live_xxx` med hver forespørsel. Nøkkelen starter med `photta_live_` i produksjon, og `photta_test_` når sandkasse-modus lanseres. Legg den i en miljøvariabel og last den via `process.env.PHOTTA_API_KEY`. API-et støtter ennå ikke OAuth eller sesjonsbasert autentisering.
Hvordan håndterer jeg genereringstiden på 1.5–4 minutes?+
Prøve-endepunktet er fullstendig asynkront. POST returnerer en genererings-ID umiddelbart med `status: 'processing'`. Poll `GET /tryon/apparel/:id` hvert 3–5 sekunder til `status` endres til `completed` eller `failed`. Sett en øvre grense for forsøk slik at forespørselen ikke henger evig — 120 forsøk á 3 sekunder dekker det dokumenterte vinduet med margin.
Kan jeg kalle API-et i Next.js?+
Ja — fra en route handler (`app/**/route.ts`), en server action (`'use server'`), eller middleware. Hold API-nøkkelen på serveren; importer aldri helperen i en `'use client'`-fil. For jobber som overskrider tidsavbrudd i serverløse funksjoner, bør du flytte pollingen til en kø (Inngest, Trigger.dev, BullMQ) og returnere genererings-ID-en til nettleseren.
Hvordan signaliserer API-et feil?+
Responser som ikke er 2xx inneholder et JSON-objekt med `error`: `type`, `code`, `message` og en request-ID for support. Vanlige tilfeller: 400 invalid_request_error med `param` som peker på feilen; 402 insufficient_credits med antall påkrevde og tilgjengelige credits; 429 rate_limit_exceeded med `retry_after` i sekunder. 5xx-feil kan trygt prøves på nytt med eksponentiell backoff.
Node.js · Virtual Try-On API
Opprett en konto og hent en API-nøkkel
Sett `PHOTTA_API_KEY` i miljøvariabler, skriv en liten `phottaFetch()`-helper som kaller `https://ai.photta.app/api/v1` med `Authorization: Bearer photta_live_xxx`, POST til `/tryon/apparel` med en bilde-URL, mannequin_id og pose_id, og poll deretter `/tryon/apparel/:id` hvert 3 sekunder til `status === 'completed'` — vanligvis innen 1.5–4 minutes.