Skip to content

İşler ve webhook'lar

Medya üretimi eşzamansızdır: oluşturunca job ID alın, polling ile sorgulayın veya callback_url ile bildirim alın. Webhook imzası kaynağı doğrular.

  • Durum queued ve processing üzerinden completed ya da failed olur.
  • Polling basittir; webhook yüksek hacim için iyidir ve herkese açık HTTPS alıcısı gerektirir.
  • Tekrarlı teslimatı kabul edin, imzayı doğrulayın ve job ID ile idempotent işlem yapın.

Eksiksiz örnekler

Özgün kılavuzdaki çalıştırılabilir örneklerin tamamı aşağıda korunmuştur. Yalnızca kullandığınız araç ve işletim sistemiyle ilgili blokları çalıştırın.

POST /media/generate  →  status: processing  ──►  done   (result_url ready)
        │                                     └─►  failed (error, funds refunded)
        └── (optional) callback_url → push webhook on done/failed
json
{ "id": "beefb531-…", "model": "image/nano-banana-2", "status": "processing",
  "poll": "https://nordrouter.com/media/job/beefb531-…" }
json
{ "id": "beefb531-…", "status": "done",
  "result_url": "https://nordrouter.com/media/file/beefb531-…",
  "cost_usd": 0.052, "error": null }
bash
curl https://nordrouter.com/media/job/beefb531-…
bash
curl https://nordrouter.com/media/generate \
  -H "Authorization: Bearer sk-nr-YOUR-KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "image/nano-banana-2",
    "input": { "prompt": "…" },
    "callback_url": "https://your-server.com/webhooks/nordrouter",
    "callback_secret": "any-string-of-yours"
  }'
json
{ "event": "media.completed", "id": "beefb531-…", "status": "done",
  "result_url": "https://nordrouter.com/media/file/beefb531-…",
  "cost_usd": 0.052, "error": null }
python
import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)  # constant-time compare
javascript
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}
javascript
import express from "express";
import crypto from "node:crypto";

const SECRET = "any-string-of-yours";          // = your callback_secret
const app = express();

app.post("/webhooks/nordrouter",
  express.raw({ type: "application/json" }),    // raw body — required for the signature
  (req, res) => {
    const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
    const got = req.headers["x-nr-signature"] || "";
    if (expected.length !== got.length || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(got)))
      return res.sendStatus(401);              // signature mismatch — not from us
    const job = JSON.parse(req.body);
    if (job.event === "media.completed") console.log("done:", job.result_url, "$" + job.cost_usd);
    res.sendStatus(200);                        // reply 2xx or we retry
  });

app.listen(3000);
python
import hmac, hashlib
from fastapi import FastAPI, Request, Response

SECRET = b"any-string-of-yours"                # = your callback_secret
app = FastAPI()

@app.post("/webhooks/nordrouter")
async def hook(request: Request):
    raw = await request.body()                 # raw bytes — required for the signature
    expected = "sha256=" + hmac.new(SECRET, raw, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-NR-Signature", "")):
        return Response(status_code=401)       # signature mismatch — not from us
    job = await request.json()
    if job["event"] == "media.completed":
        print("done:", job["result_url"], "$", job["cost_usd"])
    return Response(status_code=200)           # reply 2xx or we retry

Resmi belgeler ve bağlantılar

PollingWebhook
Public https addressnot neededrequired
Latencyup to poll intervalnear-instant
Guaranteeyou control itbest-effort + polling backup
Best forscripts, CI, laptopservers, production backends

Önce en küçük metin isteğiyle bağlantıyı doğrulayın; ardından akış, araç çağrıları, görseller ve diğer gelişmiş özellikleri ekleyin. API anahtarını herkese açık koda veya tarayıcı ön yüzüne koymayın.

Sorun giderme