Bygg · Virtuell try-on

Bygg en virtuell try-on-funktion för din app

I en mening

Ta emot produktfotot i din backend, gör en POST till /api/v1/tryon/apparel med ett mannequin ID, gör polling på det returnerade genererings-ID:t från en bakgrunds-worker (aldrig i HTTP-anropstråden) tills status slår om till completed, persistera sedan output_url i din egen objektlagring och rendera den i gränssnittet.

  • Credits: 5 credits vid 2K · 6 credits vid 4K
  • Typisk tid: 1.5–4 min
  • Bearbetning: asynkron, polling

Varje siffra på den här sidan kommer från Photter API-dokumentationen · kontrollerad

Ett produktionsanpassat recept: kunden laddar upp ett produktfoto, din backend köar ett Photta try-on-jobb, en worker gör polling tills det är klart, frontend visar resultatet på modellen. Inga blockerande anrop, inga läckta API-nycklar, inget fejk-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')

Hur det fungerar

Från uppladdning till bild på modell

Sex konkreta steg. Räkna med tio till femton minuters integrationsarbete första gången.

  1. Steg 1

    Skissa dataflödet

    Kundens enhet → din backend (uppladdning) → Photta API (skicka in) → Photta API (polling) → din databas (statusspegling) → kundens enhet (rendering). Rita detta på papper innan du skriver första raden — gränsen mellan din backend och Phottas är det enda som spelar roll.

  2. Steg 2

    Generera och lagra en API-nyckel

    Produktionsnycklar börjar med photta_live_. Spara den i en miljövariabel. Skicka den aldrig till webbläsaren. En nyckel täcker varje Photta-kapabilitet, så du behöver inte separata nycklar för try-on, smycken eller ghost mannequin.

  3. Steg 3

    Koppla upp endpointen för uppladdning

    Ta emot kundens produktfoto i objektlagringen först. Att ge Photta en publik URL är enklare än base64 och ger dig en granskningslogg för varje förfrågan.

  4. Steg 4

    Skicka in jobbet från servern

    Gör en POST till /api/v1/tryon/apparel med produktens URL, mannequin_id, resolution och aspect_ratio. API:et returnerar 202 Accepted + ett genererings-ID. Spara ID:t i din databas så att din klient kan göra polling mot din egen endpoint, inte Phottas.

  5. Steg 5

    Gör polling från en bakgrunds-worker

    Gör inte polling inuti HTTP-förfrågan — jobbet tar 1.5 till 4 minuter, vilket överskrider de flesta serverless-timeouts. Använd Trigger.dev, Inngest, BullMQ, Vercel Cron eller din egen kö för att schemalägga en ny poll var 3:e sekund tills jobbet är slutfört.

  6. Steg 6

    Rendera resultatet

    När status ändras till completed, kopiera data.output_url till din databas och skicka ett realtidsevent (websocket, SSE eller long-polling) till kundens enhet. Gränssnittet byter ut laddningsskelettet mot bilden. Klart.

Tre kodexempel, från start till mål

Uppladdningshanterare, jobb-dispatcher, worker-baserad poller — alla delar du behöver för att lansera 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 });
  },
});

Vanliga utvecklarfrågor

Frågor innan du driftsätter

Kan jag göra detta utan en backend?

Nej. Din Photta-API-nyckel måste stanna på serversidan. Även en tunn Next.js-route-handler eller en Cloudflare Worker räknas som en backend i det här avseendet — nyckeln behöver bara finnas någonstans där en användaragent inte kan läsa den.

Hur undviker jag hängande HTTP-anrop?

Polla aldrig inuti en request handler. Skicka jobbet synkront, returnera genererings-ID:t till klienten och polla från en bakgrundsworker. Klienten pollar DITT status-endpoint, inte Phottas — på så sätt är rate limits ditt problem att hantera, inte varje enskild användares.

Vad händer om ett jobb misslyckas mitt under körning?

Photta återbetalar credits automatiskt vid fel, och svaret innehåller data.error_code + data.error_message. Visa ett begripligt meddelande för användaren och erbjud en knapp för att försöka igen som startar ett nytt jobb.

Kan jag visa faktisk förloppsstatus?

Photta skickar inte ut mellanliggande förloppsstatus — status är antingen processing, completed eller failed. Det som fungerar bra är en tidsstyrd progress bar kalibrerad för tidsfönstret på 1,5–4 minuter, eller en enkel skeleton loader. Ljug inte om procentsatser.

Är resultatets URL permanent?

CDN-URL:en är stabil, men din produkt bör inte förlita sig på den för långsiktig rendering. Ladda ner byten en gång och spara dem i din egen S3/GCS/R2-bucket — då fortsätter din PDP att fungera även om Phottas CDN flyttas.

Lansera virtuell try-on på en eftermiddag

Varje kodexempel på den här sidan matchar Phottas officiella dokumentation. Hämta en API-nyckel så har du en fungerande prototyp innan kaffet har bryggts klart.