Build · Virtual Try-On

Bangun fitur virtual try-on untuk aplikasi Anda

Ringkasan singkat

Terima foto produk di backend Anda, POST ke /api/v1/tryon/apparel dengan mannequin ID, lakukan polling terhadap generation ID yang dikembalikan dari background worker (jangan pernah dari thread HTTP request) hingga status berubah menjadi completed, lalu simpan output_url ke dalam object storage Anda sendiri dan render di UI.

  • Credits: 5 credits pada 2K · 6 credits pada 4K
  • Waktu umum: 1.5–4 min
  • Pemrosesan: async, polling

Setiap angka di halaman ini bersumber dari dokumentasi API Photta · diperiksa

Resep siap produksi: pelanggan mengunggah foto produk, backend Anda mengantrekan job try-on Photta, worker melakukan polling hingga selesai, frontend menampilkan hasil on-model. Tanpa blocking request, tanpa kebocoran API key, tanpa SDK palsu.

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')

Cara kerja

Dari unggahan hingga gambar on-model

Enam langkah konkret. Siapkan sepuluh hingga lima belas menit waktu integrasi untuk pertama kali.

  1. Langkah 1

    Rancang alur datanya

    Perangkat pelanggan → backend Anda (unggah) → Photta API (submit) → Photta API (polling) → database Anda (cerminan status) → perangkat pelanggan (render). Gambar ini di atas kertas sebelum menulis baris pertama — batasan antara backend Anda dan Photta adalah satu-satunya hal yang penting.

  2. Langkah 2

    Buat dan simpan API key

    Key produksi diawali dengan photta_live_. Simpan di environment variable. Jangan pernah mengirimkannya ke browser. Satu key mencakup setiap kapabilitas Photta, jadi Anda tidak memerlukan key terpisah untuk try-on, perhiasan, atau ghost mannequin.

  3. Langkah 3

    Siapkan endpoint unggahan

    Terima foto produk pelanggan ke dalam object storage terlebih dahulu. Memberikan URL publik ke Photta lebih sederhana daripada base64 dan memberi Anda audit trail untuk setiap request.

  4. Langkah 4

    Kirimkan job dari server

    POST /api/v1/tryon/apparel dengan URL produk, mannequin_id, resolution, dan aspect_ratio. API akan mengembalikan 202 Accepted + sebuah generation ID. Simpan ID tersebut di database Anda agar client dapat melakukan polling ke endpoint Anda sendiri, bukan ke endpoint Photta.

  5. Langkah 5

    Lakukan polling dari background worker

    Jangan lakukan polling di dalam HTTP request — job ini membutuhkan waktu 1.5 hingga 4 menit, yang melebihi batas waktu sebagian besar serverless. Gunakan Trigger.dev, Inngest, BullMQ, Vercel Cron, atau antrean Anda sendiri untuk menjadwalkan ulang polling setiap 3 detik hingga job selesai.

  6. Langkah 6

    Render hasilnya

    Saat status berubah menjadi completed, salin data.output_url ke database Anda dan kirimkan event realtime (websocket, SSE, atau long-poll) ke perangkat pelanggan. UI akan menukar loading skeleton dengan gambar. Selesai.

Tiga contoh kode, end to end

Handler unggahan, job dispatcher, worker-side poller — setiap bagian yang Anda butuhkan untuk merilis fitur ini.

// 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 });
  },
});

Pertanyaan umum developer

Pertanyaan sebelum Anda merilis

Bisakah saya melakukan ini tanpa backend?

Tidak. Kunci API Photta Anda harus tetap berada di sisi server. Bahkan route handler Next.js yang sederhana atau Cloudflare Worker sudah terhitung sebagai backend untuk kebutuhan ini — kuncinya hanya perlu berada di tempat yang tidak dapat dibaca oleh user-agent.

Bagaimana cara menghindari request HTTP yang menggantung?

Jangan pernah melakukan polling di dalam request handler. Kirim job secara sinkron, kembalikan ID pembuatan ke klien, dan lakukan polling dari background worker. Klien melakukan polling ke endpoint status MILIK ANDA, bukan Photta — dengan begitu rate limit menjadi urusan Anda untuk dikelola, bukan urusan masing-masing pengguna.

Apa yang terjadi jika sebuah job gagal di tengah jalan?

Photta mengembalikan credits secara otomatis saat terjadi kegagalan, dan respons membawa data.error_code + data.error_message. Tampilkan pesan yang ramah kepada pengguna dan sediakan tombol coba lagi yang memulai job baru.

Bisakah saya menampilkan progres yang sebenarnya?

Photta tidak memancarkan progres perantara — statusnya adalah processing, completed, atau failed. Solusi yang bekerja dengan baik adalah bilah progres berwaktu yang dikalibrasi ke rentang 1.5–4 menit, atau skeleton loader sederhana. Jangan memalsukan persentase.

Apakah URL hasil bersifat permanen?

URL CDN stabil, tetapi produk Anda sebaiknya tidak bergantung padanya untuk rendering jangka panjang. Unduh byte-nya sekali dan simpan di bucket S3/GCS/R2 Anda sendiri — dengan begitu PDP Anda tetap berfungsi meskipun CDN Photta berpindah.

Rilis virtual try-on dalam waktu satu sore

Setiap sampel kode di halaman ini cocok dengan dokumentasi resmi Photta. Ambil kunci API dan Anda akan memiliki prototipe yang berfungsi sebelum kopi selesai diseduh.