# Routing services | Chersus

## Routing 4

```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "Guten Morgen, ich habe eine Frage zu meiner Rechnung."
    },
    "pipeline": [
      { "id": "detect", "service": "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({
    input: { type: "text", value: "Guten Morgen, ich habe eine Frage zu meiner Rechnung." },
    pipeline: [{ id: "detect", service: "routing.language.detect" }],
  }),
});

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

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
        "input": {"type": "text", "value": "Guten Morgen, ich habe eine Frage zu meiner Rechnung."},
        "pipeline": [{"id": "detect", "service": "routing.language.detect"}],
    },
)

data = res.json()
```
200 · 4ms · 53 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X5",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "Guten Morgen, ich habe eine Frage zu meiner Rechnung."
  },
  "results": {
    "detect": {
      "kind": "extract",
      "status": "ok",
      "data": { "language": "de", "confidence": 0.99 }
    }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 53, "steps": ["detect"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none", "total_ms": 4 }
}
```

The cheapest decision you can automate. Use `routing.language.detect` as the first hop of any multi-locale pipeline: detect the ISO language code, then route the payload to the right model, template, or human queue. Trust the text, not headers or user settings.

At under 5ms it is fast enough to run on every payload, including inside chains where a language switch should change how later steps behave. When workflows ship, a branch on `data.language` will route the payload without a second round trip.
KINDextractMODELpapluca/xlm-roberta-base-language-detectionLICENSEApache 2.0LANGUAGES20 languagesArabic, Bulgarian, German, Greek, English, Spanish, French, Hindi, Italian, Japanese, Dutch, Polish, Portuguese, Russian, Swahili, Thai, Turkish, Urdu, Vietnamese, ChineseREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "I want my money back, this arrived broken."
    },
    "pipeline": [
      {
        "id": "intent",
        "service": "routing.intent.map",
        "params": { "catalog": "support-v3" }
      }
    ]
  }'
```

```
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({
    input: { type: "text", value: "I want my money back, this arrived broken." },
    pipeline: [
      { id: "intent", service: "routing.intent.map", params: { catalog: "support-v3" } },
    ],
  }),
});

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

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
        "input": {"type": "text", "value": "I want my money back, this arrived broken."},
        "pipeline": [
            {"id": "intent", "service": "routing.intent.map", "params": {"catalog": "support-v3"}}
        ],
    },
)

data = res.json()
```
200 · 8ms · 42 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X6",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "I want my money back, this arrived broken."
  },
  "results": {
    "intent": {
      "kind": "extract",
      "status": "ok",
      "data": { "intent": "refund.request", "confidence": 0.91 }
    }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 42, "steps": ["intent"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none", "total_ms": 8 }
}
```

`routing.intent.map` turns free text into one of your own operational labels. Point it at a named intent catalog with `params.catalog`. The service maps each expression to the nearest catalog entry and attaches a confidence score, so downstream systems receive stable parameters instead of raw customer language.

Define catalogs as verbs on your domain: `refund.request`, `shipment.track`, `account.password_reset`. A low confidence score is a signal to fall back to a human queue, not to guess.
KINDextractMODELsentence-transformers/all-MiniLM-L6-v2LICENSEMITLANGUAGESEnglishREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "The invoice total does not match the amount taken from my card last month."
    },
    "pipeline": [
      {
        "id": "topic",
        "service": "routing.topic.classify",
        "params": {
          "topics": [
            "billing",
            "shipping",
            "account",
            "product feedback"
          ]
        }
      }
    ]
  }'
```

```
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({
    "input": {
      "type": "text",
      "value": "The invoice total does not match the amount taken from my card last month."
    },
    "pipeline": [
      {
        "id": "topic",
        "service": "routing.topic.classify",
        "params": {
          "topics": [
            "billing",
            "shipping",
            "account",
            "product feedback"
          ]
        }
      }
    ]
  }),
});

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

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
      "input": {
        "type": "text",
        "value": "The invoice total does not match the amount taken from my card last month."
      },
      "pipeline": [
        {
          "id": "topic",
          "service": "routing.topic.classify",
          "params": {
            "topics": [
              "billing",
              "shipping",
              "account",
              "product feedback"
            ]
          }
        }
      ]
    },
)

data = res.json()
```
200 · 74 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9XE",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "The invoice total does not match the amount taken from my card last month."
  },
  "results": {
    "topic": {
        "kind": "extract",
        "status": "ok",
        "data": {
          "topic": "billing",
          "confidence": 0.93
        }
      }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 74, "steps": ["topic"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none" }
}
```

`routing.topic.classify` sorts text into labels you supply at call time, with no training step. Pass the taxonomy in `params.topics` and change it whenever you like: the service scores the text against each label and returns the best one with a confidence.

That makes it the right tool when the label set is yours and still moving. When the label set is stable and you need an operational parameter rather than a topic, reach for `routing.intent.map` instead, which is faster and built for exactly that.

The model’s card states no supported languages, so this service declares none. Treat non-English input as untested rather than unsupported.
KINDextractMODELfacebook/bart-large-mnliLICENSEMITLANGUAGESNot statedREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "My card was charged twice for order 4821."
    },
    "pipeline": [
      {
        "id": "dupe",
        "service": "routing.duplicate.detect",
        "params": {
          "references": [
            "Order 4821 was billed to my card two times.",
            "Where is my delivery for order 5567?"
          ],
          "threshold": 0.8
        }
      }
    ]
  }'
```

```
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({
    "input": {
      "type": "text",
      "value": "My card was charged twice for order 4821."
    },
    "pipeline": [
      {
        "id": "dupe",
        "service": "routing.duplicate.detect",
        "params": {
          "references": [
            "Order 4821 was billed to my card two times.",
            "Where is my delivery for order 5567?"
          ],
          "threshold": 0.8
        }
      }
    ]
  }),
});

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

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
      "input": {
        "type": "text",
        "value": "My card was charged twice for order 4821."
      },
      "pipeline": [
        {
          "id": "dupe",
          "service": "routing.duplicate.detect",
          "params": {
            "references": [
              "Order 4821 was billed to my card two times.",
              "Where is my delivery for order 5567?"
            ],
            "threshold": 0.8
          }
        }
      ]
    },
)

data = res.json()
```
200 · 41 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9XF",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "My card was charged twice for order 4821."
  },
  "results": {
    "dupe": {
        "kind": "classify",
        "status": "ok",
        "verdict": "flag",
        "score": 0.91,
        "labels": [
          "near_duplicate"
        ]
      }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 41, "steps": ["dupe"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none" }
}
```

`routing.duplicate.detect` compares an incoming text against a reference set you pass in the call and returns the closest match as a similarity score. Use it to collapse repeat support tickets, to catch a resubmitted form, or to stop the same alert firing twice under slightly different wording.

The references travel with the request and are never stored, so the comparison set is yours to choose per call: the last hour of tickets, the open ones for that customer, whatever the decision needs. Set `params.threshold` to the similarity at which you want a `flag`, and treat the score as the thing to tune.
KINDclassifyMODELsentence-transformers/all-MiniLM-L6-v2LICENSEMITLANGUAGESEnglishREGION26 EU cities
## Start redacting in minutes.

Create an account, copy your key, make your first run before your coffee cools.
[Request access](/en/signup/)[Read the chaining guide](/en/docs/chaining/)