Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vmeg.ai/llms.txt

Use this file to discover all available pages before exploring further.

Why verify

Your webhook URL is public. Without checks, a forged completion POST could be mistaken for a real task result. Verify every callback before you parse the JSON.

Signing scheme

VMEG signs each webhook POST with HMAC-SHA256:
  1. You configure a Webhook URL on API Configuration. VMEG generates a Webhook Secret on that page — copy it to your server; you never send it in the callback.
  2. When a task completes, VMEG POSTs the JSON body to your URL and attaches:
    • X-Timestamp — send time in Unix milliseconds (string)
    • X-Signature — hex (base16) string of HMAC-SHA256(secret, X-Timestamp + rawBody)
  3. Your endpoint recomputes the same HMAC with your copy of the secret. If it matches X-Signature, the sender is VMEG and the body was not tampered with. Reject callbacks whose timestamp is more than 300 seconds from your server clock (replay protection).

How to verify

  1. Read X-Timestamp and X-Signature from the request headers.
  2. Reject if X-Timestamp is outside the 300-second window.
  3. Hash the raw request body bytes — do not re-serialize JSON, pretty-print, sort keys, or change whitespace.
  4. Compare your computed hex to X-Signature (exact match; do not transform case).
Return 401 or 403 on failure. Still respond promptly.

Examples

import crypto from "node:crypto";

function verify(secret, timestamp, rawBody, signature) {
  if (Math.abs(Number(timestamp) - Date.now()) > 300_000) return false;
  const message = Buffer.concat([Buffer.from(timestamp), rawBody]);
  const expected = crypto.createHmac("sha256", secret).update(message).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

After verification

  1. Parse JSON and route on event (openapi-tts, openapi-translate, openapi-clone-voice, or openapi-media-translation) — see Webhook request body.
  2. Process data using the Callbacks schema on the matching create-async endpoint in API reference.
  3. Return 2xx immediately; queue long-running work.
See Webhooks for URL configuration and receiver requirements.