API Documentation
HushSafe is a tiered text moderation API. Submit text, get back a decision (PASS / REVIEW / BLOCK), per-category confidence scores, a plain-English explanation, and a signed audit watermark — all in under 10ms for 95% of requests.
Quickstart
Get a moderation decision in under 5 minutes. Create an account, get an API key from the dashboard, and send your first request:
curl -X POST https://api.hushsafe.com/v1/moderate \
-H "Authorization: Bearer hs_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"text": "Hello, world!"}'Authentication
All API requests require a Bearer token in the Authorization header. Keys begin with hs_live_ and are shown once at creation.
Authorization: Bearer hs_live_<your_key>Keys are HMAC-SHA256 hashed server-side. If a key is compromised, revoke it immediately from API Keys and generate a new one.
POST /v1/moderate
Moderate a single piece of text.
/v1/moderateRequest body
| Field | Type | Description |
|---|---|---|
text* | string | Text to moderate. Max 10,000 characters. |
customer_id | string (UUID) | Passed by gateway from auth context — do not set manually. |
context | object | Optional metadata (language hint, session_id) for routing decisions. |
Example request
curl -X POST https://api.hushsafe.com/v1/moderate \
-H "Authorization: Bearer hs_live_..." \
-H "Content-Type: application/json" \
-d '{"text": "I hate you so much"}'Example response
{
"request_id": "req_01HX4ZMQKP8J5N3TG7R2WBAC9D",
"decision": "BLOCK",
"scores": {
"hate": 0.92,
"harassment": 0.87,
"sexual": 0.03,
"self_harm": 0.01,
"violence": 0.08,
"spam": 0.04,
"threat": 0.44
},
"explanation": "High hate and harassment signals — contains dehumanizing language targeting a person.",
"tier_reached": 1,
"latency_ms": 7,
"model_version": "xlm-roberta-v2.1-onnx-int8",
"language": "en",
"watermark": {
"signed": true,
"algorithm": "HMAC-SHA256",
"dsa_compliant": true
}
}POST /v1/moderate/conversation
Moderate a multi-turn conversation with context-aware risk signals.
/v1/moderate/conversationSupports up to 20 turns. Returns standard moderation output plus context_risk signals: secrecy patterns, age/minor references, sexualization escalation, and late-turn escalation.
{
"turns": [
{ "role": "user", "text": "hey wanna hang out?" },
{ "role": "assistant", "text": "sure, where?" },
{ "role": "user", "text": "don't tell your parents, let's meet alone" }
]
}POST /v1/moderate/batch
Moderate up to 100 texts in a single request. Processed in parallel (max 10 concurrent).
/v1/moderate/batch{
"items": [
{ "id": "msg_1", "text": "Hello world" },
{ "id": "msg_2", "text": "I will hurt you" }
]
}POST /v1/replay/{request_id}
Re-run a retained request payload under the current model and policy. Useful for debugging threshold changes and policy DSL effects. Requires retention_days > 0 in config.
/v1/replay/{request_id}POST /v1/counterfactual/{request_id}
Returns a plain-English explanation of what would need to change for the decision to flip to a specified target decision.
/v1/counterfactual/{request_id}{ "target_decision": "PASS" }
// Response:
{
"current_decision": "BLOCK",
"target_decision": "PASS",
"explanation": "The harassment score (0.87) would need to drop below 0.35 (your PASS threshold). The phrase 'I hate you' accounts for most of this signal.",
"policy_band": "harassment"
}Response Schema
| Field | Type | Description |
|---|---|---|
request_id* | string | Unique identifier for this moderation call. Format: req_{26 chars}. |
decision* | PASS | REVIEW | BLOCK | Final moderation decision. See Decisions section. |
scores* | object | Per-category confidence scores, 0.0–1.0. |
explanation* | string | Plain-English reason for the decision. |
tier_reached* | 0 | 1 | 2 | 3 | Which inference tier produced the final decision. |
latency_ms* | number | End-to-end request latency in milliseconds. |
model_version* | string | Model artifact version used for this request. |
language | string | Detected language code (ISO 639-1). |
context_risk | object | Conversation risk signals. Only present on /v1/moderate/conversation. |
watermark* | object | Signed audit watermark for DSA compliance. |
policy_applied | string | Policy DSL version applied to this request, if any. |
7 Categories
All scores are returned for every request, regardless of which tier resolved it. Scores range from 0.0 (clean) to 1.0 (high confidence positive signal).
hateContent targeting race, ethnicity, religion, national origin, disability, sex, or sexual orientation with dehumanizing language.
harassmentTargeted abuse, personal attacks, threatening language directed at individuals or groups.
sexualExplicit sexual content, nudity, solicitation. Stricter thresholds for minors/CSAM apply regardless of customer config.
self_harmContent promoting, glorifying, or providing methods for self-injury or suicide. Routed to Tier 3 LLM for sensitive context.
violenceDepictions or incitement of physical violence, gore, or real-world threats.
spamUnsolicited commercial content, phishing attempts, coordinated inauthentic behavior.
threatDirect threats to physical safety, credible statements of intent to harm.
Decisions
All category scores are below your configured PASS thresholds. Safe to allow.
One or more scores are between PASS and BLOCK thresholds. Route to human review queue.
One or more scores exceed your configured BLOCK threshold. Do not allow.
Error Codes
| Field | Type | Description |
|---|---|---|
401 Unauthorized | Invalid or missing API key, or key has been revoked. | |
400 Bad Request | Malformed request body, text exceeds 10,000 characters, or invalid category threshold. | |
429 Too Many Requests | Rate limit exceeded. Check Retry-After header. | |
502 Bad Gateway | Inference service temporarily unavailable. Retry with exponential backoff. | |
503 Service Unavailable | ML models not loaded — service is starting up or degraded. |
Rate Limits
| Plan | Requests/hour | Requests/day |
|---|---|---|
| Free | 1,000 | 1,000 |
| Growth | 10,000 | 100,000 |
| Scale | 100,000 | 1,000,000 |
| Enterprise | Custom | Custom |
Rate limit status is returned in response headers: X-RateLimit-Remaining, X-RateLimit-Reset. When exceeded, HTTP 429 is returned with a Retry-After header.
SDKs
TypeScript / Node.js
npm install @hushsafe/sdkPython
pip install hushsafeBoth SDKs include TypeScript types, retry logic, and support for all API endpoints. Source code is available on GitHub.