Browse the docs

Webhooks & automation

Add a webhook_url to any job and we POST the result to you the moment it's ready — no polling, no held connections. This is the backbone for n8n, Zapier, and custom pipelines.

The payload

When a job finishes (success or failure), we send a single POST to your webhook_url:

POST your-webhook-url
{
  "job_id": "385df601-fafb-4549-b8a8-…",
  "status": "completed",
  "output_url": "https://…/your-video.mp4"
}
  • status is completed, failed, or failed_oom (the settings were too demanding) — treat any status other than completed as failure. output_url is present on success and points to the finished MP4.
  • On failure there is no output_url — and remember, failed jobs cost $0.
  • Stories use the same payload, with job_id carrying the story id and one delivery for the stitched video.

Delivery headers

HeaderMeaning
X-GetMeCompute-EventThe job status this delivery reports (completed / failed / failed_oom).
X-GetMeCompute-DeliveryStable id for this event (job_id:status). If your endpoint sees the same value twice, it's a redelivery — safe to ignore the duplicate.
X-GetMeCompute-TimestampUnix timestamp of the delivery attempt.
User-AgentGetMeCompute-Webhook/1

Retries

Respond with any 2xx quickly — do heavy work after acknowledging. If your endpoint returns a server error or times out, we retry the delivery; permanent client errors (e.g. 404) are not retried. Because retries can deliver the same event twice, use X-GetMeCompute-Delivery to dedupe.

Webhooks fire for every job that has a webhook_url — including jobs submitted from the dashboard form. And with a sandbox test key (gmc_test_…) the whole flow — submit, auto-complete, webhook delivery — runs in test mode, so you can build and verify your automation before switching to real renders.

Account-level webhook endpoints

The per-job webhook_url covers one job. To get every job event for your account — designed for automation platforms like Zapier and n8n — subscribe an endpoint at Dashboard → Webhooks or via the /api/v1/webhook-endpoints API. Each endpoint chooses its events (job.completed, job.failed) and gets its own signing secret (gmcwh_…, shown once at creation). You can have up to 10 active endpoints per account.

Endpoint deliveries are wrapped in a versioned envelope:

POST your-endpoint-url
{
  "event": "job.completed",
  "api_version": "v1",
  "delivery_id": "385df601-…:completed:9f2c41ab-…",
  "created_at": "2026-08-10T00:31:07Z",
  "data": {
    "job_id": "385df601-fafb-4549-b8a8-…",
    "status": "completed",
    "output_url": "https://…/your-video.mp4"
  }
}

The event name is normalized: a failed_oom job arrives as job.failed, with data.status carrying the raw job status. And unlike per-job payloads (which omit output_url on failure), the envelope's data always includes the output_url key — null when the job failed.

Delivery headers and retry behavior match per-job webhooks (dedupe on X-GetMeCompute-Delivery, which equals delivery_id). One extra rule: an endpoint whose server permanently rejects 20 deliveries in a row is disabled automatically — delete and re-add it to re-enable with a fresh secret.

One known limitation: story (multi-scene) completion events are currently delivered only to the webhook_url set on the story itself — they don't reach account-level endpoints yet.

Verifying signatures

Every endpoint delivery carries X-GetMeCompute-Signature: sha256=<hex> — an HMAC-SHA256 of "<timestamp>.<raw body>" using your endpoint's secret. Verify before trusting the payload, and compare with a constant-time function:

Node.js
import { createHmac, timingSafeEqual } from "crypto";

function verify(secret, headers, rawBody) {
  const ts = headers["x-getmecompute-timestamp"];
  const expected = "sha256=" +
    createHmac("sha256", secret).update(ts + "." ).update(rawBody).digest("hex");
  const got = headers["x-getmecompute-signature"] || "";
  return got.length === expected.length &&
    timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}
Python
import hashlib, hmac

def verify(secret: str, headers: dict, raw_body: bytes) -> bool:
    ts = headers["X-GetMeCompute-Timestamp"]
    expected = "sha256=" + hmac.new(
        secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(headers.get("X-GetMeCompute-Signature", ""), expected)

Reject deliveries whose timestamp is more than a few minutes old to guard against replays.

Recipe: n8n

  1. Add a Webhook trigger node and copy its production URL.
  2. Paste that URL into the Webhook URL field when submitting your GetMeCompute job.
  3. In the workflow, branch on {{ $json.body.status }} completed vs failed.
  4. On success, use an HTTP Request node to download output_url, then continue — upload to your CMS, post to social, notify Slack, or kick off the next job.

Recipe: Zapier

  1. Create a Zap with Webhooks by Zapier → Catch Hook and copy the custom webhook URL.
  2. Use it as the Webhook URL on your GetMeCompute job.
  3. Add a Filter step for status = completed, then any action you like — save the video to Drive/Dropbox from output_url, add a row to a sheet, send an email.

Recipe: your own backend

Expose an HTTPS endpoint, store the payload, and return 200 immediately. Download the video from output_url in a background task. Track job_id against the id returned when you submitted the job to correlate results.