Skip to content
StatusSupportDashboard

Classify content

POST/v1/content

Classify a piece of content synchronously. Send text and image parts and receive per-label results in the response. Requests have a maximum size of 6MB. API version 2026-08-11; see the API versioning guide for superseded versions.

Errors: 400 for an invalid body or images, with the failing field in the message. 401 for a missing or invalid API key. 413 for requests over 6MB. 503 when classification is temporarily unavailable, in which case the request was not processed and is safe to retry.

Header ParametersExpand Collapse
"SafetyKit-Version": optional "2026-08-11"

The API version this operation is defined against.

Body ParametersJSONExpand Collapse
content: array of object { text, type, key } or object { source, type, key }

Content parts to classify together. At most 20 images.

One of the following:
object { text, type, key }
text: string

User-authored text to classify.

maxLength16000
type: "text"
key: optional string

Your name for where this part came from.

maxLength256
object { source, type, key }
source: object { data, type }
data: string

Base64-encoded image bytes, raw or as a data URI. At most 5MB.

minLength1
type: "base64"
type: "image"
key: optional string

Your name for where this part came from.

maxLength256
user_id: string

Your stable identifier for the user this content belongs to.

minLength1
maxLength512
content_id: optional string

Your content identifier.

minLength1
maxLength512
metadata: optional map[unknown]

Additional product context for this content. At most 8KB when serialized.

ReturnsExpand Collapse
content_id: string

SafetyKit identifier for the classified content.

labels: array of object { decision, escalation, label, 2 more } or object { decision, escalation, label, 3 more }

Per-label results for the submitted content.

One of the following:
object { decision, escalation, label, 2 more }
decision: "match" or "not_match" or "review"

Whether the submitted content matches the label.

One of the following:
"match"
"not_match"
"review"
escalation: "none" or "completed" or "error"

Escalation outcome for this label.

One of the following:
"none"
"completed"
"error"
label: string

Label identifier.

score: number

Classifier score between 0 and 1. Higher means more likely matching. Null when no classifier scored the label.

type: "classifier"
object { decision, escalation, label, 3 more }
decision: "match" or "not_match" or "review"

Whether the submitted content matches the label.

One of the following:
"match"
"not_match"
"review"
escalation: "none" or "completed" or "error"

Escalation outcome for this label.

One of the following:
"none"
"completed"
"error"
label: "reference_set_match"
score: number

Similarity between the submitted content and the matched entry.

set_id: string

Identifier of the matched reference set.

type: "similarity"
user_id: string

The user_id from the request.

version: string

The API version that served this request.

Classify content

curl https://api.safetykit.com/v1/content \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $SAFETYKIT_API_KEY" \
    -d '{
          "content": [
            {
              "text": "Hey, is this still available?",
              "type": "text"
            }
          ],
          "user_id": "user_123",
          "content_id": "post_42",
          "metadata": {
            "channel": "bar"
          }
        }'
{
  "content_id": "post_42",
  "labels": [
    {
      "decision": "not_match",
      "escalation": "none",
      "label": "hate_speech",
      "score": 0.12,
      "type": "classifier"
    }
  ],
  "user_id": "user_123",
  "version": "2026-08-11"
}
Returns Examples
{
  "content_id": "post_42",
  "labels": [
    {
      "decision": "not_match",
      "escalation": "none",
      "label": "hate_speech",
      "score": 0.12,
      "type": "classifier"
    }
  ],
  "user_id": "user_123",
  "version": "2026-08-11"
}