Node.js · Korujen try-on-API

Korujen try-on-API Node.js:ssä

Yhdellä lauseella

Aseta PHOTTA_API_KEY ympäristömuuttujiin, kirjoita pieni fetch-apufunktio osoitteelle https://api.photta.app/api/v1 Bearer-avaimella, tee POST osoitteeseen /api/v1/tryon/jewelry, ja pollaa sitten osoitetta /api/v1/tryon/jewelry/{id} 3 sekunnin välein, kunnes tila on completed.

  • Tyypillinen kesto: 1.5–4 min
  • Credits: 5 credits resoluutiolla 2K · 6 credits resoluutiolla 4K
  • Käsittely: asynkroninen, polling
  • Rajoitukset: 600 pyyntöä/min
  • Autentikointi: Bearer-avain

Jokainen luku tällä sivulla on peräisin Photta-rajapinnan dokumentaatiosta · tarkistettu

POST/api/v1/tryon/jewelry
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");
}

Lyhyesti

Lyhyesti

Endpoint
POST /api/v1/tryon/jewelry
Autentikointi
Bearer-API-avain
Käsittely
Asynkroninen — tee polling-kyselyitä status-endpointiin
Tyypillinen kesto
1.5–4 min
Credits
5 credits resoluutiolla 2K · 6 credits resoluutiolla 4K
Kuvasuhteet
3:4 · 1:1 · 4:3 · 9:16 · 16:9
Syöterajoitukset
Enintään 10 MB per kuva; JPEG, PNG, WebP
Idempotentti
Ei

Miten se toimii

Viisi vaihetta, noin viisi minuuttia rekisteröitymisestä ensimmäiseen kuvaan.

  1. Vaihe 1

    Rekisteröidy ja luo avain

    Luo tili osoitteessa ai.photta.app. Avaa hallintapaneelin Developers-osio, napsauta Generate API key ja kopioi live-avain. Se alkaa merkkijonolla `photta_live_`, jota seuraa 32 heksadesimaalimerkkiä.

  2. Vaihe 2

    Tallenna avain ympäristömuuttujiin, älä lähdekoodiin

    Lisää `PHOTTA_API_KEY=...` tiedostoon `.env` (tai alustasi salaisuuksien hallintaan) ja lataa se muuttujan `process.env` kautta. Älä koskaan commitoi avainta; älä koskaan tuo sitä tiedostoon, jossa on merkintä `'use client'` — paketointityökalu vie sen selaimeen.

    node --version   # 18 or later ships fetch
    echo "PHOTTA_API_KEY=photta_live_xxxxx" >> .env
  3. Vaihe 3

    Kirjoita pieni fetch-apufunktio

    Yksi 20 rivin kääre `fetch()`-funktion ympärille hoitaa perus-URL:n, Authorization-otsakkeen, JSON-rungon ja virheiden normalisoinnin. Tämä on ainoa tarvitsemasi abstraktio, kunnes virallinen SDK julkaistaan.

    // 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;
    }
  4. Vaihe 4

    Lähetä try-on ja tee pollingia

    Tee POST-pyyntö kohteeseen `/api/v1/tryon/jewelry` dokumentoidulla esimerkki-payloadilla — alla oleva koodi sisältää jokaisen kentän. API palauttaa generointitunnisteen välittömästi. Pollaa `/api/v1/tryon/jewelry/{id}` 3 sekunnin välein, kunnes `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");
    }
  5. Vaihe 5

    Tallenna tulos pysyvästi

    Valmis payload sisältää kentät `output_url` ja `thumbnail_url`. Nouda tavut kerran ja tallenna ne omaan objektitallennustilaasi — URL-osoitteet ovat pysyviä, mutta tuotteesi ei pitäisi riippua Phottan CDN:stä renderöintiä varten.

Virheet

400invalid_request_error
The request is malformed or contains invalid parameters.
401authentication_error
The API key is missing, invalid, or expired.
402insufficient_credits_error
Your account does not have enough credits.
404not_found_error
The requested resource does not exist.
409conflict_error
The request conflicts with current state — e.g. your concurrent-batch cap is reached.
429rate_limit_error
Too many requests. Slow down and retry.Retry-After: 30
500api_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;
}

Rajoitukset

  • 600 pyyntöä minuutissa per API-avain (Kiinteä aikaikkuna; rajoitus on sama kaikissa tilauksissa)
  • Vastaus 429 sisältää otsakkeen Retry-After: 30 sekuntia
  • Enintään 10 MB per kuva
  • Formaatit: JPEG, PNG, WebP
  • Rinnakkaiset eräajot per tilaus: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
  • Vain polling — API ei lähetä webhookeja.

Miksi apufunktio voittaa asiakaskirjaston — toistaiseksi

  • Node 18+ sisältää natiivin fetchin — ei ajonaikaisia riippuvuuksia
  • Sama apufunktio toimii Next.js-reittikäsittelijöissä, server actioneissa ja missä tahansa workerissa
  • Pidä API-avain ympäristömuuttujissa; älä koskaan tuo apufunktiota 'use client' -moduuliin, jotta paketointityökalu ei vuoda sitä
  • Toimii minkä tahansa jonon tai cronin kanssa: BullMQ, Inngest, Trigger.dev, Vercel Cron, Cloudflare Queues

Mitä se ei tee

  • Ei vielä virallista @photta/node-pakettia — REST on ainoa tapa tällä hetkellä
  • Polling on ainoa valmistumissignaali; API ei lähetä webhookeja
  • Vain Bearer-avain; OAuth client-credentials -kulkua ei ole

Kehittäjien usein kysymää

Onko olemassa virallista Photta Node.js SDK:ta?

Ei vielä. Dokumentoitu tapa on suora REST Noden natiivin fetchin kautta — tällä sivulla oleva apufunktio on koko integraatiopinta, ja se toimii samalla tavalla jokaiselle kyvykkyydelle.

Mitä Node.js-versioita tuetaan?

Kaikkia, jotka tukevat natiivia `fetch`-funktiota — eli Node 18 ja uudemmat. Node 16 -versiossa joko käytät polyfilliä `node-fetch`-paketilla tai päivität uudempaan. Muu koodi on pelkkää ECMAScript 2020:tä (async/await, mallimerkkijonot, dynaamiset tuonnit), joten muita ajonaikaisia vaatimuksia ei ole.

Miten autentikoidun Nodesta?

Lähetä `Authorization: Bearer photta_live_xxx` jokaisessa pyynnössä. Aseta avain ympäristömuuttujaan ja lue se `process.env`-kautta; älä koskaan tuo sitä tiedostosta, jota ajetaan selaimessa.

Miten käsittelen generointi-ikkunan?

Generointi-endpoint on täysin asynkroninen. POST palauttaa generointitunnisteen välittömästi tilalla `status: 'processing'`. Pollaa `GET /api/v1/tryon/jewelry/{id}` 3–5 sekunnin välein, kunnes `status` muuttuu arvoon `completed` tai `failed`, ja aseta yrityksille yläraja, jotta jumiutunut työ ei jätä pyyntöä roikkumaan.

Voinko kutsua APIa Next.js:n sisällä?

Kyllä — reittikäsittelijästä (`app/**/route.ts`), server actionista (`'use server'`) tai middlewaresta. Pidä API-avain palvelimella; älä koskaan tuo apufunktiota `'use client'` -tiedostosta. Jos kyseessä on pitkäkestoinen työ, joka ylittää Vercelin funktion aikakatkaisun, siirrä polling jonoon (Inngest, Trigger.dev, BullMQ) ja palauta generointitunniste selaimelle, jotta se voi pollata omaa status-endpointiasi.

Miten API ilmoittaa virheistä?

Muut kuin 2xx-vastaukset sisältävät JSON-rungon, jossa on `error`-objekti: `type`, `code`, `message` sekä pyyntötunniste tukea varten. Yleisiä tapauksia: 400 invalid_request_error, jossa `param` osoittaa virheelliseen kenttään; 402 insufficient_credits, jossa on `required`- ja `available`-määrät; 429 rate_limit_exceeded, jossa on `retry_after` sekunteina ja vastaava Retry-After-otsake. 5xx-virheitä voi turvallisesti yrittää uudelleen eksponentiaalisella peruutuksella.

Liittyvät sivut

Jokainen luku tällä sivulla on peräisin Photta-rajapinnan dokumentaatiosta · tarkistettu

Kokeile APIa viidessä minuutissa

Luo Photta-API-avain, liitä yllä oleva cURL-koodinpätkä, ja sinulla on ensimmäinen mallikuva ennen kuin kahvi ehtii tippua.

  • 1.5–4 min
  • 5 credits resoluutiolla 2K · 6 credits resoluutiolla 4K
  • asynkroninen, polling
  • 600 pyyntöä/min
  • Bearer-avain