Skip to main content

Run a Video Compliance Check

End-to-end in 2 minutes: get an API key, upload a video, get back timestamped findings.
This walks through the video endpoint (POST /v1/compliance/check-video) — the primary ZebraTruth product. For image or text compliance, see Other Content Types.

1. Get your API key

Sign up at developers.zebratruth.ai and create an API key.
export ZEBRATRUTH_API_KEY=zt_live_your_key_here
Test keys (zt_test_...) return deterministic sandbox responses with no credit cost. Use them for development and integration testing.

2. Validate your key

curl https://api.zebratruth.ai/v1/whoami \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY"
Response
{
  "tenantId": "kp_a269d9695f734329a216669410731a21",
  "tier": "pro",
  "authType": "apikey",
  "scopes": ["compliance:check", "agents:*", "reports:read", "policies:read"]
}

3. Request a video upload URL

The video pipeline is fully server-side. No client-side ffmpeg, no preprocessing — your client just gets a signed upload URL, PUTs the bytes, and submits.
curl -X POST https://api.zebratruth.ai/v1/compliance/media/upload-url \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contentType": "video/mp4"}'
Response
{
  "uploadUrl": "https://studio2.blob.core.windows.net/videos/...?sv=...&sig=...",
  "blobPath": "videos/<tenantId>/<requestId>/source.mp4",
  "requestId": "319b5d9e-a67f-45ee-9789-d7384fd73a3e",
  "requiredTags": { "tenantId": "...", "requestId": "...", "kind": "video" },
  "maxSizeBytes": 209715200,
  "uploadInstructions": {
    "method": "PUT",
    "headers": {
      "x-ms-blob-type": "BlockBlob",
      "x-ms-tags": "tenantId=...&requestId=...&kind=video",
      "Content-Type": "video/mp4"
    }
  }
}
Save the requestId + blobPath — you’ll need them in step 5.

4. Upload the video

PUT the video bytes directly to the uploadUrl from step 3. Use exactly the headers in uploadInstructions.headers:
curl -X PUT "$UPLOAD_URL" \
  -H "x-ms-blob-type: BlockBlob" \
  -H "x-ms-tags: $X_MS_TAGS" \
  -H "Content-Type: video/mp4" \
  --data-binary @your-ad.mp4
The upload bypasses ZebraTruth servers — bytes go directly to managed blob storage. Max 200 MB.

5. Submit for compliance analysis

curl -X POST https://api.zebratruth.ai/v1/compliance/check-video \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "319b5d9e-a67f-45ee-9789-d7384fd73a3e",
    "blobPath": "videos/<tenantId>/<requestId>/source.mp4",
    "jurisdictions": ["us", "eu"],
    "platforms": ["tiktok", "youtube"],
    "mode": "fast"
  }'
Response (HTTP 202)
{
  "jobId": "319b5d9e-a67f-45ee-9789-d7384fd73a3e",
  "status": "queued",
  "estimatedCredits": 300
}
You’ll get back a 202 Accepted immediately with estimatedCredits reserved. The pipeline runs server-side — no client preprocessing required.

6. Poll for the report

curl https://api.zebratruth.ai/v1/compliance/check-video/319b5d9e-a67f-45ee-9789-d7384fd73a3e \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY"
Response (status: completed)
{
  "requestId": "319b5d9e-a67f-45ee-9789-d7384fd73a3e",
  "status": "completed",
  "reportStatus": "complete",
  "billingStatus": "committed",
  "durationMs": 28000,
  "report": {
    "schemaVersion": "video-report.v1",
    "status": "complete",
    "checks": [
      {
        "agentId": "advertising-law",
        "checkName": "Unsubstantiated efficacy claim",
        "status": "flag",
        "severity": "medium",
        "evidenceIds": ["audio_003"],
        "timelineLocation": { "startMs": 4500, "endMs": 7200, "track": "audio" },
        "message": "Claim 'guaranteed results' lacks substantiation — FTC §5 risk.",
        "recommendation": "Add 'individual results may vary' overlay or remove claim."
      },
      {
        "agentId": "rights-clearance-image",
        "checkName": "Brand detected: Nike",
        "status": "flag",
        "severity": "medium",
        "evidenceIds": ["frame_007", "frame_009"],
        "timelineLocation": { "startMs": 12000, "endMs": 18000, "track": "video" }
      }
    ],
    "analysisDiagnostics": [],
    "preprocessing": {
      "transcriptionStatus": "complete",
      "frameAnalysisStatus": "complete",
      "degraded": false,
      "evidenceTruncated": false
    }
  }
}
Poll every 2 seconds. Typical completion: 20-60 seconds for a 30-second video.

Status state machine

queued → processing → completed (reportStatus: complete / insufficient_evidence)

                    failed (reportStatus: analysis_failed)
When status is completed or failed, stop polling. Configure a webhook URL once at the account level, then submit videos with no polling required:
curl -X POST https://api.zebratruth.ai/v1/compliance/check-video \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY" \
  -d '{
    "requestId": "<uuid>",
    "blobPath": "<from step 3>",
    "jurisdictions": ["us"],
    "platforms": ["tiktok"],
    "mode": "fast",
    "webhookUrl": "https://yourapp.com/zebratruth-callback"
  }'
Each delivery is HMAC-signed with a stable signature across retries (5 attempts, exponential backoff). See Async + Webhooks for HMAC verification + retry handling.

Next Steps

Full video guide

Detailed examples, error codes, webhook HMAC verification.

Cost & credits

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

LLM Skill installation

Install the ZebraTruth skill so your LLM agent can run video compliance checks autonomously.

Other content types

Image + text endpoints (sync).