Node.js · Try-on-API til smykker
Try-on-API til smykker i Node.js
I én sætning
Sæt PHOTTA_API_KEY i env, skriv en lille fetch-helper til https://api.photta.app/api/v1 med en Bearer-nøgle, POST til /api/v1/tryon/jewelry, og foretag derefter polling på /api/v1/tryon/jewelry/{id} hvert 3. sekund, indtil status er completed.
- Typisk tid: 1.5–4 min
- Credits: 5 credits ved 2K · 6 credits ved 4K
- Behandling: async, polling
- Grænser: 600 requests/min
- Autentifikation: Bearer key
Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket
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 fortalt
Kort fortalt
- Endpoint
- POST /api/v1/tryon/jewelry
- Autentifikation
- Bearer API-nøgle
- Behandling
- Asynkron — poll status-endpointet
- Typisk tid
- 1.5–4 min
- Credits
- 5 credits ved 2K · 6 credits ved 4K
- Billedformater
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Inputgrænser
- Op til 10 MB pr. billede; JPEG, PNG, WebP
- Idempotent
- Nej
Sådan virker det
Fem trin, cirka fem minutter fra oprettelse til første billede.
Trin 1
Opret en konto og generér en nøgle
Opret en konto på ai.photta.app. Åbn afsnittet Developers i dashboardet, klik på Generate API key, og hent din live-nøgle. Den starter med `photta_live_` efterfulgt af 32 hex-tegn.
Trin 2
Gem nøglen i env, ikke i kildekoden
Tilføj `PHOTTA_API_KEY=...` til `.env` (eller din platforms hemmelighedslager) og indlæs den via `process.env`. Commit aldrig nøglen; importér den aldrig i en fil markeret med `'use client'` — bundleren vil trække den ind i browseren.
node --version # 18 or later ships fetch echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .envTrin 3
Skriv en lille fetch-helper
En 20-linjers wrapper omkring `fetch()` håndterer base-URL, Authorization-header, JSON-body og fejlnormalisering. Dette er den eneste abstraktion, du har brug for, indtil der udgives et officielt SDK.
// 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; }Trin 4
Indsend en try-on og poll
Lav et POST-kald til `/api/v1/tryon/jewelry` med den dokumenterede eksempel-body — koden nedenfor indeholder alle felter. API'et returnerer et generations-ID med det samme. Poll `/api/v1/tryon/jewelry/{id}` hvert 3. sekund, indtil `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"); }Trin 5
Gem resultatet
Det fuldførte payload indeholder `output_url` og `thumbnail_url`. Hent bytes én gang og gem dem i din egen object storage — URL'erne er stabile, men dit produkt bør ikke være afhængigt af Phottas CDN til rendering.
Fejl
- 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;
}Grænser
- 600 anmodninger i minuttet pr. API-nøgle (Fast vindue; grænsen er den samme på alle planer)
- En 429 indeholder Retry-After: 30 sekunder
- Op til 10 MB pr. billede
- Formater: JPEG, PNG, WebP
- Samtidige batches pr. plan: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Kun polling — API'et sender ingen webhooks.
Hvorfor en helper slår et klientbibliotek — indtil videre
- Node 18+ leveres med native fetch — ingen runtime-afhængigheder
- Den samme helper fungerer i Next.js route handlers, server actions og enhver worker
- Gem API-nøglen i env; importér aldrig helperen fra et 'use client'-modul, da bundleren ellers vil lække den
- Fungerer med enhver kø eller cron: BullMQ, Inngest, Trigger.dev, Vercel Cron, Cloudflare Queues
Hvad det ikke gør
- Ingen officiel @photta/node-pakke endnu — REST er den eneste vej i dag
- Polling er det eneste signal om fuldførelse; API'et sender ingen webhooks
- Kun Bearer-nøgle; der findes intet OAuth client-credentials-flow
Spørgsmål udviklere stiller
Findes der et officielt Photta Node.js-SDK?
Ikke endnu. Den dokumenterede vej er rå REST via Nodes native fetch — helperen på denne side udgør hele integrationsfladen, og den fungerer ens for alle capabilities.
Hvilke Node.js-versioner understøttes?
Alt, der understøtter native `fetch` — hvilket vil sige Node 18 og nyere. På Node 16 kan du enten polyfille med `node-fetch` eller opgradere. Resten af koden er ren ECMAScript 2020 (async/await, template literals, dynamiske imports), så der er ingen andre runtime-krav.
Hvordan autentificerer jeg fra Node?
Send `Authorization: Bearer photta_live_xxx` på hver anmodning. Placer nøglen i en miljøvariabel og indlæs den via `process.env`; importér den aldrig fra en fil, der kører i browseren.
Hvordan håndterer jeg generationsvinduet?
Generations-endpointet er fuldstændig asynkront. POST returnerer et generations-ID med det samme med `status: 'processing'`. Poll `GET /api/v1/tryon/jewelry/{id}` hvert 3.–5. sekund, indtil `status` skifter til `completed` eller `failed`, og sæt et loft over forsøgene, så et job, der sidder fast, ikke blokerer en anmodning.
Kan jeg kalde API'et inde i Next.js?
Ja — fra en route handler (`app/**/route.ts`), en server action (`'use server'`) eller middleware. Hold API-nøglen på serveren; importér aldrig helperen fra en `'use client'`-fil. Ved langvarige job, der overskrider Vercels funktions-timeout, udskydes polling til en kø (Inngest, Trigger.dev, BullMQ), og generations-ID'et returneres til browseren, så den kan polle dit eget status-endpoint.
Hvordan signalerer API'et fejl?
Ikke-2xx-svar indeholder en JSON-body med et `error`-objekt: `type`, `code`, `message` og et anmodnings-ID til support. Almindelige tilfælde: 400 invalid_request_error med `param`, der peger på det ugyldige felt; 402 insufficient_credits med antal for `required` og `available`; 429 rate_limit_exceeded med `retry_after` i sekunder og en matchende Retry-After-header. 5xx-fejl kan sikkert forsøges igen med eksponentiel backoff.
Relaterede sider
Python
Try-on-API til smykker i Python
Kald Phottas try-on-API til smykker i Python med requests-biblioteket. Tredive-linjers wrapper, async-venlig via httpx, fungerer i Django, FastAPI og Celery.
LæscURL
Try-on-API til smykker med cURL
Kald Phottas try-on-API til smykker direkte fra kommandolinjen med cURL. Indsend, poll, download — hvert kodestykke fungerer sammen med jq til scriptede pipelines.
LæsFunktioner
Try-on-API til smykker til halskæder, ringe, armbånd og øreringe
Placér halskæder, ringe, armbånd og øreringe på AI-modeller via REST. 5 credits ved 2K, indbyggede close-up-mannequiner, refleksionsbevidst rendering fra Photta-dokumentationen.
LæsByg
Byg en AI-produktfotograferingstjeneste
En playbook til stiftere om videresalg af Phottas virtuelle try-on-API som en white-label-SaaS: tenant-nøgler, batch-fanout, fakturering pr. credit, SLA-realiteter.
LæsHurtig start
Første Photta-billede på under fem minutter.
Opret en konto, generer en API-nøgle, kør dit første cURL-kald, foretag polling indtil det er fuldført, gem resultatet. Fem trin, dokumenteret fra start til slut.
LæsReference
Photta API-priser
Hvad hvert Photta API-endpoint koster i credits ved 2K og 4K, hvordan debitering og refundering fungerer, og hvilke endpoints der er gratis. Ingen faste pengepriser pr. billede.
Læs
Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket
Prøv API'et på fem minutter
Generér en Photta API-nøgle, indsæt cURL-kodestykket ovenfor, og du har dit første billede på en model, før kaffen er færdigbrygget.
- 1.5–4 min
- 5 credits ved 2K · 6 credits ved 4K
- async, polling
- 600 requests/min
- Bearer key