Skip to main content

Video Compliance — Concept

ZebraTruth runs compliance checks on video ads through a server-side async pipeline. Your client uploads the video, submits a job, and either polls or receives a webhook when the report is ready. No client-side ffmpeg, no preprocessing, no transcript provisioning — ZebraTruth handles everything.

Primary endpoint

POST https://api.zebratruth.ai/v1/compliance/check-videoRead the full guide with curl, Node, and Python examples →

Endpoint family

EndpointMethodPurpose
/v1/compliance/media/upload-urlPOSTGet a signed Azure Blob upload URL (15-min TTL)
/v1/compliance/check-videoPOSTSubmit for analysis (returns 202 with jobId + estimatedCredits)
/v1/compliance/check-video/{requestId}GETPoll for status + inlined report
/v1/compliance/webhooks/video/secretGETGet/create your tenant’s webhook signing secret
/v1/compliance/webhooks/video/secret/rotatePOSTRotate the secret (in-flight deliveries keep old signature)

The 3-step flow

1. Get upload URL    ──→  2. PUT video bytes  ──→  3. POST check-video  ──→  4. Poll or webhook
   (1 round-trip)        (direct to blob)        (returns 202 + jobId)     (status: completed)
See Quickstart or the full guide for working curl commands at each step.

Evidence IDs — how findings cite the source

Every check in the report carries an evidenceIds[] array referencing stable IDs from the evidence timeline:
ID formatWhat it cites
audio_NNNA transcript segment from the audio track (sentence-level)
frame_NNNA sampled video frame (with timestamp)
ocr_NNNA specific OCR detection within a frame
signal_NNNA controlled-vocab signal (brand, watermark, restricted category, regulatory disclosure)
Plus every check carries a timelineLocation:
{
  "startMs": 4500,
  "endMs": 7200,
  "track": "audio"
}
So findings always pin to a specific moment in the source video, enabling timestamped UI annotations in your video editor.

VideoComplianceCheck schema

interface VideoComplianceCheck {
  agentId: "ai-laws" | "advertising-law" | "platform-policy" | "metadata-labeling" | "rights-clearance" | "rights-clearance-image"
  checkName: string
  status: "pass" | "flag" | "block" | "escalate"
  severity: "info" | "low" | "medium" | "high" | "critical"
  message: string
  recommendation?: string
  citation?: string
  primaryCategory?: string
  categories?: string[]
  // Video-mode required fields:
  evidenceIds: string[]
  timelineLocation: {
    startMs: number
    endMs: number
    track: "audio" | "video" | "mixed"
  }
}
Checks that fail to populate evidenceIds or timelineLocation are dropped + emitted as analysisDiagnostics — never leaked as fake compliance findings. Enforced at the Stage C boundary.

Report envelope

interface VideoReport {
  schemaVersion: "video-report.v1"
  preprocessorVersion: "video-preprocessor.v1"
  evidenceVersion: "evidence-timeline.v1"
  tenantId: string
  requestId: string
  generatedAt: string
  status: "complete" | "insufficient_evidence" | "analysis_failed"
  reason?: string
  checks: VideoComplianceCheck[]
  analysisDiagnostics?: AnalysisDiagnostic[]
  preprocessing: {
    transcriptionStatus: string
    frameAnalysisStatus: string
    degraded: boolean
    evidenceTruncated: boolean
  }
}
The 3 terminal report statuses:
statusMeaningBilling
completeStage A→C ran, real findings producedCommitted (charged)
insufficient_evidencePipeline ran but no meaningful content to analyze (silent video, no OCR, no signals)Released (no charge)
analysis_failedEngine error — failure recorded for auditReleased (no charge)

Limits

Duration3 to 180 seconds
File size200 MB
Content typesvideo/mp4, video/webm, video/quicktime
Frame sample cap20 frames per video (scene-change-aware + claim-aware)
Modefast (V1 only — full pipeline)

What it detects

ZebraTruth’s video compliance checks span 5 specialized agents:
AgentDetects
AI LawsJurisdiction applicability (FTC, EU UCPD, UK ASA, India ASCI, China Ad Law) + AI disclosure rules
Advertising LawUnsubstantiated claims, missing disclaimers, comparative ad rules, endorsement / influencer marketing rules
Platform PolicyTikTok, YouTube, Instagram, Meta, LinkedIn AI-disclosure + monetization rules
Metadata & LabelingRequired visible labels, watermarks, C2PA metadata
Rights ClearanceBrand logos, restricted-category content safety (alcohol/tobacco/firearm/gambling/pharmaceutical), watermarks, regulatory disclosure presence
Plus deterministic checks emitted by the per-frame analysis (brand-detected, watermark-detected, restricted-label, safesearch-flag, regulatory-disclosure) that don’t require LLM calls.

Webhooks vs polling

Polling is the default. Poll GET /v1/compliance/check-video/{requestId} every 2 seconds. Stop when status is completed or failed. Webhooks are recommended for production. Submit with webhookUrl set, configure a tenant signing secret via /v1/compliance/webhooks/video/secret, and receive HMAC-signed POSTs with stable signatures across retries (5 attempts, exponential backoff 0/1m/5m/15m/1h). See Async + Webhooks for HMAC verification.

Idempotency

Submitting POST /v1/compliance/check-video with the same (requestId, blobPath, jurisdictions, platforms, mode) tuple returns 202 with idempotent: true — no extra charge. Different inputs with the same requestId return 409 idempotency_conflict.

Cost

Per-second pricing. A 60-second video costs ~600 credits. Sub-3-second videos are floored at 30 credits (3-second minimum). See Cost & Credits for the math + tier multipliers.

Next

Run a video check now

Full step-by-step guide.Open the guide →

Async + Webhooks

HMAC verification, retry semantics, replay protection.Read the webhooks guide →