# Classifier

The Classifier uses NLP and machine learning to evaluate a wide range of input signals in real time and returns a numeric score for how likely that input is legitimate vs. unwanted, so you can accept, flag, or block based on your own threshold.

## What it evaluates

- **Text content** — multi-layered NLP scoring (spam/abuse patterns, injection attempts, and more — see [rules](#text-classification-rules) below).
- **Email addresses** — disposable-domain detection, DMARC/MX checks, free-provider identification.
- **IP addresses** — hosting/datacenter detection, known-malicious blocklists, proxy/Tor detection.
- **Device/headers** — bot detection, missing standard headers.
- **Location** — high-risk country matching, "fast traveler" detection (comparing current location against a recent known one).
- Can also integrate [rate limiting](/docs/sentinel/features/rate-limiters/) and [Similarity & Training Data](/docs/sentinel/features/similarity-training-data/) matching in the same request.

Performance is around 10ms for a 10KB text payload.

## Classification bands

| Classification | Score |
|---|---|
| `GOOD` | below 1 |
| `NEUTRAL` | 1–2 |
| `BAD` | above 2 |

## Using the API

```
POST /v1/classifier
Authorization: Bearer {API_KEY}
```

Requires an API key on a Security Group with **Restricted** access — see [API Keys](/docs/sentinel/configure/api-keys/).

You can classify one or several of these in a single request:

**Text**

```json
{ "text": "Example text to classify" }
```

**Form fields**

```json
{
"fields": {
"email": "text@example.com",
"name": "John Doe",
"message": "Hello, I need help with checkout on your website."
}
}
```

**Email** (domain only is enough, and better for privacy)

```json
{ "email": "gmail.com" }
```

**IP address**

```json
{ "ip": "127.0.0.1" }
```

**Device** (from request headers)

```json
{
"headers": {
"Accept": "...",
"Accept-Language": "...",
"User-Agent": "..."
}
}
```

**Location, with fast-traveler detection**

```json
{
"ip": "127.0.0.1",
"timeZone": "Europe/London",
"lastKnownLocation": { "latitude": 51.5074, "longitude": -0.1278 }
}
```

**Rate limiting, in the same call**

```json
{
"rateLimit": { "customKey": "{USER_ID}", "limit": "10/1h", "memory": true }
}
```

**Similarity matching, in the same call**

```json
{
"similarity": [{ "groups": ["chat_spam"], "partial": true, "stopOnMatch": 0.7 }],
"text": "Example text to classify"
}
```

**Enabling/disabling specific rules per request**

```json
{
"text": "Example",
"disableRules": ["CAPITALIZATION"],
"enableRules": ["PROFANITY"]
}
```

### Response

```json
{
"classification": "NEUTRAL",
"score": 1,
"triggeredRules": ["SHORT_TEXT"],
"text": {
"classifier": "en",
"language": "en",
"score": 1,
"time": 11.93,
"rules": { "CAPITALIZATION": { "score": 0 }, "PROFANITY": { "score": 0 } },
"triggeredRules": ["SHORT_TEXT"]
},
"email": null,
"ip": null,
"location": null,
"device": null,
"similarity": null,
"rateLimit": null,
"timeZone": null
}
```

`score` above 2 typically indicates spam; `triggeredRules` lists which rules fired, sorted by contribution to the score.

## Text classification rules

| Rule | Detects |
|---|---|
| `CAPITALIZATION` | Excessive capitalization |
| `CURRENCY` | Currency symbols |
| `EMOJI` | Excessive emoji use |
| `EXCLAMATION` | Excessive exclamation marks |
| `HASH_TAGS` | Hashtags |
| `HTML` | HTML tags |
| `HTML_INJECTION` | HTML injection attempts |
| `NUMBERS_ONLY` | Text that's only numbers |
| `PROFANITY` | Profane language |
| `RANDOM_CHARS` | Random character sequences |
| `SHORT_TEXT` | Unusually brief messages |
| `SPAM_WORDS` | Known spam vocabulary |
| `SPECIAL_CHARS` | Excessive special characters |
| `SQL_INJECTION` | SQL injection patterns |
| `UNEXPECTED_LANGUAGE` | Language mismatch vs. context |
| `URL` | URLs — feeds [Phishing Detection](/docs/sentinel/features/phishing-detection/) via `URL_PHISHING` |

## Email, IP, location, and device rules

| Rule | Applies to | Detects |
|---|---|---|
| `DISPOSABLE` | Email | Disposable/temporary email services |
| `DMARC` | Email | Missing `_dmarc.` DNS record |
| `FREE_PROVIDER` | Email | Free provider (scores 0.5) vs. business domain (scores 0) |
| `MX` | Email | Missing MX record |
| `HOSTING` | IP | Datacenter/hosting IPs |
| `MALICIOUS` | IP | Known-malicious blocklist match |
| `PROXY` | IP | Proxy/VPN service |
| `TOR` | IP | Tor exit node |
| `HIGH_RISK_COUNTRY` | Location | Sanctioned/high-risk country |
| `LOCATION_DISTANCE` | Location | Current location vs. `lastKnownLocation` differs significantly (≥100km threshold; scores up to 5 at ~3,000km+) |
| `TIMEZONE_MISMATCH` | Location | Geolocation doesn't match the country implied by `timeZone` |
| `BOT` | Device | Bot/crawler/AI agent |
| `ACCEPT_HEADER_MISSING` | Device | Missing `Accept` header |
| `ACCEPT_LANGUAGE_HEADER_MISSING` | Device | Missing `Accept-Language` header |
| `USER_AGENT_HEADER_MISSING` | Device | Missing `User-Agent` header |

Toggle individual rules per Security Group with the `enableClassificationRules` / `disableClassificationRules` [rule fields](/docs/sentinel/configure/security-groups/#schema), or per-request with `enableRules`/`disableRules` as shown above.

## Setup

1. Finish installing Sentinel.
2. Configure an [IP Resolver](/docs/sentinel/integrations/ip-resolvers/) — IP classification depends on it.
3. Create an [API Key](/docs/sentinel/configure/api-keys/) on a Security Group with Restricted access.

## Language support

The Classifier's dedicated NLP rules are fully supported in 19 languages (including English, French, German, Spanish, Italian, and Portuguese); other languages fall back to English-based heuristics. This is separate from Sentinel's general [language detection](/docs/sentinel/features/detection-signals/), which recognizes 160+ languages regardless of classifier support.

## Best practices

- Submit multiple data points (text, email, IP, device) in a single request rather than separately — it reduces false positives, since the Classifier can cross-reference them.
- For privacy, send only the email **domain** (`gmail.com`) rather than the full address where you don't need the full address.
- Keep `lastKnownLocation` recent (within hours) for fast-traveler detection to be meaningful.
- Tune `enableRules`/`disableRules` per use case rather than accepting the full default set everywhere.

## Related

- [Forms](/docs/sentinel/configure/forms/) — attaching the Classifier to submitted fields.
- [Security Groups](/docs/sentinel/configure/security-groups/) — the `classifyFields`, `enableClassificationRules`, `disableClassificationRules` rule fields.
- [Phishing Detection](/docs/sentinel/features/phishing-detection/) — the `URL_PHISHING` rule this integrates with.
- [Similarity & Training Data](/docs/sentinel/features/similarity-training-data/)
- [Chat & Forum Moderation](/docs/sentinel/use-cases/chat-forum-moderation/) — a usage example.
