Node.js · API try-on per gioielli
API try-on per gioielli in Node.js
In sintesi
Imposta PHOTTA_API_KEY nell'ambiente, scrivi un piccolo helper fetch per https://api.photta.app/api/v1 con chiave Bearer, invia una POST a /api/v1/tryon/jewelry, quindi esegui il polling su /api/v1/tryon/jewelry/{id} ogni 3 secondi fino a quando lo stato non è completed.
- Tempo tipico: 1.5–4 min
- Credits: 5 credits a 2K · 6 credits a 4K
- Elaborazione: asincrono, polling
- Limiti: 600 richieste/min
- Autenticazione: Chiave Bearer
Ogni dato in questa pagina proviene da la documentazione dell'API di Photta · verificato
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/jewelry \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')
# $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed".
for i in $(seq 1 120); do
RESULT=$(curl -s "https://api.photta.app/api/v1/tryon/jewelry/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.data.status')
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "generation failed" && exit 1
sleep 3
done
echo "$RESULT" | jq -r '.data.output_url'const res = await fetch("https://api.photta.app/api/v1/tryon/jewelry", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
}),
});
const { data } = await res.json(); // data.id, data.status
async function waitFor(id) {
for (let attempt = 0; attempt < 120; attempt++) {
const res = await fetch(`https://api.photta.app/api/v1/tryon/jewelry/${id}`, { 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 ?? "generation failed");
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("timed out after 6 minutes");
}import os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/jewelry",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
},
)
data = res.json()["data"] # data["id"], data["status"]
import time
def wait_for(job_id):
for _ in range(120):
res = requests.get(f"https://api.photta.app/api/v1/tryon/jewelry/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"})
data = res.json()["data"]
if data["status"] == "completed":
return data["output_url"]
if data["status"] == "failed":
raise RuntimeError(data.get("error_message", "generation failed"))
time.sleep(3)
raise TimeoutError("timed out after 6 minutes")Panoramica
Panoramica
- Endpoint
- POST /api/v1/tryon/jewelry
- Autenticazione
- API key Bearer
- Elaborazione
- Asincrona — effettua il polling dell'endpoint di stato
- Tempo tipico
- 1.5–4 min
- Credits
- 5 credits a 2K · 6 credits a 4K
- Rapporti d'aspetto
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Limiti di input
- Fino a 10 MB per immagine; JPEG, PNG, WebP
- Idempotente
- No
Come funziona
Cinque passaggi, circa cinque minuti dalla registrazione alla prima immagine.
Passaggio 1
Registrati e genera una chiave
Crea un account su ai.photta.app. Apri la sezione Developers della dashboard, fai clic su Generate API key e copia la chiave live. Inizia con `photta_live_` seguito da 32 caratteri esadecimali.
Passaggio 2
Conserva la chiave nelle variabili d'ambiente, non nel codice sorgente
Aggiungi `PHOTTA_API_KEY=...` al file `.env` (o al secret store della tua piattaforma) e caricala tramite `process.env`. Non committare mai la chiave; non importarla mai in un file contrassegnato con `'use client'` — il bundler la includerebbe nel browser.
node --version # 18 or later ships fetch echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .envPassaggio 3
Scrivi un piccolo helper per fetch
Un wrapper di 20 righe attorno a `fetch()` gestisce l'URL di base, l'header Authorization, il body JSON e la normalizzazione degli errori. Questa è l'unica astrazione necessaria finché non verrà rilasciato un SDK ufficiale.
// photta.js — one helper for every endpoint const BASE = "https://api.photta.app/api/v1"; export async function photta(path, init = {}) { const res = await fetch(BASE + path, { ...init, headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json", ...(init.headers ?? {}) } }); const body = await res.json(); if (!res.ok) throw Object.assign(new Error(body.error?.message ?? res.statusText), { status: res.status, retryAfter: res.headers.get("Retry-After"), body }); return body; }Passaggio 4
Invia un try-on ed esegui il polling
Invia una richiesta POST a `/api/v1/tryon/jewelry` con il body di esempio documentato — il codice sottostante include ogni campo. L'API restituisce immediatamente un ID di generazione. Esegui il polling su `/api/v1/tryon/jewelry/{id}` ogni 3 secondi finché `status === 'completed'`.
const res = await fetch("https://api.photta.app/api/v1/tryon/jewelry", { method: "POST", headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ "jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg", "jewelry_type": "necklace", "mannequin_id": "mnk_j9k1l2", "background": "soft window light on dark velvet", "resolution": "2K", "aspect_ratio": "3:4", "user_instruction": "Make the pendant 10% smaller." }), }); const { data } = await res.json(); // data.id, data.status async function waitFor(id) { for (let attempt = 0; attempt < 120; attempt++) { const res = await fetch(`https://api.photta.app/api/v1/tryon/jewelry/${id}`, { 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 ?? "generation failed"); await new Promise((r) => setTimeout(r, 3000)); } throw new Error("timed out after 6 minutes"); }Passaggio 5
Salva il risultato
Il payload completato include `output_url` e `thumbnail_url`. Recupera i byte una sola volta e archiviali nel tuo object storage — gli URL sono stabili, ma il tuo prodotto non dovrebbe dipendere dalla CDN di Photta per il rendering.
Errori
- 400
invalid_request_error - The request is malformed or contains invalid parameters.
- 401
authentication_error - The API key is missing, invalid, or expired.
- 402
insufficient_credits_error - Your account does not have enough credits.
- 404
not_found_error - The requested resource does not exist.
- 409
conflict_error - The request conflicts with current state — e.g. your concurrent-batch cap is reached.
- 429
rate_limit_error - Too many requests. Slow down and retry.Retry-After: 30
- 500
api_error - An internal server error occurred. Retry later.
try {
await photta("/tryon/jewelry", { method: "POST", body: JSON.stringify({
"jewelry_image": "https://cdn.yourstore.com/products/gold-necklace.jpg",
"jewelry_type": "necklace",
"mannequin_id": "mnk_j9k1l2",
"background": "soft window light on dark velvet",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "Make the pendant 10% smaller."
}) });
} catch (err) {
if (err.status === 402) console.error("insufficient_credits_error: top up before retrying");
else if (err.status === 429) await new Promise((r) => setTimeout(r, Number(err.retryAfter ?? 30) * 1000));
else throw err;
}Limiti
- 600 richieste al minuto per API key (Finestra fissa; il limite è lo stesso per ogni piano)
- Un 429 restituisce Retry-After: 30 secondi
- Fino a 10 MB per immagine
- Formati: JPEG, PNG, WebP
- Batch simultanei per piano: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Solo polling — l'API non invia webhook.
Perché un helper batte una libreria client — per ora
- Node 18+ include fetch nativo — nessuna dipendenza di runtime
- Lo stesso helper funziona all'interno di route handler di Next.js, server action e qualsiasi worker
- Mantieni la chiave API nelle variabili d'ambiente; non importare mai l'helper da un modulo 'use client' altrimenti il bundler la esporrà
- Funziona con qualsiasi coda o cron: BullMQ, Inngest, Trigger.dev, Vercel Cron, Cloudflare Queues
Cosa non fa
- Nessun pacchetto ufficiale @photta/node al momento — REST è l'unica via oggi
- Il polling è l'unico segnale di completamento; l'API non invia webhook
- Solo chiave Bearer; non è previsto un flusso OAuth client-credentials
Domande frequenti degli sviluppatori
Esiste un SDK Node.js ufficiale di Photta?
Non ancora. Il percorso documentato è REST puro tramite la fetch nativa di Node — l'helper in questa pagina rappresenta l'intera superficie di integrazione e funziona allo stesso modo per ogni capability.
Quali versioni di Node.js sono supportate?
Qualsiasi versione che supporti `fetch` nativo — ovvero Node 18 e successive. Su Node 16 puoi usare un polyfill con `node-fetch` oppure aggiornare la versione. Il resto del codice è plain ECMAScript 2020 (async/await, template literals, import dinamici), quindi nessun altro requisito di runtime.
Come si effettua l'autenticazione da Node?
Invia `Authorization: Bearer photta_live_xxx` su ogni richiesta. Inserisci la chiave in una variabile d'ambiente e caricala tramite `process.env`; non importarla mai da un file eseguito nel browser.
Come si gestisce la finestra di generazione?
L'endpoint di generazione è completamente asincrono. La POST restituisce immediatamente un ID di generazione con `status: 'processing'`. Esegui il polling con `GET /api/v1/tryon/jewelry/{id}` ogni 3–5 secondi finché lo `status` non passa a `completed` o `failed`, e limita i tentativi in modo che un job bloccato non mantenga la richiesta in sospeso.
Posso chiamare l'API all'interno di Next.js?
Sì — da un route handler (`app/**/route.ts`), una server action (`'use server'`) o un middleware. Mantieni la chiave API sul server; non importare mai l'helper da un file `'use client'`. Per job di lunga durata che superano il timeout delle funzioni di Vercel, delega il polling a una coda (Inngest, Trigger.dev, BullMQ) e restituisci l'ID di generazione al browser affinché possa effettuare il polling sul tuo endpoint di stato.
Come segnala gli errori l'API?
Le risposte non-2xx contengono un body JSON con un oggetto `error`: `type`, `code`, `message` e un ID di richiesta per il supporto. Casi comuni: 400 invalid_request_error con `param` che punta al campo errato; 402 insufficient_credits con il conteggio di `required` e `available`; 429 rate_limit_exceeded con `retry_after` in secondi e un header Retry-After corrispondente. Gli errori 5xx possono essere ritentati in sicurezza con backoff esponenziale.
Pagine correlate
Python
API try-on per gioielli in Python
Chiama la aPI try-on per gioielli di Photta in Python con la libreria requests. Wrapper di trenta righe, compatibile con async tramite httpx, funziona in Django, FastAPI e Celery.
LeggicURL
API try-on per gioielli con cURL
Chiama aPI try-on per gioielli di Photta direttamente dalla shell con cURL. Invia, effettua il polling, scarica — ogni snippet si integra con jq per pipeline basate su script.
LeggiFunzionalità
API try-on per gioielli per collane, anelli, bracciali e orecchini
Applica collane, anelli, bracciali e orecchini su modelli AI tramite REST. 5 credits a 2K, manichini in primo piano integrati, rendering con gestione dei riflessi dalla documentazione di Photta.
LeggiSviluppa
Crea un servizio di fotografia di prodotto basato su AI
La guida per i founder per rivendere l'API di virtual try-on di Photta come SaaS white-label: tenant key, fanout in batch, fatturazione per credits, realtà degli SLA.
LeggiGuida rapida
La prima immagine con Photta in meno di cinque minuti.
Registrati, genera una chiave API, esegui la tua prima chiamata cURL, fai polling fino al completamento, salva il risultato. Cinque passaggi, interamente documentati.
LeggiRiferimento
Prezzi dell'API Photta
Il costo in crediti di ogni endpoint delle API di Photta a 2K e 4K, il funzionamento di addebiti e rimborsi, e quali endpoint sono gratuiti. Nessun prezzo monetario per immagine.
Leggi
Ogni dato in questa pagina proviene da la documentazione dell'API di Photta · verificato
Prova l'API in 5 minuti
Genera una chiave API di Photta, incolla lo snippet cURL qui sopra e otterrai la tua prima immagine con modello prima ancora che il caffè sia pronto.
- 1.5–4 min
- 5 credits a 2K · 6 credits a 4K
- asincrono, polling
- 600 richieste/min
- Chiave Bearer