Skip to main content

Video Compliance Check — Full Guide

ZebraTruth runs compliance analysis on video ads through a server-side async pipeline. Your client uploads the video to managed blob storage, submits a job, then either polls or receives a webhook when the report is ready.

Primary endpoint

POST https://api.zebratruth.ai/v1/compliance/check-video
No client-side ffmpeg. ZebraTruth handles video probing, audio transcription, frame extraction, OCR, visual signals, and Stage A→C compliance analysis server-side.

Supported inputs

The 3-step flow

  1. POST /v1/compliance/media/upload-url — get a 15-min signed Azure Blob upload URL
  2. PUT <uploadUrl> — upload your video bytes directly to managed storage
  3. POST /v1/compliance/check-video — submit the uploaded video for analysis (returns 202)
  4. Poll GET /v1/compliance/check-video/{requestId} OR receive an HMAC-signed webhook

Step 1 — Request an upload URL

Response
The uploadUrl is valid for 15 minutes. Save requestId + blobPath — you’ll pass blobPath back in step 3 + use requestId to poll.

Step 2 — Upload the video

PUT your video bytes directly to uploadUrl. Use exactly the headers from uploadInstructions.headersx-ms-tags is required by Azure for the integrity check.
Azure returns 201 Created on success. Bytes go directly to ZebraTruth-managed blob storage — they don’t pass through ZebraTruth servers.

Step 3 — Submit for analysis

Response (HTTP 202)
The endpoint validates the upload (existence + content-length under 200 MB + duration in [3, 180] sec), reserves credits, and enqueues the job.

Request body fields

Possible error responses

Step 4 — Poll for results

Response (in-flight)
Response (terminal)

Status state machine

Poll every 2 seconds. Typical completion: 20-60 seconds for a 30-second video. Hard ceiling: 3 minutes.

Terminal report statuses

Instead of polling, configure a webhook URL once at the account level and submit videos with webhookUrl set.

Get / create your tenant webhook secret

Response
Save the secret securely — ZebraTruth only returns it once on creation.

Verify webhook signatures

Each delivery is HMAC-SHA256-signed. Signature is stable across retries (computed once at enqueue + cached on the row). Headers:
  • x-zt-timestamp: <unix-seconds>
  • x-zt-signature: <hex-signature>
Canonical signing format:
Node.js example:

Retry semantics

After 5 failures, the delivery is marked failed and dropped. Webhook failures do NOT mutate the compliance job row — the job stays completed_committed. The webhook delivery has its own retry state in videoWebhookDeliveries.

Rotate the secret

In-flight deliveries keep their original signature (sig is computed at enqueue). New jobs use the rotated secret immediately.

Idempotency

Same (requestId, blobPath, jurisdictions, platforms, mode) → 202 with idempotent: true, no extra charge. Same requestId with different blobPath / jurisdictions / platforms / mode → 409 idempotency_conflict:
Precedence: blobPath > feature > inputHash (deterministic order for stable error messages).

Cost

Per-second pricing. A 60-second video costs ~600 credits. Credits are reserved at submit + committed on reportStatus: complete. insufficient_evidence and analysis_failed release the reservation (no charge). See Cost & Credits for tier multipliers + billing lifecycle.

Common errors

Next

Cost & credits

Per-second pricing math, tier multipliers, credit lifecycle.

Async + Webhooks

HMAC verification deep dive, retry semantics.

Interpreting reports

How to read scores + decisions + agent breakdowns.

LLM Skill

Install the skill so your LLM agent runs video checks autonomously.