İçeriğe geç

RehberlerTeknik

Vellria API'sini kendi kodundan çağırmak

Dört çağrı seni sıfırdan biten dosyaya götürüyor: anahtar oluştur, üretimi başlat, kaydı yokla ve çıktıyı indir. Bu, o döngünün baştan sona hâli; her adımın döndürdüğü hata ve bir istemcinin o hata karşısında ne yapması gerektiğiyle birlikte.

Rehber kapak görseli: Vellria API'sini kendi kodundan çağırmak

Anahtar oluştur, Bearer token olarak gönder

Anahtarlar konsolda, API anahtarları sayfasında üretiliyor ve tam anahtarın göründüğü tek yer o yanıt: anahtar listeni sonraki her okuyuşun bir kimlik, bir ad ve bir önek döndürüyor, sırrı bir daha değil. Hemen sakla. Önek, bir log satırının anahtarı içermeden onu adlandırabilmesi için var.

Her istekte Authorization başlığında, Bearer kelimesinin ardından anahtar olarak gönder. Sorgu dizesi biçimi yok. RFC 6750 şunu öneriyor: "Bearer tokens SHOULD NOT be passed in page URLs (for example, as query string parameters)". Sebebi açık: token taşıyan adresler tarayıcı geçmişine, referrer'a ve sunucu log'larına düşüyor.

Eksik ya da iptal edilmiş anahtar authentication_required koduyla 401 dönüyor. Her hata tek bir gövdeyi paylaşıyor: message, type, param ve code taşıyan bir error nesnesi. Dallanmayı code üzerinden yap; message bir insan için yazılmış ve sözcükleri değişecek.

Kataloğu gömmek yerine oku

GET /v1/models iki liste döndürüyor: image ve video. Bir görsel kaydı kendi geçerli boyutlarını her birinin kredi bedeliyle ve bir varsayılan boyutla taşıyor; bir video kaydı saniye başına bedelle çözünürlükleri, bir süre alt ve üst sınırını ve kabul ettiği oranları taşıyor. Boyut listesi kataloğa değil tek bir modele ait, varsayılan da öyle; yani hiçbir tek değeri her yere uygulamak güvenli değil. Model kataloğu ve fiyat sayfaları da aynı ucu okuyor. Her model sayfası ayrıca göndereceğin kimliği gösteriyor; video için örneğin Seedance 2.5, görsel için Qwen 3; NSFW görsel API ve NSFW video API sayfaları da istek biçimlerini özetliyor.

kind alanı modelin görsel mi video mu ürettiğini söylüyor; her kayıt ardından bir metin kipi ve bir referans kipi listeliyor. İki durumda da aynı model kimliğini gönderirsin: referans görsel eklersen referans kipinin boyutları ve fiyatları geçerli olur. Bilinmeyen model, geçersiz boyut ya da aralık dışı süre, alanı adlandıran bir param ile 400 dönüyor; aralık dışı süre sığdırmak için kırpılmıyor, reddediliyor.

Üretimi başlat, sonra kaydı yokla

Bir model kimliği, bir prompt ve o modelin kabul ettiği seçeneklerle /v1/generate/image ya da /v1/generate/video ucuna POST at. Geriye bir kimlik, processing durumu ve az önce alınan kredi bedeliyle 202 alıyorsun: krediler üretimin sonunda değil başında düşüyor. Sonra durum queued ve processing'ten çıkana kadar GET /v1/generations/{id} yokla. Tamamlanmış kayıt bizim dosya ucumuzu gösteren output_url taşıyor; düşen kayıt ise kapalı bir kümeden gelen bir error_code ile birlikte, log'ların için kısa bir özet olan error taşıyor.

Yoklamalar arasına gecikme, gecikmenin içine rastgelelik koy. Marc Brooker'ın AWS Architecture Blog'daki geri çekilme deneyi tek bir satır için yarışan istemcileri benzetiyor ve jitter eklendiğinde şunu bildiriyor: "in the case with 100 contending clients, we've reduced our call count by more than half". Yoklama, sonucu nasıl öğrendiğin; nasıl olduğu değil: üretimler kimse bakmasa da sunucu tarafında uzlaştırılıyor, yani kopan bir bağlantı sana sonucu değil sonucun üstündeki tutamağını kaybettiriyor.

Döngünün tamamı tek dosyada

Bunu bir .mjs dosyası olarak kaydet, VELLRIA_API_KEY'i ayarla ve güncel bir Node'da çalıştır. Hiçbir model kimliği, boyut ya da bedel gömülü değil.

```js import { writeFile } from "node:fs/promises"; const BASE = "https://vellria.com"; const AUTH = { Authorization: `Bearer ${process.env.VELLRIA_API_KEY}` }; const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); async function call(path, init) { const res = await fetch(BASE + path, { ...init, headers: { ...AUTH, ...init?.headers } }); if (res.status === 429) { await sleep(Number(res.headers.get("retry-after") ?? 5) * 1000); return call(path, init); } if (!res.ok) throw new Error((await res.json().catch(() => null))?.error?.code ?? res.status); return res.json(); } const catalog = await call("/v1/models"); const model = catalog.image[0]; let rec = await call("/v1/generate/image", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: model.id, prompt: "a lighthouse in fog", size: model.text.default_size }), }); while (rec.status === "queued" || rec.status === "processing") { await sleep(2000 + Math.random() * 2000); rec = await call(`/v1/generations/${rec.id}`); } if (rec.status !== "completed") throw new Error(rec.error_code ?? "generation_failed"); const file = await fetch(rec.output_url, { headers: AUTH }); const ext = file.headers.get("content-type") === "image/png" ? "png" : "jpg"; await writeFile(`${rec.id}.${ext}`, Buffer.from(await file.arrayBuffer())); ```

Görsel alan bir model için önce dosyayı, baytlarla eşleşen bir Content-Type başlığıyla /v1/uploads ucuna POST at, sonra dönen adresi image_urls içinde geçir; görselden videoya kabul edilen biçimleri ve ret listesini taşıyor. Bir modelin görsel isteyip istemediği modelin özelliği ve yanlış şekildeki bir gövde sessizce düzeltilmiyor, reddediliyor; bunu karakteri tutarlı tutmak anlatıyor. Video gövdeleri size yerine duration ve resolution taşıyor; onu da çözünürlük ve süre seçimi anlatıyor. Her video model kimliği türü ve saniye başı fiyatıyla NSFW video API'si sayfasında tek tabloda duruyor.

Hatalar, geri basınç ve süre dolumu

Bir üretim başladıktan sonra düştüğünde, başta alınan krediler kayıt failed olarak işaretlendiği anda kendiliğinden geri dönüyor. failed'i terminal ve kapanmış say: sebep için error_code üzerinden dallan ve bakiyeleri kendi tarafından asla uzlaştırma. İade, yalnız tek bir yazarın sağlayabileceği bir koşul altında yazılıyor, yani yeniden teslim edilen bir sağlayıcı bildirimi sana iki kez kredi yazamıyor ya da bir kez atlayamıyor.

Hız sınırını aşmak rate_limit_exceeded kodu ve bir Retry-After başlığıyla 429 döndürüyor. RFC 6585 o durumu tanımlıyor: "the 429 status code indicates that the user has sent too many requests in a given amount of time". RFC 9110 bölüm 10.2.3 de başlığı şöyle tanımlıyor: "indicates how long the user agent ought to wait before making a follow-up request". Tahmin etmek yerine onu oku; bir parti ateşlerken bunun ne demek olduğu için storyboard ve previz rehberine bak. Bakiye yetmezse 402 ve hiç kayıt oluşmuyor. Tam ayrıntı API referansında.

SSS ( 3 )

Sık sorulan sorular

Bir üretimin bitmesi için yoklamaya devam etmek zorunda mıyım?

Hayır. Yoklama, sonucu nasıl öğrendiğin; nasıl olduğu değil. Üretimler bir istemci bağlı olsa da olmasa da bizim tarafımızda uzlaştırılıyor, yani sonra ölen bir sürecin başlattığı iş yine completed ya da failed'e ulaşıyor; kimliğiyle sonra al.

Bunu tarayıcı kodundan çağırabilir miyim?

Anahtarınla değil. Bir anahtar kredi harcıyor ve kapsamı daraltılamıyor, yani tarayıcıya gönderilen her şey yayımlanmış bir anahtar. Çağrıları kendi sunucunun arkasına koy, anahtarı onun ortamında tut ve ön yüzün onunla konuşsun.

Model kimliklerini, boyutları ve bedelleri koduma gömebilir miyim?

Gömebilirsin ve kayar. Model sayfalarının çizdiği ve sunucunun ücretlendirdiği şey katalog ucu, yani kopyalanmış bir değer kataloğun değiştiği gün eşleşmeyi bırakıyor. Onu açılışta çek ve sürecin ömrü boyunca önbellekte tut.

İlgili rehberler

Tüm rehberler