# Runs | Chersus

Documentation

# Runs

One transform plus any number of checks in a single run, all on your input at the same time. The run bills the characters in and the characters the transform hands back, once.

Last updated 2026-09-10

A run is not limited to one service. Name one transform in `transform` and any number of checks in `checks`; they all run on your input at the same time, and one response carries every result.

```
curl -X POST https://api.chersus.com/v1/run \
-H "Authorization: Bearer $CHERSUS_KEY" \
-H "Content-Type: application/json" \
-d '{
  "type": "text",
  "input": "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
  "transform": "governance.pii.redact",
  "checks": ["security.toxicity.flag"]
}'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
method: "POST",
headers: {
  Authorization: "Bearer " + process.env.CHERSUS_KEY,
  "Content-Type": "application/json",
},
body: JSON.stringify({
  type: "text",
  input: "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
  transform: "governance.pii.redact",
  checks: ["security.toxicity.flag"],
}),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
  "https://api.chersus.com/v1/run",
  headers={"Authorization": "Bearer " + os.environ["CHERSUS_KEY"]},
  json={
      "type": "text",
      "input": "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
      "transform": "governance.pii.redact",
      "checks": ["security.toxicity.flag"],
  },
)

data = res.json()
```

The rewritten text arrives in `output`, its details in `transformed`; each check reports under its own name in `checked`:

```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X0",
  "status": "completed",
  "output": "Contact [REDACTED] at [REDACTED]. Your service is garbage.",
  "transformed": {
    "service": "governance.pii.redact",
    "changes": 2
  },
  "checked": {
    "security.toxicity.flag": {
      "kind": "classify",
      "verdict": "flag",
      "score": 0.84,
      "labels": ["threat"]
    }
  },
  "usage": {
    "billed": { "unit": "characters", "input": 66, "output": 58, "quantity": 124 }
  }
}
```

The run billed 124: 66 characters in, 58 handed back by the redaction. The toxicity check added latency and nothing to the bill.

## What can share a run

Classify and extract services go in `checks` and combine freely: every one of them reads your input and leaves it alone. Transforms rewrite the input, so `transform` takes exactly one: `governance.pii.redact`, `governance.pii.tokenize`, `governance.pii.rehydrate`, or `data.date.normalize`. A transform listed under `checks` is rejected with `invalid_services` before anything runs.

The request names the transform in `transform` and the checks in `checks`, and the response mirrors it: the rewritten text arrives in `output`, its details in `transformed`, each verdict in `checked`. With no transform in the run, both are `null` and nothing is handed back.

A run that cleans and checks in one pass:

```
curl -X POST https://api.chersus.com/v1/run \
-H "Authorization: Bearer $CHERSUS_KEY" \
-H "Content-Type: application/json" \
-d '{
  "type": "text",
  "input": "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
  "transform": "governance.pii.redact",
  "checks": [
    "security.toxicity.flag",
    "routing.language.detect"
  ]
}'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
method: "POST",
headers: {
  Authorization: "Bearer " + process.env.CHERSUS_KEY,
  "Content-Type": "application/json",
},
body: JSON.stringify({
  type: "text",
  input: "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
  transform: "governance.pii.redact",
  checks: [
    "security.toxicity.flag",
    "routing.language.detect"
  ],
}),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
  "https://api.chersus.com/v1/run",
  headers={"Authorization": "Bearer " + os.environ["CHERSUS_KEY"]},
  json={
      "type": "text",
      "input": "Contact Jane Doe at jane.doe@example.com. Your service is garbage.",
      "transform": "governance.pii.redact",
      "checks": [
        "security.toxicity.flag",
        "routing.language.detect"
      ],
  },
)

data = res.json()
```

The three services read the same input: the redaction reports in `transformed`, the two checks in `checked`, and `usage.billed` still says 66 in, 58 out, 124 billed. The run took 11 ms, the slowest service, not the 23 ms the three would need one after another. Attach a fourth check and the bill does not move; the wait grows only if the new one is the slowest.

## The audit trace

Every response includes an audit trace, no flag needed. Per run: region, retention, timing. Per service: the version, the model, input and output sizes, SHA-256 hashes of the content, and the verdict or change count. The hashes let you prove a given text went through a given service with a given result, while Chersus stores no content at all.

## Billing

A run bills the characters you send plus the characters its transform hands back, once, whatever the number of checks. `usage.billed` shows the split: `input`, `output`, and their sum. A failed run hands nothing back, so it bills its input only; rejected requests and failures on our side bill nothing. The [pricing page](/en/pricing/) has the rate rule.

The free allowance works like everything else: the characters in your runs count toward the 1M monthly allowance. The [API reference](/en/docs/api-reference/) has the full request and response contract.