> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zebratruth.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Content Compliance Check

> Step-by-step guide

# Content Compliance Check

Full procedure for running a compliance check in any of the three response modes.

## Prerequisites

* Valid API key (validated via `GET /whoami`)
* **Completed onboarding** — your tenant record must have default jurisdictions and
  platforms set. See the [Tenant Onboarding and Scoping guide](/guides/tenant-onboarding-and-scoping).
  Requests from a tenant that hasn't onboarded return 403.
* Content to check (text, optionally images)
* Target jurisdictions and platforms — must be a subset of what you subscribed to

## Procedure

### Step 1: Check Credits

```
GET https://api.zebratruth.ai/v1/usage
Authorization: Bearer {api_key}
```

Verify `creditsRemaining` is sufficient:

* Fast mode text check: \~12 credits
* Full mode text check: \~47 credits
* Image check: 35 credits per image (additional)

If insufficient, inform the user and suggest upgrading at the `upgradeUrl` in the response.

### Step 2: Choose Mode and Response Mode

**Execution mode:**

* `fast` — All agents run in parallel. Cheaper, faster. Good for quick checks.
* `full` — 4-phase pipeline with content enrichment between phases. Thorough. Use for final pre-publish checks.

**Response mode:**

* `sync` — Block until complete. Best for fast mode or simple integrations.
* `stream` — SSE events per agent. Best for full mode with real-time UI updates.
* `async` — Return immediately, deliver result via webhook. Best for batch processing.

### Step 3: Submit the Check

Two request formats are supported.

**JSON** — canonical format, full feature set (streaming, webhooks, image URLs):

```
POST https://api.zebratruth.ai/v1/compliance/check
Authorization: Bearer {api_key}
Content-Type: application/json
Idempotency-Key: {generate-a-uuid-here}

{
  "jurisdictions": ["us", "eu"],
  "platforms": ["youtube", "instagram"],
  "content": {
    "text": "The full ad script or content text goes here.",
    "imageUrls": ["https://example.com/ad-image.jpg"]
  },
  "mode": "fast",
  "responseMode": "sync",
  "externalId": "my-project-123"
}
```

**Multipart** — use when you need to upload an image binary directly instead of
referencing a public URL:

```bash theme={null}
curl -X POST https://api.zebratruth.ai/v1/compliance/check \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F "text=The full ad script or content text goes here." \
  -F "image=@./ad.png" \
  -F "jurisdictions=us" -F "jurisdictions=eu" \
  -F "platforms=youtube" -F "platforms=instagram" \
  -F "mode=fast"
```

### Step 4: Handle the Response

**Sync mode** — the full report is in the response body.

**Stream mode** — see [streaming-integration.md](streaming-integration.md)

**Async mode** — see [async-webhook-execution.md](async-webhook-execution.md)

### Step 5: Interpret Results

1. Check `decision`: PUBLISH, HOLD, or BLOCK
2. If HOLD or BLOCK, review `checks[]` for detailed findings
3. Use `annotations[]` to map issues to content locations
4. Present `recommendation` fields as actionable fixes

### Step 6: Iterate (if needed)

If the decision is HOLD or BLOCK:

1. Fix the flagged content based on recommendations
2. Re-submit with the updated content (use a NEW `Idempotency-Key`)
3. Repeat until the decision is PUBLISH

## Latency & Timeouts

Sync compliance checks typically complete in **15–120 seconds**, depending on:

* Execution mode (`fast` is parallel across agents; `full` is a 4-phase pipeline and runs longer)
* Number of jurisdictions and platforms in scope (more = more legal context injected into each agent prompt)
* Content length (longer text = more tokens per agent)
* Whether research-stage caches hit (Stage A is cached with a 30-day TTL; identical
  topic queries return in milliseconds)

Cached full-result hits (identical `content.text + jurisdictions + platforms + mode`) return
in **≤1 second** at zero credits.

**Recommended client configuration:**

* Set your HTTP client timeout to **at least 2.5 minutes (150 seconds)** to leave headroom
  above the upper typical bound. Timeouts shorter than 2 min will occasionally cut healthy
  requests.
* For workflows where a 90-second block is unacceptable (batch jobs, UI threads), use
  `responseMode: "async"` with a webhook — the endpoint returns immediately with a `jobId`,
  and the result is POSTed to your webhook when ready. See
  [async-webhook-execution.md](/guides/async-webhook-execution).
* For progressive UI updates while the check runs, use `responseMode: "stream"` (SSE) —
  see [streaming-integration.md](/guides/streaming-integration).

## Error Handling

* **400 Bad Request**: Check that `jurisdictions` and `platforms` contain valid IDs.
* **402 Payment Required**: Credits exhausted. Response includes `creditsRemaining` and `upgradeUrl`.
* **403 Forbidden** — tenant scope: The request asks for a jurisdiction or platform
  outside your subscription, or your tenant record is missing / incomplete. The `error`
  field carries the exact runtime message. Four shapes:

  * `"Tenant not onboarded. Complete setup at https://developers.zebratruth.ai before using the API."` — no tenant record yet
  * `"Tenant configuration incomplete. Set default jurisdictions and platforms in your dev portal."` — tenant exists but has empty defaults
  * `"Requested jurisdictions [india, china] are not in your subscription. Allowed: [us, eu]."`
  * `"Requested platforms [tiktok] are not in your subscription. Allowed: [youtube, instagram]."`

  Fix by adjusting the request or updating defaults at
  [developers.zebratruth.ai/dashboard/settings](https://developers.zebratruth.ai/dashboard/settings).
* **429 Too Many Requests**: Rate limited. Wait for `Retry-After` seconds.

## Example: Full Flow

```bash theme={null}
# 1. Check credits
curl https://api.zebratruth.ai/v1/usage \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY"

# 2. Run check
curl -X POST https://api.zebratruth.ai/v1/compliance/check \
  -H "Authorization: Bearer $ZEBRATRUTH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "jurisdictions": ["us"],
    "platforms": ["youtube"],
    "content": { "text": "Try our amazing guaranteed weight loss pills!" },
    "mode": "fast",
    "responseMode": "sync"
  }'
```
