API Reference

API Reference

Complete reference for the Supervisor API endpoints.

Authentication

All API requests require authentication using an API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Base URL

https://supervisor.gg/api

POST /moderate

Moderate text content using AI models. Optionally include context analysis to determine if message history is needed.

Request Body

{
    "text": "string (optional, required if no image)",
    "image": "base64 string (optional, required if no text)",
    "model": "observer|sentinel|arbiter (optional, default: sentinel)",
    "enabled_labels": ["profanity", "toxicity", "harassment", "hate", "insult", "sexual", "sexual/unlawful", "sexual/explicit", "sensitive", "violence", "self-harm", "medical", "spam", "promotional", "scam", "illegal"] (optional),
    "include_context": boolean (optional, default: false, included with Premium)
}

Response

{
    "flagged": boolean,
    "labels": string[],
    "implicit_labels": string[],
    "model_version": string,
    "needs_context": boolean (only present if include_context=true),
    "context_labels": string[] (only present if include_context=true)
}

Example: Basic Moderation

curl -X POST https://supervisor.gg/api/moderate \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello, this is a test message",
    "model": "sentinel"
  }'

Example: With Context Analysis

curl -X POST https://supervisor.gg/api/moderate \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "text": "stop it",
    "model": "sentinel",
    "include_context": true
  }'

# Response:
{
    "flagged": false,
    "labels": [],
    "needs_context": true,
    "context_labels": ["harassment"]
}

Example: Image Moderation

Images can be moderated by sending base64-encoded image data in the image field instead of text. Send text and images in separate requests.

# Encode image to base64 and send
curl -X POST https://supervisor.gg/api/moderate \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "image": "<base64-encoded image data>",
    "model": "sentinel"
  }'

GET /labels

Get a list of all available content labels and their descriptions.

Response

{
    "profanity": "Profanity",
    "toxicity": "Toxicity",
    "harassment": "Harassment",
    "hate": "Hate/Racism",
    "insult": "Insult",
    "sexual": "Sexual",
    "sexual/unlawful": "Sexual (Unlawful)",
    "sexual/explicit": "Sexual (Explicit)",
    "sensitive": "Sensitive Content",
    "violence": "Violence",
    "self-harm": "Self-Harm",
    "medical": "Medical/Injury",
    "spam": "Spam",
    "promotional": "Promotional",
    "scam": "Scam/Incoherent",
    "illegal": "Illegal Activity"
}

Example

curl -X GET https://supervisor.gg/api/labels \
  -H "Authorization: Bearer sk_test_..."

POST /batch

Moderate multiple texts in a single request. Useful for processing large volumes of content efficiently.

Request Body

{
    "texts": ["string"] (required array),
    "model": "observer|sentinel|arbiter (optional, default: sentinel)",
    "enabled_labels": ["profanity", "toxicity", "harassment", "hate", "insult", "sexual", "sexual/unlawful", "sexual/explicit", "sensitive", "violence", "self-harm", "medical", "spam", "promotional", "scam", "illegal"] (optional),
    "include_context": boolean (optional, default: false, included with Premium)
}

Response

[
    {
        "flagged": boolean,
        "labels": string[],
        "implicit_labels": string[],
        "model_version": string,
        "needs_context": boolean (only present if include_context=true),
        "context_labels": string[] (only present if include_context=true)
    }
]

Example

curl -X POST https://supervisor.gg/api/batch \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "texts": [
      "First message to check",
      "Second message to check",
      "Third message to check"
    ],
    "model": "sentinel",
    "include_context": true
  }'

POST /username

Check whether a username is allowed. Returns a flag and a confidence score.

Request Body

{ "username": "user123" }

Response

{ "flagged": false, "score": 0.12 }

Example

curl -X POST https://supervisor.gg/api/username \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "username": "user123" }'

Platform API

Building moderation into your own product for many of your own users? The Platform API adds OAuth2 client credentials, per-user provisioning, and delegated moderation. See the dedicated Platform API guide for the full flow and endpoint reference.

Models

  • observer (v2.1): Fast, lightweight model for high-volume applications (~£0.0014/KB)
  • sentinel (v2.1): Balanced model with good accuracy and speed (~£0.0027/KB)
  • arbiter (v2.1): Most accurate model for critical moderation (~£0.0055/KB)

Video moderation

POST /api/moderation/user/video moderates a short video. Requires the video-moderation feature on your plan.

Send the whole clip. Supervisor decodes it, picks out the frames where the picture actually changes rather than every frame, and moderates those through the same pipeline as images. A sixty second clip costs a handful of frames, not hundreds.

Limits, all enforced server-side:

LimitValue
File size10 MB
Duration60 seconds
Frames analysed20 maximum
curl -X POST https://supervisor.gg/api/moderation/user/video \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video": "BASE64_ENCODED_VIDEO",
    "model": "arbiter"
  }'
{
  "flagged": true,
  "labels": ["violence"],
  "frames": [
    { "timestamp_ms": 0, "flagged": false, "labels": [] },
    { "timestamp_ms": 2133, "flagged": true, "labels": ["violence"] }
  ],
  "frames_analysed": 2,
  "duration_secs": 6.4,
  "codec": "h264",
  "decoder": "nvdec"
}

frames carries a timestamp_ms per analysed frame, so a flagged moment can be located in the clip rather than only reported for the video as a whole. labels at the top level is the union across every frame.

H.264 and HEVC decode on the GPU; VP9 and AV1 fall back to software decode and are slower. decoder reports which ran.

The SDKs wrap this, and check the size limit locally so an oversized clip fails before it is uploaded:

result = client.moderate_video("clip.mp4")
const result = await client.moderateVideo(videoBytes);

Labels

LabelDescription
profanityProfanity
toxicityGeneral toxicity
harassmentHarassment or bullying
hateHate speech or racism
insultInsult
sexualSexual content
sexual/unlawfulSevere sexual content or minors
sexual/explicitExplicit sexual depictions
sensitiveSensitive content
violenceViolence or gore
self-harmSelf-harm content
medicalMedical/Injury
spamSpam
promotionalPromotional
scamScam/Incoherent
illegalIllegal activity

OpenAPI Specification

A machine-readable OpenAPI 3.0 spec describes every endpoint, schema, and error shape on this page. Import it into Postman, Insomnia, or your codegen tool of choice.

Credits and Billing

Text is billed by the byte at the model's rate:

ModelCost per KB
Observer~£0.0014
Sentinel~£0.0027
Arbiter~£0.0055

Video frames are billed at a quarter of the image rate, and extracted at a smaller size than a standalone image, so a full 20 frame clip costs far less than 20 images. Batched requests get 50% off, which applies to video frames since a clip goes through as one batch.

Images are billed at a flat ~£0.0014/KB of image data, the Observer rate, regardless of model. If our OCR extracts readable text from the image, that text is additionally billed at the model's rate, so you only pay text-model prices when the text models actually run.

Examples:

  • Moderating 1 KB of text with Sentinel costs about £0.0027.
  • Moderating a 100 KB image with no readable text costs about £0.14 on any model.
  • Moderating a 100 KB image containing 200 bytes of readable text with Arbiter costs about £0.14.

Cached results are free: repeating an identical (or near-identical, for images) request within the cache window consumes no credits.

The grandfathered free tier (accounts created before 13 July 2026 only) includes 0.25 GBP of credits per month; newer accounts start with a paid plan. View your credit usage in the Dashboard.

When your balance is exhausted: API requests will fail with HTTP 402 Payment Required until credits are replenished through monthly reset or subscription upgrade.

Model Access

Premium is the only plan on sale and includes every model. The remaining rows are closed plans, listed for the accounts still on them:

PlanAvailable ModelsMonthly AllowanceContext Available
PremiumObserver, Sentinel, ArbiterSee the pricing page for current credit allowancesYes
Legacy Free (pre-13 July 2026 accounts)Observer only0.25 GBP of creditsNo
Legacy Basic (closed)Observer onlySee the pricing page for current credit allowancesYes
Legacy Standard (closed)Observer, SentinelSee the pricing page for current credit allowancesYes

Important: Requesting a model your plan does not include returns a 400 Bad Request error.

Error Codes

CodeDescription
400Bad request: invalid parameters or a model your plan does not include
401Unauthorized: invalid or missing API key
402Payment Required: insufficient credits to process request
429Too Many Requests: rate limit exceeded
500Internal server error: unexpected error occurred