Byg · Virtuel Try-On

Byg en virtuel try-on-funktion til din app

I én sætning

Modtag produktbilledet i dit backend, POST det til /api/v1/tryon/apparel med et mannequin-ID, poll det returnerede generation-ID fra en baggrunds-worker (aldrig i HTTP-request-tråden), indtil status skifter til completed, persistér derefter output_url i dit eget objektlager, og render det i brugerfladen.

  • Credits: 5 credits ved 2K · 6 credits ved 4K
  • Typisk tid: 1.5–4 min
  • Behandling: async, polling

Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket

En produktionsklar opskrift: Kunden uploader et produktbillede, dit backend sætter et Photta try-on-job i kø, en worker poller indtil det er færdigt, og frontend viser resultatet på modellen. Ingen blokerende requests, ingen lækkede API-nøgler, ingen falsk SDK.

RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
  -H "Authorization: Bearer $PHOTTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "product_type": "top",
  "product_images": [
    "https://cdn.yourstore.com/products/shirt-front.jpg"
  ],
  "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
  "product_category": "t_shirt",
  "mannequin_id": "mnk_f3a9b1",
  "pose_id": "pose_c2d4e5",
  "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
  "lock_background": true,
  "resolution": "2K",
  "aspect_ratio": "3:4",
  "body_size": "M",
  "expression": "neutral",
  "user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')

Sådan virker det

Fra upload til billede på model

Seks konkrete trin. Forvent ti til femten minutters integrationsarbejde første gang.

  1. Trin 1

    Tegn dataflowet

    Kundens enhed → dit backend (upload) → Photta API (indsend) → Photta API (poll) → din database (statusspejling) → kundens enhed (render). Tegn dette på papir, før du skriver den første linje — grænsefladen mellem dit backend og Phottas er det eneste, der betyder noget.

  2. Trin 2

    Generér og gem en API-nøgle

    Live-nøgler starter med photta_live_. Læg den i en miljøvariabel. Send den aldrig til browseren. Én nøgle dækker alle Photta-kapabiliteter, så du behøver ikke separate nøgler til try-on, smykker eller ghost mannequin.

  3. Trin 3

    Forbind upload-endpointet

    Modtag kundens produktbillede i dit objektlager først. At give Photta en offentlig URL er enklere end base64 og giver dig et audit trail for hvert request.

  4. Trin 4

    Indsend jobbet fra serveren

    POST /api/v1/tryon/apparel med produktets URL, mannequin_id, resolution og aspect_ratio. API'et returnerer 202 Accepted + et generation-ID. Gem dette ID i din database, så din klient kan polle dit eget endpoint, ikke Phottas.

  5. Trin 5

    Poll fra en baggrunds-worker

    Foretag ikke polling inde i HTTP-requestet — jobbet tager 1.5 til 4 minutter, hvilket overskrider de fleste serverless-timeouts. Brug Trigger.dev, Inngest, BullMQ, Vercel Cron eller din egen kø til at planlægge et nyt poll hvert 3. sekund, indtil jobbet er færdigt.

  6. Trin 6

    Render resultatet

    Når status skifter til completed, kopieres data.output_url over i din database, og der udsendes en realtidshændelse (websocket, SSE eller long-poll) til kundens enhed. UI'en erstatter loading-skelettet med billedet. Færdig.

Tre kodeeksempler, fra start til slut

Upload-handler, job-dispatcher, poller på worker-siden — alle de dele, du behøver for at release funktionen.

// POST /app/try-on → your backend upload handler
import { put } from "@vercel/blob";

export async function uploadProduct(file: File) {
  const { url } = await put(`products/${crypto.randomUUID()}.jpg`, file, {
    access: "public",
  });
  return url;
}
const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "product_type": "top",
    "product_images": [
      "https://cdn.yourstore.com/products/shirt-front.jpg"
    ],
    "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
    "product_category": "t_shirt",
    "mannequin_id": "mnk_f3a9b1",
    "pose_id": "pose_c2d4e5",
    "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
    "lock_background": true,
    "resolution": "2K",
    "aspect_ratio": "3:4",
    "body_size": "M",
    "expression": "neutral",
    "user_instruction": "Keep the collar pattern crisp and centered."
  }),
});
const { data } = await res.json(); // data.id, data.status
// Trigger.dev / Inngest / BullMQ task
const BASE = "https://api.photta.app/api/v1";

export const pollTryOnTask = task({
  id: "poll-try-on",
  run: async ({ generationId, attempt = 0 }) => {
    const res = await fetch(`${BASE}/tryon/apparel/${generationId}`, {
      headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` },
    });
    const { data } = await res.json();
    if (data.status === "completed") return data.output_url;
    if (data.status === "failed") throw new Error(data.error_message);
    if (attempt >= 120) throw new Error("try-on timed out");
    // Re-schedule this same task after 3 seconds.
    return ctx.retry.after(3000, { generationId, attempt: attempt + 1 });
  },
});

Spørgsmål udviklere stiller

Spørgsmål før du releaser

Kan jeg gøre dette uden en backend?

Nej. Din Photta API-nøgle skal forblive på serversiden. Selv en simpel Next.js route handler eller en Cloudflare Worker tæller som en backend til dette formål — nøglen skal blot ligge et sted, hvor en user-agent ikke kan læse den.

Hvordan undgår jeg hængende HTTP-forespørgsler?

Lav aldrig polling inde i en request handler. Opret jobbet synkront, returner generations-id'et til klienten, og lav polling fra en background worker. Klienten poller DIT status-endpoint, ikke Phottas — på den måde er rate limits dit problem at håndtere, ikke den enkelte brugers.

Hvad sker der, hvis et job fejler undervejs?

Photta refunderer automatisk credits ved fejl, og svaret indeholder data.error_code + data.error_message. Vis en brugervenlig besked til brugeren, og tilbyd en retry-knap, der starter et nyt job.

Kan jeg vise reel fremgang?

Photta udsender ikke mellemliggende statusopdateringer — status er enten processing, completed eller failed. Hvad der fungerer godt, er en tidsbaseret progress bar kalibreret til et vindue på 1.5–4 minutter, eller en simpel skeleton loader. Lad være med at opdigte procenter.

Er resultatets URL permanent?

CDN-URL'en er stabil, men dit produkt bør ikke være afhængigt af den til langsigtet rendering. Download bytes én gang, og gem dem i din egen S3/GCS/R2-bucket — så fortsætter dit PDP med at virke, selvom Phottas CDN flytter sig.

Få virtuel try-on i produktion på en eftermiddag

Hvert kodeeksempel på denne side stemmer overens med den officielle Photta-dokumentation. Hent en API-nøgle, og du har en fungerende prototype, inden kaffen er brygget færdig.