Bygg · Virtuell Try-On

Bygg en virtuell try-on-funksjon for appen din

I én setning

Motta produktbildet i backenden din, POST det til /api/v1/tryon/apparel med en mannequin ID, poll den returnerte generasjons-ID-en fra en bakgrunns-worker (aldri i HTTP-forespørselstråden) til status endres til completed, lagre deretter output_url i din egen objektlagring og vis det i brukergrensesnittet.

  • Credits: 5 credits ved 2K · 6 credits ved 4K
  • Typisk tidsbruk: 1.5–4 min
  • Prosessering: asynkron, polling

Hvert tall på denne siden er hentet fra dokumentasjonen for Photta-API-et · verifisert

En produksjonsklar oppskrift: kunden laster opp et produktbilde, backenden din setter en Photta try-on-jobb i kø, en worker poller til den er ferdig, frontenden viser resultatet på modellen. Ingen blokkerende forespørsler, ingen lekkede API-nøkler, 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')

Slik fungerer det

Fra opplasting til bilde på modell

Seks konkrete trinn. Forvent ti til femten minutter med integrasjonsarbeid første gang.

  1. Trinn 1

    Skisser dataflyten

    Kundens enhet → din backend (opplasting) → Photta API (innsending) → Photta API (polling) → din database (statusspeiling) → kundens enhet (visning). Tegn dette på papir før du skriver den første linjen — skillet mellom din backend og Phottas er det eneste som betyr noe.

  2. Trinn 2

    Generer og lagre en API-nøkkel

    Produksjonsnøkler starter med photta_live_. Legg den i en miljøvariabel. Send den aldri til nettleseren. Én nøkkel dekker alle Photta-funksjoner, så du trenger ikke separate nøkler for try-on, smykker eller ghost mannequin.

  3. Trinn 3

    Sett opp opplastingsendepunktet

    Motta kundens produktbilde i objektlagring først. Å gi Photta en offentlig URL er enklere enn base64 og gir deg en sporingslogg for hver forespørsel.

  4. Trinn 4

    Send inn jobben fra serveren

    POST /api/v1/tryon/apparel med produktets URL, mannequin_id, resolution og aspect_ratio. API-et returnerer 202 Accepted + en generasjons-ID. Lagre ID-en i databasen din slik at klienten din kan polle ditt eget endpoint, ikke Phottas.

  5. Trinn 5

    Poll fra en bakgrunns-worker

    Ikke poll inne i HTTP-forespørselen — jobben tar 1.5 til 4 minutter, noe som overskrider de fleste serverless-tidsavbrudd. Bruk Trigger.dev, Inngest, BullMQ, Vercel Cron eller din egen kø til å planlegge ny polling hvert 3. sekund til jobben er fullført.

  6. Trinn 6

    Vis resultatet

    Når status endres til completed, kopierer du data.output_url til databasen din og sender et sanntids-event (websocket, SSE eller long-poll) til kundens enhet. Brukergrensesnittet bytter ut lasteskjelettet med bildet. Ferdig.

Tre kodeeksempler, ende til ende

Opplastingshåndterer, jobbdistributør, worker-poller — hver eneste del du trenger for å lansere funksjonen.

// 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ørsmål utviklere stiller

Spørsmål før du setter i produksjon

Kan jeg gjøre dette uten en backend?

Nei. Photta-API-nøkkelen din må forbli på serversiden. Selv en tynn Next.js route handler eller en Cloudflare Worker regnes som en backend for dette formålet — nøkkelen må bare ligge et sted der en user-agent ikke kan lese den.

Hvordan unngår jeg hengende HTTP-forespørsler?

Utfør aldri polling inne i en request handler. Send inn jobben synkront, returner generasjons-ID-en til klienten, og gjør polling fra en bakgrunns-worker. Klienten poller DITT status-endpoint, ikke Phottas — på den måten er rate limits ditt problem å håndtere, ikke hver enkelt brukers.

Hva skjer hvis en jobb feiler underveis?

Photta refunderer credits automatisk ved feil, og responsen inneholder data.error_code + data.error_message. Vis en vennlig melding til brukeren og tilby en prøv igjen-knapp som starter en ny jobb.

Kan jeg vise reell fremdrift?

Photta sender ikke ut mellomliggende fremdrift — status er enten processing, completed eller failed. Det som fungerer bra, er en tidsstyrt fremdriftslinje kalibrert til vinduet på 1.5–4 minutter, eller en enkel skeleton loader. Ikke lyv om prosenter.

Er resultat-URL-en permanent?

CDN-URL-en er stabil, men produktet ditt bør ikke være avhengig av den for langsiktig visning. Last ned bytene én gang og lagre dem i din egen S3/GCS/R2-bøtte — da fortsetter produktsiden din å fungere selv om Phottas CDN flyttes.

Lanser virtuell try-on på en ettermiddag

Hvert kodeeksempel på denne siden samsvarer med den offisielle Photta-dokumentasjonen. Hent en API-nøkkel, så har du en fungerende prototype før kaffen er ferdig traktet.