Run CautionLabs on your infrastructure
Log in to our registry with your private key, start the container, and call a local endpoint. The text you send never leaves your network.
http://localhost:8000Introduction
CautionLabs is a content moderation model that runs on your own servers. It analyzes user-generated text and returns a boolean flag for each of twelve moderation categories: true if the category was detected, false if not. Use it to filter chat, comments, reviews, and any other text your product accepts. It is built for English text.
This guide covers running the model yourself. If you would rather call our hosted endpoint, see the Cloud API reference.
The model ships as a container image in the CautionLabs registry. Your private key is the registry password: it is checked against your license each time the image is downloaded, and revoking the key stops further downloads. Once the image is on your host, the container serves a local HTTP endpoint, makes no outbound requests, and has no telemetry.
Where will it run?
Pick the row that matches you. Each has its own step-by-step section below.
| You have | What you do | Go to |
|---|---|---|
A server, VM or laptop where you can run docker | You log in to the registry and start the container yourself. | Deploy with Docker |
| A GPU pod platform such as RunPod or Novita, where you pick an image and a GPU in a web console | You give the platform the image name and your key. The platform pulls and starts it. There is no docker command to run. | Deploy on RunPod, Novita & GPU pods |
Requirements
- A host: Linux with Docker, on x86_64 or arm64 (tested on Ubuntu, Debian and Amazon Linux, including AWS Graviton), or a GPU cloud such as RunPod. Any host that runs Linux containers works.
- Memory and disk: about 4 GB of free RAM, and at least 15 GB of free disk on x86_64 (a 4.6 GB download that unpacks to about 7 GB) or about 8 GB on arm64 (a 2 GB download).
- GPU (optional): a CPU is enough. To use an NVIDIA GPU (x86_64 only) you need the NVIDIA Container Toolkit, a driver version 580 or newer (the image uses CUDA 13), and a Turing generation or newer card: the RTX 20, 30 and 40 series, T4, L4, A10, A100 and H100. Pascal and Volta cards, such as the GTX 10 series and V100, are not supported. The model uses about 2 GB of GPU memory.
- Network, for the download: allow outbound HTTPS to
registery.cautionlabs.comand to*.r2.cloudflarestorage.com, where the image layers are served from. The running model needs no internet at all. See Air-gapped install.
Deploy with Docker
For a machine where you can run docker: a Linux server, a cloud VM, or a laptop with Docker Desktop.
1. Get a private key
Buy the model on the Licenses page, then create a private key on the Private Keys page. It starts with sk_private_.
2. Log in and start the container
Run this on the machine, with your key in place of sk_private_.... The username can be anything; the password is the key.
echo sk_private_... | docker login registery.cautionlabs.com -u cautionlabs --password-stdin
docker run -d --name argus_1 --restart unless-stopped -p 127.0.0.1:8000:8000 registery.cautionlabs.com/argus_13. Wait until it is ready
The first run downloads the image, which takes a few minutes. The model then needs a few more minutes to load. docker ps shows (healthy) when it is ready.
4. Send it some text
From the same machine:
curl -X POST http://localhost:8000/moderate \
-H "Content-Type: application/json" \
-d '{"text": "Hello, world!"}'127.0.0.1, so only the host itself can reach it. See Run options to serve other machines, and keep it behind your own firewall or private network.Deploy on RunPod, Novita and other GPU pods
For a platform where you choose an image and a GPU in a web console and the platform starts the container for you. You do not run docker yourself: you give the platform the image name and your private key, and it pulls the image from the CautionLabs registry. RunPod is tested. Novita and other platforms that pull private images work the same way: add the registry credential, then use the image name in a pod or template.
- Buy the model on the Licenses page and create a private key on the Private Keys page.
- In the platform's settings, add a private container registry credential: the registry username and password from the table below. On RunPod this is Settings, then Container Registry Auth.
- Create a GPU pod or template using the image and the other settings in the table, and select that credential for the pod.
- Start the pod. The first start downloads about 4.6 GB, so allow a few minutes before it shows as running.
- Open the address the platform gives for port 8000 and check
/health. On RunPod that ishttps://<pod id>-8000.proxy.runpod.net/health.
| Setting | Value |
|---|---|
| Container image | registery.cautionlabs.com/argus_1 |
| Registry username | cautionlabs (any value is accepted) |
| Registry password | your private key, sk_private_... |
| HTTP port to expose | 8000 |
| Container disk | at least 25 GB |
| Start command | leave empty: the image starts the model itself |
| GPU | Turing generation or newer, NVIDIA driver 580 or newer (CUDA 13) |
Once /health answers {"status":"ok"}, send text to /moderate on the same address, exactly as in the Docker section.
Run options
The container is started with plain docker run, so add these flags to the command from the quickstart.
| To | Add | Notes |
|---|---|---|
| Use a different host port | -p 8001:8000 | The container always listens on 8000 inside, so this publishes it on 8001. |
| Accept traffic from other machines | -p 8000:8000 | Without 127.0.0.1: the port is open on every interface. Open it in your firewall or security group only to your own application servers: the model has no authentication. |
| Use an NVIDIA GPU | --gpus all | Needs the NVIDIA Container Toolkit and an NVIDIA driver version 580 or newer. x86_64 only. |
| Limit memory | --memory 6g | The model needs about 4 GB. Below that the container is stopped while it loads. |
| Start on boot and after a crash | --restart unless-stopped | Already part of the quickstart command. |
| Name the container | --name argus_1 | Already part of the quickstart command. It is how you stop, restart and read the logs. |
Example: a GPU host
docker run -d --name argus_1 --restart unless-stopped --gpus all -p 127.0.0.1:8000:8000 registery.cautionlabs.com/argus_1Air-gapped install
For a host with no internet access, download the image on a connected machine and carry it across as a file.
1. Save the image on a connected machine
echo sk_private_... | docker login registery.cautionlabs.com -u cautionlabs --password-stdin
docker pull registery.cautionlabs.com/argus_1
docker save -o argus_1.tar registery.cautionlabs.com/argus_1This writes argus_1.tar to the current directory, about 7 GB.
2. Load and run it on the air-gapped host
docker load -i argus_1.tar
docker run -d --name argus_1 --restart unless-stopped -p 127.0.0.1:8000:8000 registery.cautionlabs.com/argus_1The model image contains everything it needs. It never contacts CautionLabs, a model registry, or any other service.
Moderate text
Analyze a string of text and receive a boolean flag for each of the twelve moderation categories.
/moderateRequest body
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The text content to analyze. UTF-8 encoded. Only the first 512 tokens, about 2,000 characters of English, are read. |
Example request
curl -X POST http://localhost:8000/moderate \
-H "Content-Type: application/json" \
-d '{"text": "Your content to analyze"}'Example response
Returns 200 OK with a JSON object containing a categories object, where each key is a boolean flag. Unlike the Cloud API, the local endpoint needs no API key and returns no top-level flagged field.
{
categories: {
toxic: false,
profanity: false,
hate: false,
harassment: false,
self_harm: false,
adult: false,
violence: false,
drugs: false,
weapons: false,
pii: false,
spam: true,
minor: false,
},
}Health check
/healthUse this for load balancer and orchestrator health probes.
curl http://localhost:8000/health
# {"status":"ok"}Throughput
Concurrent requests are grouped into small batches automatically, so sending requests in parallel is faster than sending them one at a time. Each container holds one copy of the model. To scale, run more containers behind a load balancer. Your license allows as many as you need.
Response fields
Every successful response includes all twelve category flags nested under categories. Each is either true (detected) or false (not detected). There are no thresholds to tune.
| Field | Category | Description |
|---|---|---|
categories.toxic | Toxicity | Boolean flag — true if the text contains toxic content |
categories.profanity | Profanity | Boolean flag — true if the text contains profanity |
categories.hate | Hate Speech | Boolean flag — true if the text contains hate speech |
categories.harassment | Harassment | Boolean flag — true if the text contains harassment |
categories.self_harm | Self-Harm | Boolean flag — true if the text contains self-harm content |
categories.adult | Adult Content | Boolean flag — true if the text contains adult content |
categories.violence | Violence | Boolean flag — true if the text contains violent content |
categories.drugs | Drug Content | Boolean flag — true if the text contains drug-related content |
categories.weapons | Weapons | Boolean flag — true if the text contains weapons-related content |
categories.pii | PII Detection | Boolean flag — true if the text contains PII |
categories.spam | Spam | Boolean flag — true if the text is spam |
categories.minor | Minor Safety | Boolean flag — true if the text endangers minor safety |
categories is true. To allow some categories on your platform, such as profanity, check only the ones you care about.Upgrading
Upgrades to a model you own are included in your purchase. To upgrade, pull the latest image and start the container again.
docker pull registery.cautionlabs.com/argus_1
docker rm -f argus_1
docker run -d --name argus_1 --restart unless-stopped -p 127.0.0.1:8000:8000 registery.cautionlabs.com/argus_1On RunPod and other GPU clouds, restart or redeploy the pod. The latest image is pulled again. For air-gapped hosts, repeat the save and load steps. There is no limit on how many times you can download a model you have bought.
Errors
Logging in or pulling the image
These come from the registry, in docker login, docker pull, or the log of a GPU cloud that cannot start the pod.
| Message | Meaning |
|---|---|
unauthorized: Log in with any username and your private key as the password. | The password is not a valid private key, or the key was deleted. Create a new private key in the dashboard. |
denied: This is not a private key. Use the private key from your CautionLabs dashboard. | A cloud key (sk_...) was used. Only private keys (sk_private_...) can download a model. |
denied: You have not purchased this model. | The account behind the key has no license for this model, or the purchase was refunded. |
No repository named ... | The image name is wrong. Use registery.cautionlabs.com/argus_1. The tag latest is the current release. |
Starting the container
| Problem | What to check |
|---|---|
| The container stops while loading | Usually not enough memory. The model needs about 4 GB of free RAM. Read the reason with docker logs argus_1. |
/health does not answer yet | The model takes a few minutes to load, longer on a slow or busy host. docker ps shows (healthy) when it is ready. |
| The GPU is not used | Check that you passed --gpus all, that nvidia-smi works on the host, and that the driver is version 580 or newer. |
Local endpoint
| Status | Description |
|---|---|
422 | Malformed body: text is missing or is not a string. |
500 | Unexpected error inside the model container. Check docker logs argus_1. |
Data & privacy
- Text you moderate is processed on your host and is never sent to CautionLabs.
- The model container makes no outbound network requests. It has no telemetry, no usage reporting, and does not log request text.
- The only requests to CautionLabs happen when the image is downloaded: the license check, which sends your private key, and the image layers themselves. After the image is on your host, the model runs without any connection to us.