Node.js · API for smykke-try-on
API for smykke-try-on i Node.js
I én setning
Sett PHOTTA_API_KEY i env, skriv en liten fetch-hjelper for https://api.photta.app/api/v1 med en Bearer-nøkkel, POST til /api/v1/tryon/jewelry, og poll deretter /api/v1/tryon/jewelry/{id} hvert 3. sekund til status er completed.
- Typisk tidsbruk: 1.5–4 min
- Credits: 5 credits ved 2K · 6 credits ved 4K
- Prosessering: asynkron, polling
- Grenser: 600 forespørsler/min
- Autentisering: Bearer-nøkkel
Hvert tall på denne siden er hentet fra dokumentasjonen for Photta-API-et · verifisert
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")Kort oppsummert
Kort oppsummert
- Endepunkt
- POST /api/v1/tryon/jewelry
- Autentisering
- Bearer API-nøkkel
- Prosessering
- Asynkron – poll status-endepunktet
- Typisk tidsbruk
- 1.5–4 min
- Credits
- 5 credits ved 2K · 6 credits ved 4K
- Bildeformater
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Inndatagrenser
- Opptil 10 MB per bilde; JPEG, PNG, WebP
- Idempotent
- Nei
Slik fungerer det
Fem steg, omtrent fem minutter fra registrering til første bilde.
Trinn 1
Registrer deg og generer en nøkkel
Opprett en konto på ai.photta.app. Åpne Developers-seksjonen i dashbordet, klikk Generate API key, og hent live-nøkkelen. Den starter med `photta_live_` etterfulgt av 32 hex-tegn.
Trinn 2
Lagre nøkkelen i env, ikke i kildekoden
Legg til `PHOTTA_API_KEY=...` i `.env` (eller plattformens hemmelighetslager) og last den inn via `process.env`. Du må aldri committe nøkkelen, og aldri importere den i en fil merket med `'use client'` — bundleren vil dra den inn i nettleseren.
node --version # 18 or later ships fetch echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .envTrinn 3
Skriv en liten fetch-hjelper
En 20-linjers wrapper rundt `fetch()` håndterer base-URL, Authorization-header, JSON-body og feilnormalisering. Dette er den eneste abstraksjonen du trenger inntil en offisiell SDK lanseres.
// 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; }Trinn 4
Send inn en try-on og poll
POST til `/api/v1/tryon/jewelry` med den dokumenterte eksempel-bodyen — koden nedenfor inneholder alle felter. API-et returnerer en genererings-ID umiddelbart. Poll `/api/v1/tryon/jewelry/{id}` hvert 3. sekund til `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"); }Trinn 5
Persister resultatet
Den fullførte payloaden inkluderer `output_url` og `thumbnail_url`. Hent bytene én gang og lagre dem i din egen objektlagring — URL-ene er stabile, men produktet ditt bør ikke være avhengig av Phottas CDN for rendering.
Feil
- 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;
}Grenser
- 600 forespørsler per minutt per API-nøkkel (Fast tidsvindu; grensen er lik for alle abonnementer)
- En 429 inneholder Retry-After: 30 sekunder
- Opptil 10 MB per bilde
- Formater: JPEG, PNG, WebP
- Samtidige batcher per abonnement: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Kun polling – API-et sender ikke webhooks.
Hvorfor en hjelper slår et klientbibliotek — foreløpig
- Node 18+ leveres med native fetch — ingen kjøretidsavhengigheter
- Den samme hjelperen fungerer i Next.js route handlers, server actions og alle typer workers
- Hold API-nøkkelen i env; importer aldri hjelperen fra en 'use client'-modul, ellers vil bundleren lekke den
- Fungerer med alle køer og cron-tjenester: BullMQ, Inngest, Trigger.dev, Vercel Cron, Cloudflare Queues
Hva den ikke gjør
- Ingen offisiell @photta/node-pakke ennå — REST er den eneste veien i dag
- Polling er det eneste fullføringssignalet; API-et sender ingen webhooks
- Kun Bearer-nøkkel; det finnes ingen OAuth client-credentials-flyt
Spørsmål utviklere stiller
Finnes det en offisiell Photta Node.js-SDK?
Ikke ennå. Den dokumenterte veien er ren REST via Nodes native fetch — hjelperen på denne siden utgjør hele integrasjonsflaten, og den fungerer likt for alle capabilities.
Hvilke Node.js-versjoner støttes?
Alt som støtter native `fetch` — som betyr Node 18 og nyere. På Node 16 må du enten polyfille med `node-fetch` eller oppgradere. Resten av koden er ren ECMAScript 2020 (async/await, template literals, dynamiske imports), så det er ingen andre kjøretidskrav.
Hvordan autentiserer jeg fra Node?
Send `Authorization: Bearer photta_live_xxx` på hver forespørsel. Legg nøkkelen i en miljøvariabel og les den via `process.env`; importer den aldri fra en fil som kjører i nettleseren.
Hvordan håndterer jeg genereringsvinduet?
Genererings-endpointet er fullstendig asynkront. POST returnerer en genererings-ID umiddelbart med `status: 'processing'`. Poll `GET /api/v1/tryon/jewelry/{id}` hvert 3.–5. sekund til `status` endres til `completed` eller `failed`, og sett en grense for antall forsøk slik at en jobb som henger seg opp ikke låser en forespørsel.
Kan jeg kalle API-et inne i Next.js?
Ja — fra en route handler (`app/**/route.ts`), en server action (`'use server'`) eller middleware. Hold API-nøkkelen på serveren; importer aldri hjelperen fra en `'use client'`-fil. For langvarige jobber som overskrider Vercels funksjonstimeout, utsett pollingen til en kø (Inngest, Trigger.dev, BullMQ) og returner genererings-ID-en til nettleseren slik at den kan polle ditt eget status-endpoint.
Hvordan signaliserer API-et feil?
Ikke-2xx-responser inneholder en JSON-body med et `error`-objekt: `type`, `code`, `message` og en request-ID for support. Vanlige tilfeller: 400 invalid_request_error med `param` pekende på det ugyldige feltet; 402 insufficient_credits med `required`- og `available`-antall; 429 rate_limit_exceeded med `retry_after` i sekunder og en tilhørende Retry-After-header. 5xx-feil er trygge å prøve på nytt med eksponensiell backoff.
Relaterte sider
Python
API for smykke-try-on i Python
Kall Phottas aPI for smykke-try-on i Python med requests-biblioteket. Tretti linjers wrapper, async-vennlig via httpx, fungerer i Django, FastAPI og Celery.
LescURL
API for smykke-try-on med cURL
Kall Phottas aPI for smykke-try-on direkte fra kommandolinjen med cURL. Send inn, poll, last ned — alle kodesnutter kan kombineres med jq for skriptede pipelines.
LesFunksjoner
API for smykke-try-on for halskjeder, ringer, armbånd og øredobber
Plasser halskjeder, ringer, armbånd og øredobber på AI-modeller via REST. 5 credits ved 2K, innebygde nærbilde-mannekenger, refleksjonsbevisst rendering fra Photta-dokumentasjonen.
LesBygg
Bygg en tjeneste for AI-produktfotografering
En gründers oppskrift for å videreselge Phottas virtuelle try-on-API som en white-label-SaaS: tenant-nøkler, batch-fanout, fakturering per credit, SLA-virkelighet.
LesHurtigstart
Første Photta-bilde på under fem minutter.
Registrer deg, generer en API-nøkkel, kjør ditt første cURL-kall, utfør polling til det er fullført, lagre resultatet. Fem trinn, dokumentert fra start til slutt.
LesReferanse
Photta API-priser
Hva hvert Photta API-endepunkt koster i credits ved 2K og 4K, hvordan trekk og refusjoner fungerer, og hvilke endepunkter som er gratis. Ingen pengepris per bilde.
Les
Hvert tall på denne siden er hentet fra dokumentasjonen for Photta-API-et · verifisert
Prøv API-et på fem minutter
Generer en Photta API-nøkkel, lim inn cURL-kodesnutten ovenfor, og du har ditt første bilde på modell før kaffen er ferdig traktet.
- 1.5–4 min
- 5 credits ved 2K · 6 credits ved 4K
- asynkron, polling
- 600 forespørsler/min
- Bearer-nøkkel