View as /docs.md
Platform

Webhooks

Subscribe an HTTPS endpoint to AIgateway events: async job completion, batch status, usage alerts, spend thresholds, key rotation reminders. Every payload is signed with HMAC-SHA256 so you can verify it came from us.

Create a webhook

Dashboard → WebhooksAdd endpoint. Pick the events you care about and we generate a signing secret (shown once — store it in your secrets manager).

Event catalog

EventWhen it fires
job.completedAsync inference job finishes successfully.
job.failedAsync job errors out after retries exhausted.
batch.completedBatch API job reaches terminal state.
usage.thresholdMonthly spend crosses a threshold you set.
balance.lowPrepaid balance falls below your auto-reload trigger.
key.rotatedA scoped key is rotated or revoked.

Payload shape

{
  "id": "evt_01HQE7YRG3K...",
  "type": "job.completed",
  "created": 1712345678,
  "data": {
    "job_id": "job_01HQE...",
    "model": "openai/sora-2",
    "result_url": "https://media.aigateway.sh/...",
    "usage": { "cost_cents": 412 }
  }
}

Verifying the signature

Every delivery includes aig-signature and aig-timestamp headers. Reconstruct the signed payload as timestamp + "." + raw_body and compare an HMAC-SHA256 of that using your signing secret against the signature header. Reject anything older than 5 minutes to block replays.

import crypto from "node:crypto";

function verify(req, secret) {
  const ts = req.headers["aig-timestamp"];
  const sig = req.headers["aig-signature"];
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${req.rawBody}`)
    .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) throw new Error("bad sig");
  if (Math.abs(Date.now() / 1000 - ts) > 300) throw new Error("stale");
}

Delivery + retries

We send a POST and expect a 2xx within 10 seconds. On failure we retry with exponential backoff for 24 hours (~8 attempts). Every delivery is logged in your dashboard with full request + response so you can replay any event manually.

Idempotency

evt.id is stable across retries. Store it and de-dupe on your side — we may deliver the same event more than once during network partitions.