Skip to content

REST API server

Use openmoderate from any language over HTTP.

pip install "openmoderate[server]"
OPENMODERATE_API_KEY=change-me openmoderate serve --host 0.0.0.0 --port 8000

Or with the published Docker image (CPU, model weights included, so it runs offline):

docker run -p 8000:8000 -e OPENMODERATE_API_KEY=change-me ghcr.io/karammm/openmoderate:latest

Pin a version (ghcr.io/karammm/openmoderate:1.1.0 or :1.1) in production. The published image contains the fast model. For another preset, build your own image with its weights baked in:

docker build --build-arg OPENMODERATE_PRESET=accurate -t openmoderate:accurate .

Interactive API docs are served at http://localhost:8000/docs.

Endpoint Body Returns
GET /health – {"status": "ok", "model_loaded": true} (no API key needed)
GET /v1/categories – labels, parents and thresholds
POST /v1/moderate multipart field file one result
POST /v1/moderate/batch multipart field files (repeat it) {"results": [...]}; unreadable files get an error entry
POST /v1/moderate/json {"image_base64": "..."} or {"url": "..."} one result
POST /v1/moderate/video multipart field file; query fps, min_frames, stop_on_violation timestamped segments
curl -H "X-API-Key: change-me" -F file=@upload.jpg http://localhost:8000/v1/moderate
{
  "source": "upload.jpg",
  "is_safe": false,
  "violations": [{"name": "weapons", "confidence": 0.996, "parent": "violence", "threshold": 0.5}],
  "labels": [...]
}
// Node.js
const form = new FormData();
form.append("file", new Blob([fs.readFileSync("upload.jpg")]), "upload.jpg");
const res = await fetch("http://localhost:8000/v1/moderate", {
  method: "POST", headers: { "X-API-Key": "change-me" }, body: form,
});
const { is_safe, violations } = await res.json();

Server settings (environment variables):

Variable Default Purpose
OPENMODERATE_API_KEY unset Require this value in the X-API-Key header. Set it whenever the port is reachable by others.
OPENMODERATE_ALLOW_URLS false Allow {"url": ...} requests (see the security note below)
OPENMODERATE_PRESET fast Model preset: fast, balanced or accurate (also --preset)
OPENMODERATE_CONFIG / OPENMODERATE_HEAD unset Policy YAML and trained head to load (also --config / --head)
OPENMODERATE_MAX_BATCH 16 Max files per batch request
OPENMODERATE_MAX_BYTES 25 MB Max size per image
OPENMODERATE_MAX_VIDEO_BYTES / OPENMODERATE_MAX_VIDEO_SECONDS 200 MB / 600 s Video upload limits
OPENMODERATE_PRELOAD true Load the model at startup rather than on the first request

URL fetching is off by default. A server that downloads any URL it is given can be tricked into reaching internal services (cloud metadata endpoints, admin panels). When you enable it, openmoderate only allows http(s), refuses private, loopback and link-local addresses, and re-checks every redirect. If untrusted callers can use the API, also route outbound traffic through an egress proxy.

Performance: a single-image request took 15–25 ms end to end on an Apple M-series laptop once the model was warm. CPU-only servers will be slower, so measure on your own hardware before sizing. Requests are processed one at a time per worker (PyTorch already uses all cores for each image). Use --workers N to run more processes; each loads its own copy of the model (~600 MB RAM).