Skip to main content
Endpoint:
POST https://api.mynth.io/image/rate
Authentication: API key or OAuth access token required. Public Access Tokens are not accepted. By default the endpoint is synchronous — results are returned in the response body as a 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

{
  "mode": "custom",
  "urls": ["https://example.com/photo-1.webp", "https://example.com/photo-2.webp"],
  "levels": [
    { "value": "safe", "description": "Safe for all audiences" },
    { "value": "sensitive", "description": "Contains mature or suggestive content" },
    { "value": "explicit", "description": "Explicit adult content" }
  ],
  "sync": true
}

Fields

FieldTypeDefaultNotes
modestringrequirednsfw_sfw for the built-in scale, or custom.
urlsarrayrequiredImage URLs to rate. Minimum 1, maximum 10.
levelsarrayRequired when mode is custom. Defines the rating scale.
syncbooleantrueWhen 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:
FieldTypeConstraintsNotes
valuestring1–24 charactersThe string returned in the result for images at this level.
descriptionstring1–150 charactersNatural-language description used by the rating model.
Constraints for the levels array:
  • Minimum 2 items
  • Maximum 7 items
How the rating model uses levels The 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.
{
  "data": {
    "task": {
      "id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
      "status": "completed",
      "cost": "0.00020000"
    },
    "results": [
      { "status": "success", "url": "https://example.com/photo-1.webp", "level": "safe" },
      {
        "status": "failed",
        "url": "https://example.com/photo-2.webp",
        "error": { "code": "RATING_FAILED" }
      }
    ]
  }
}
FieldTypeNotes
data.taskobjectTask record created for this request.
data.resultsarrayOne 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.
{
  "data": {
    "task": {
      "id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
      "status": "pending"
    }
  }
}

Success item

{ "status": "success", "url": "https://example.com/photo-1.webp", "level": "sfw" }
FieldTypeNotes
statusstringAlways success.
urlstringThe submitted image URL.
levelstringThe assigned rating value from the active scale.
When using the default scale, level is one of sfw or nsfw. When using custom levels, level is the value of the chosen level.

Failure item

{
  "status": "failed",
  "url": "https://example.com/photo-2.webp",
  "error": { "code": "RATING_FAILED" }
}
A failure item means that one image could not be rated. Other images in the same request are unaffected.
CodeCause
FETCH_FAILEDThe image could not be downloaded from the provided URL.
RATING_FAILEDThe image was downloaded but the rating operation failed.
UNKNOWN_ERRORAn unexpected error occurred. Should not normally occur; treat as a bug and retry.

Limits

ConstraintValue
URLs per request1–10
Custom levels2–7
Level value1–24 characters
Level description1–150 characters

Pricing

Each URL is priced at **0.0002.Thefullamount(urls×0.0002**. The full amount (`urls` × 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 returns 422 INSUFFICIENT_BALANCE.

Error responses

StatusBodyCause
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.
See Errors and Limits for the full error reference.