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')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.statusimport os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"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."
},
)
data = res.json()["data"] # data["id"], data["status"]Cara kerja
Dari unggahan hingga gambar on-model
Enam langkah konkret. Siapkan sepuluh hingga lima belas menit waktu integrasi untuk pertama kali.
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.
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.
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.
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.
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.
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.
Halaman terkait
Referensi
Kapabilitas
Virtual try-on API untuk pakaian
REST API yang memakaikan pakaian pada manekin AI. Asinkron, waktu generasi 1.5–4 menit, 5 credits pada 2K, 6 pada 4K. Contoh cURL, Node.js, dan Python.
BacaQuickstart
Gambar Photta pertama dalam waktu kurang dari lima menit.
Daftar, buat API key, jalankan pemanggilan cURL pertama Anda, lakukan polling hingga selesai, simpan hasilnya. Lima langkah, terdokumentasi end-to-end.
BacaBahasa
Node.js walkthrough
BacaBahasa
Python walkthrough
Baca
Setiap angka di halaman ini bersumber dari dokumentasi API Photta · diperiksa
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.