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:
| Limit | Value |
|---|---|
| File size | 10 MB |
| Duration | 60 seconds |
| Frames analysed | 20 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
| Label | Description |
|---|---|
profanity | Profanity |
toxicity | General toxicity |
harassment | Harassment or bullying |
hate | Hate speech or racism |
insult | Insult |
sexual | Sexual content |
sexual/unlawful | Severe sexual content or minors |
sexual/explicit | Explicit sexual depictions |
sensitive | Sensitive content |
violence | Violence or gore |
self-harm | Self-harm content |
medical | Medical/Injury |
spam | Spam |
promotional | Promotional |
scam | Scam/Incoherent |
illegal | Illegal 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:
| Model | Cost 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:
| Plan | Available Models | Monthly Allowance | Context Available |
|---|---|---|---|
| Premium | Observer, Sentinel, Arbiter | See the pricing page for current credit allowances | Yes |
| Legacy Free (pre-13 July 2026 accounts) | Observer only | 0.25 GBP of credits | No |
| Legacy Basic (closed) | Observer only | See the pricing page for current credit allowances | Yes |
| Legacy Standard (closed) | Observer, Sentinel | See the pricing page for current credit allowances | Yes |
Important: Requesting a model your plan does not include returns a 400 Bad Request error.
Error Codes
| Code | Description |
|---|---|
400 | Bad request: invalid parameters or a model your plan does not include |
401 | Unauthorized: invalid or missing API key |
402 | Payment Required: insufficient credits to process request |
429 | Too Many Requests: rate limit exceeded |
500 | Internal server error: unexpected error occurred |