# Moderate text with ZeroGPU's OpenAI-compatible moderation API

ZeroGPU's content moderation API checks one string or a list of strings and returns OpenAI's moderations envelope for each input: a `flagged` verdict, 13 category booleans and 13 `category_scores`. Calls draw on prepaid Credits at $0.10 per million input tokens and $0.15 per million output tokens. Send `POST https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/zeroclick/v1/moderations` with `model` and `input`, and put your ZeroClick credential in `Authorization`.

## At a glance

- **Endpoint:** `POST https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/zeroclick/v1/moderations`
- **Body:** `model` (`zlm-v1-moderation-edge`; the OpenAI ids `omni-moderation-latest` and `text-moderation-stable` are accepted and mapped to it) and `input`, which is one string or an array of strings.
- **Price:** $0.10 per million input tokens, $0.15 per million output tokens.
- **Payment:** calls draw on Credits, bought once from $0.01 on a wallet or $0.50 by card.
- **Credential:** `Authorization: Bearer <access token>` for a registered agent credential, or `Authorization: Receipt <receiptId>` for a small credit bought without registering.
- **Response:** `id`, `model` and `results`, with one entry per input. Each entry has `flagged`, `categories`, `category_scores` and `category_applied_input_types`.
- **Limits:** text only. A `429` carries `retry-after`.
- **Full purchase flow:** [the buyer skill](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/SKILL.md)

## Screen messages before they are posted

1. Get a credential that holds credit: Credits bought with a registered agent credential, or a receipt from a small credit bought without registering for a first test. [The buyer skill](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/SKILL.md) has the steps.

2. Send the text to check. This request sends two messages in one call:

   ```bash
   curl -s https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/zeroclick/v1/moderations \
     -H "Authorization: Bearer $ACCESS_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"model": "zlm-v1-moderation-edge", "input": ["Thanks for the quick reply, that fixed my login problem.", "You are worthless and everyone at this company hates you."]}'
   ```

3. Read `results`. Each element of `input` gets one entry. In the example response, the first entry, for the thanks message, has `flagged` set to false and every score below 0.001:

   ```json
   {
     "model": "zlm-v1-moderation-edge",
     "results": [
       {
         "flagged": false,
         "categories": {"harassment": false, "harassment/threatening": false, "hate": false, "hate/threatening": false, "illicit": false, "illicit/violent": false, "self-harm": false, "self-harm/intent": false, "self-harm/instructions": false, "sexual": false, "sexual/minors": false, "violence": false, "violence/graphic": false},
         "category_scores": {"harassment": 0.000251, "harassment/threatening": 0.000251, "hate": 0.000287, "hate/threatening": 0.000287, "illicit": 0.000435, "illicit/violent": 0.000435, "self-harm": 0.000583, "self-harm/intent": 0.000583, "self-harm/instructions": 0.000583, "sexual": 0.000439, "sexual/minors": 0.000439, "violence": 0.000514, "violence/graphic": 0.000514}
       }
     ],
     "usage": {"prompt_tokens": 29, "completion_tokens": 503, "total_tokens": 532}
   }
   ```

   The second entry, for the insult, has `flagged` set to true, with `harassment` scoring 0.788. In `category_applied_input_types`, every category maps to `["text"]` because the model is text only.

4. Check what the call drew. A response funded by credit carries a `zc-billing` header with `fundingSource`, `chargedUsd` and `remainingCreditUsd`. The example call used 29 prompt tokens and 503 completion tokens, and drew $0.000078 from credit.

## Use it from an OpenAI moderation client

Code written for OpenAI's moderation endpoint needs two changes:

| Setting | Value |
| --- | --- |
| Base URL | `https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/zeroclick/v1` |
| Credential | your ZeroClick access token, sent as `Authorization: Bearer` |
| `model` | `zlm-v1-moderation-edge`, or keep `omni-moderation-latest`, which is mapped to it |

The request body is unchanged. All 13 categories are always present in `categories` and `category_scores`, in OpenAI's order. Code that reads `results[i].flagged` and `results[i].category_scores` keeps working.

## Turn scores into block, flag or allow

`flagged` is the model's verdict. It is true if the model marked the input in any category. Each `category_scores` value is a confidence between 0 and 1, and those scores are what a pipeline sets its thresholds on. The decision belongs to you.

The cut-offs in this table only illustrate the pattern. Which values to use is your own choice.

| Condition (your thresholds) | Action |
| --- | --- |
| Any score of 0.8 or more in a category your policy forbids | Block the message |
| `flagged` is true, or the highest score is between 0.3 and 0.8 | Hold it for review |
| `flagged` is false and every score is below 0.3 | Allow it |

## What is charged, and when

- Each call draws its input and output tokens from your credit balance. The call itself never answers with a price quote. Only buying Credits does.
- A call without a credential returns `401 bearer_required`. A credential with no covering plan returns `403 plan_required`.
- A receipt spends only its own small balance. It cannot be topped up, and losing it loses the remaining credit.
- Credit you do not use stays on the balance.

## Limits

- Text only. The endpoint does not moderate images.
- One request takes one string or one list of strings, and returns one result per element.

## Errors

| Status or code | Meaning | Action |
| --- | --- | --- |
| `bearer_required` | No credential was sent | Register at [auth.md](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/auth.md) and retry with `Authorization: Bearer` |
| `plan_required` | The credential holds no Credits | Buy Credits at `/plans/{planId}/purchase`, then retry |
| `usage_exhausted` | The credit balance is used up | Top up with `POST https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/extend` and `{"amountUsd": "..."}` |
| `receipt_credit_exhausted` | The receipt cannot cover the call | Buy a new receipt, or buy a larger balance with an agent credential |
| `400`, error type `invalid_request_error` | Malformed JSON, or a missing or invalid `input` | Fix the body |
| `429`, error type `rate_limit_error` | Too many requests | Wait `retry-after` seconds, then retry |

## Frequently asked questions

### Is this a drop-in replacement for OpenAI's moderation API?

For text, yes. The request body and the `results` shape match OpenAI's moderations envelope, and `omni-moderation-latest` is accepted as a `model` value. A client changes only its base URL to `https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/zeroclick/v1` and its credential.

### How much does it cost to moderate user comments?

Each call is billed on the tokens it uses: $0.10 per million input tokens and $0.15 per million output tokens, drawn from prepaid Credits. The `zc-billing` header on each response states what that call drew and the balance left.

### Can I moderate several chat messages in one call?

Yes. Send `input` as an array of strings, and `results` comes back with one entry per string.

### Does it moderate images?

No. This is a text-only moderation model, and every category in `category_applied_input_types` maps to `["text"]`.

### Do I need a ZeroGPU API key?

No. Calls through the storefront use a ZeroClick credential: a registered agent credential presented as a bearer token, or a receipt from a small credit bought without registering. [auth.md](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/auth.md) covers both.

## Keep reading

- [ZeroGPU API pricing: per-token rates and Credits](/guides/pricing-for-agents)
- [ZeroGPU API errors and recovery](/guides/errors)
- [Send a chat completion with ZeroGPU's API](/guides/quickstart)
- [Buyer skill](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/SKILL.md): the full purchase flow
- [How to pay](https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/payment.md): x402, MPP, card and top-ups

---

Updated 2026-10-16. All ZeroGPU guides: https://agents.zerogpu.ai/guides.md. Storefront: https://agents.zerogpu.ai/zcj/v0s9gt5l7mgi/llms.txt.
