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

# Image moderation

> Screen images for unsafe content using vision-language and NSFW classifiers

Image moderation evaluates a single image against vision-language classifiers (for NSFW, AI adult
general, and underage detection) plus any per-client custom categories you have configured.

## Input

Submit a `multipart/form-data` request with:

| Field         | Type   | Required | Description                                                                                   |
| ------------- | ------ | -------- | --------------------------------------------------------------------------------------------- |
| `image`       | string | Yes      | Publicly reachable HTTP or HTTPS URL of the image to scan. The classifiers fetch it directly. |
| `webhook_url` | string | No       | URL to receive the result on completion.                                                      |

```bash theme={null}
curl -X POST https://api.omnifence.ai/api/v1/moderate/image \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "image=https://example.com/photo.jpg"
```

<Note>
  The `image` field must be a public HTTP or HTTPS URL. URLs using another scheme, or resolving to a
  private or internal network address, are rejected with `400 INVALID_REQUEST`.
</Note>

## Pipeline

Checks run in parallel on the submitted image:

### VLM classification

A vision-language model analyses the image for each configured visual
[moderation category](/moderation/categories) — by default NSFW, AI adult general, and underage.
Disabled categories are skipped at enqueue time.

### Custom VLM categories

If your client has any [custom categories](/moderation/categories#custom-categories) enabled, each one
runs as an additional VLM child job in parallel. Results are returned nested under `categories.custom`
on the completed job.

## Output

When all child checks complete, the parent job merges the results:

```json theme={null}
{
  "is_prohibited": false,
  "categories": {
    "ai_adult_general": false,
    "underage": false,
    "nsfw": false,
    "custom": {
      "brand_logos": false
    }
  },
  "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "type": "image",
  "status": "completed",
  "created_at": "2026-05-19T12:00:00.000Z",
  "completed_at": "2026-05-19T12:00:05.000Z"
}
```

`categories.custom` is only included when at least one custom category ran for the job. If you haven't
configured any custom categories, the `custom` key is omitted entirely.
See [decision logic](/moderation/decisions) for how the prohibition decision is determined.
