Wdróż · Virtual Try-On
Zbuduj funkcję virtual try-on dla swojej aplikacji
W jednym zdaniu
Odbierz zdjęcie produktu w swoim backendzie, wyślij żądanie POST do /api/v1/tryon/apparel z mannequin ID, odpytuj zwrócony generation ID w tle za pomocą workera (nigdy w wątku żądania HTTP) do momentu, aż status zmieni się na completed, a następnie zapisz output_url we własnym object storage i wyrenderuj go w UI.
- Credits: 5 credits w 2K · 6 credits w 4K
- Typowy czas: 1.5–4 min
- Przetwarzanie: asynchroniczne, polling
Każda liczba na tej stronie pochodzi z dokumentacji API Photta · sprawdzono
Sprawdzony na produkcji schemat: klient przesyła zdjęcie produktu, Twój backend kolejkuje zadanie try-on w Photta, worker wykonuje polling do momentu zakończenia, a frontend wyświetla wynik na modelu. Bez blokujących żądań, bez wyciekających kluczy API, bez sztucznych 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')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"]Jak to działa
Od uploadu do zdjęcia na modelu
Sześć konkretnych kroków. Przy pierwszym podejściu zarezerwuj od dziesięciu do piętnastu minut na integrację.
Krok 1
Rozrysuj przepływ danych
Urządzenie klienta → Twój backend (upload) → Photta API (submit) → Photta API (polling) → Twoja baza danych (odzwierciedlenie statusu) → urządzenie klienta (renderowanie). Rozrysuj to na kartce przed napisaniem pierwszej linijki kodu — granica między Twoim backendem a Photta to jedyna rzecz, która ma znaczenie.
Krok 2
Wygeneruj i zapisz klucz API
Klucze produkcyjne zaczynają się od photta_live_. Zapisz go w zmiennej środowiskowej. Nigdy nie przesyłaj go do przeglądarki. Jeden klucz obsługuje każdą funkcjonalność Photta, więc nie potrzebujesz osobnych kluczy dla try-on, jewelry ani ghost mannequin.
Krok 3
Skonfiguruj endpoint do uploadu
W pierwszej kolejności zapisz zdjęcie produktu przesłane przez klienta w object storage. Przekazanie do Photta publicznego URL jest prostsze niż base64 i zapewnia pełną ścieżkę audytu dla każdego żądania.
Krok 4
Zleć zadanie z poziomu serwera
Wyślij POST do /api/v1/tryon/apparel z adresem URL produktu, mannequin_id, resolution oraz aspect_ratio. API zwróci kod 202 Accepted + generation ID. Zapisz ten ID w swojej bazie danych, aby klient mógł odpytywać Twój własny endpoint, a nie infrastrukturę Photta.
Krok 5
Wykonuj polling z poziomu workera działającego w tle
Nie wykonuj operacji polling wewnątrz żądania HTTP — zadanie trwa od 1.5 do 4 minut, co przekracza limity timeoutu większości środowisk serverless. Użyj Trigger.dev, Inngest, BullMQ, Vercel Cron lub własnej kolejki, aby ponawiać polling co 3 sekundy do momentu ukończenia zadania.
Krok 6
Wyrenderuj wynik
Gdy status zmieni się na completed, skopiuj data.output_url do swojej bazy danych i wyemituj zdarzenie w czasie rzeczywistym (WebSocket, SSE lub long-polling) do urządzenia klienta. UI podmienia placeholder ładowania na gotowy obraz. Gotowe.
Trzy przykłady kodu, end-to-end
Obsługa uploadu, dyspozytor zadań, worker realizujący polling — każdy komponent niezbędny do wdrożenia funkcji.
// 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 });
},
});Pytania zadawane przez programistów
Pytania przed wdrożeniem produkcyjnym
Czy mogę to zrobić bez backendu?
Nie. Twój klucz API Photta musi pozostać po stronie serwera. Nawet prosty route handler w Next.js lub Cloudflare Worker liczy się w tym przypadku jako backend — klucz musi po prostu znajdować się w miejscu niedostępnym dla user-agenta.
Jak uniknąć zawieszających się żądań HTTP?
Nigdy nie wykonuj pollingu wewnątrz handlera żądania. Prześlij zadanie synchronicznie, zwróć identyfikator generowania do klienta i odpytuj z poziomu workera w tle. Klient odpytuje TWÓJ status endpoint, a nie Photta — dzięki temu limity zapytań (rate limits) są Twoim problemem do obsłużenia, a nie każdego użytkownika.
Co się stanie, jeśli zadanie nie powiedzie się w trakcie przetwarzania?
Photta automatycznie zwraca credits w przypadku niepowodzenia, a odpowiedź zawiera data.error_code + data.error_message. Wyświetl przystępny komunikat użytkownikowi i udostępnij przycisk ponowienia, który uruchamia nowe zadanie.
Czy mogę pokazać rzeczywisty postęp?
Photta nie emituje postępu pośredniego — status to processing, completed lub failed. Dobrze sprawdza się pasek postępu z timerem skalibrowanym pod okno 1.5–4 minut lub prosty skeleton loader. Nie przekłamuj wartości procentowych.
Czy URL wyniku jest stały?
URL z CDN jest stabilny, ale Twój produkt nie powinien polegać na nim przy długoterminowym renderowaniu. Pobierz bajty raz i zapisz je we własnym buckecie S3/GCS/R2 — wtedy Twoja strona produktu (PDP) nadal działa, nawet jeśli CDN Photta ulegnie zmianie.
Powiązane strony
Dokumentacja referencyjna
Możliwości
API wirtualnego try-on dla odzieży
REST API, które nakłada odzież na manekiny AI. Asynchroniczne, generowanie w 1.5–4 minuty, 5 credits przy 2K, 6 przy 4K. Przykłady dla cURL, Node.js i Python.
CzytajSzybki start
Pierwszy obraz z Photta w mniej niż pięć minut.
Zarejestruj się, wygeneruj klucz API, wykonaj pierwsze wywołanie cURL, odpytuj aż do ukończenia, zapisz wynik. Pięć kroków opisanych od początku do końca.
CzytajJęzyki
Node.js walkthrough
CzytajJęzyki
Python walkthrough
Czytaj
Każda liczba na tej stronie pochodzi z dokumentacji API Photta · sprawdzono
Wdróż virtual try-on w jedno popołudnie
Każdy przykład kodu na tej stronie jest zgodny z oficjalną dokumentacją Photta. Pobierz klucz API, a będziesz mieć działający prototyp, zanim zaparzy się kawa.