200. Set "sync": false to queue the task and receive a 202 with a task ID for polling instead. In sync mode, if the task does not finish within the sync timeout the endpoint returns a 202 pending response, and if the task fails it returns a 500.
Request body
Fields
| Field | Type | Default | Notes |
|---|---|---|---|
mode | string | required | nsfw_sfw for the built-in scale, or custom. |
urls | array | required | Image URLs to rate. Minimum 1, maximum 10. |
levels | array | — | Required when mode is custom. Defines the rating scale. |
sync | boolean | true | When true, wait for results and return them inline. When false, return a 202 pending task. |
levels items
Each item in the levels array must have:
| Field | Type | Constraints | Notes |
|---|---|---|---|
value | string | 1–24 characters | The string returned in the result for images at this level. |
description | string | 1–150 characters | Natural-language description used by the rating model. |
levels array:
- Minimum
2items - Maximum
7items
description of each level is passed directly to a vision language model (LLM), which selects the best match for each image. Because LLM inference is non-deterministic, results for borderline images may occasionally vary between requests.
This endpoint is optimised for speed and accuracy at a high level of abstraction. Broad, clearly separated scales such as safe / suggestive / explicit or safe-for-children / safe-for-adults / nsfw perform reliably. Scales that depend on subtle visual distinctions — for example distinguishing between artistic and explicit nudity — are outside the intended scope and may produce inconsistent results. Test thoroughly before using such scales in production.
Response body
200 — completed
Returned when sync is true (the default) and the task finishes within the sync timeout.
| Field | Type | Notes |
|---|---|---|
data.task | object | Task record created for this request. |
data.results | array | One entry per submitted URL, in the same order. Each entry is a success or failure item. |
202 — pending
Returned when sync is false, or when sync is true but the task did not finish within the sync timeout. Use the task id to poll for completion.
Success item
| Field | Type | Notes |
|---|---|---|
status | string | Always success. |
url | string | The submitted image URL. |
level | string | The assigned rating value from the active scale. |
level is one of sfw or nsfw.
When using custom levels, level is the value of the chosen level.
Failure item
| Code | Cause |
|---|---|
FETCH_FAILED | The image could not be downloaded from the provided URL. |
RATING_FAILED | The image was downloaded but the rating operation failed. |
UNKNOWN_ERROR | An unexpected error occurred. Should not normally occur; treat as a bug and retry. |
Limits
| Constraint | Value |
|---|---|
| URLs per request | 1–10 |
| Custom levels | 2–7 |
Level value | 1–24 characters |
Level description | 1–150 characters |
Pricing
Each URL is priced at **0.0002) is reserved from your account balance before processing begins. You are charged only for URLs that are successfully rated — the reserved balance for any failed ratings is released. If your balance is insufficient to reserve the full amount, the request returns422 INSUFFICIENT_BALANCE.
Error responses
| Status | Body | Cause |
|---|---|---|
400 | { success: false, errors: [...] } | Request body fails schema validation. |
401 | { code: "UNAUTHORIZED", ... } | Missing or invalid API key or OAuth access token. |
422 | { code: "INSUFFICIENT_BALANCE" } | Account balance is too low to reserve the full cost. |
500 | { code: "UNKNOWN_ERROR" } | sync is true and the rating task failed. Use async mode or retry to poll the task. |