HushSafe API v1

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:

bash
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.

http
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.

POST/v1/moderate

Request body

FieldTypeDescription
text*stringText to moderate. Max 10,000 characters.
customer_idstring (UUID)Passed by gateway from auth context — do not set manually.
contextobjectOptional 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

json
{
  "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.

POST/v1/moderate/conversation

Supports up to 20 turns. Returns standard moderation output plus context_risk signals: secrecy patterns, age/minor references, sexualization escalation, and late-turn escalation.

json
{
  "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).

POST/v1/moderate/batch
json
{
  "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.

POST/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.

POST/v1/counterfactual/{request_id}
json
{ "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

FieldTypeDescription
request_id*stringUnique identifier for this moderation call. Format: req_{26 chars}.
decision*PASS | REVIEW | BLOCKFinal moderation decision. See Decisions section.
scores*objectPer-category confidence scores, 0.0–1.0.
explanation*stringPlain-English reason for the decision.
tier_reached*0 | 1 | 2 | 3Which inference tier produced the final decision.
latency_ms*numberEnd-to-end request latency in milliseconds.
model_version*stringModel artifact version used for this request.
languagestringDetected language code (ISO 639-1).
context_riskobjectConversation risk signals. Only present on /v1/moderate/conversation.
watermark*objectSigned audit watermark for DSA compliance.
policy_appliedstringPolicy 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).

hate

Content targeting race, ethnicity, religion, national origin, disability, sex, or sexual orientation with dehumanizing language.

harassment

Targeted abuse, personal attacks, threatening language directed at individuals or groups.

sexual

Explicit sexual content, nudity, solicitation. Stricter thresholds for minors/CSAM apply regardless of customer config.

self_harm

Content promoting, glorifying, or providing methods for self-injury or suicide. Routed to Tier 3 LLM for sensitive context.

violence

Depictions or incitement of physical violence, gore, or real-world threats.

spam

Unsolicited commercial content, phishing attempts, coordinated inauthentic behavior.

threat

Direct threats to physical safety, credible statements of intent to harm.

Decisions

PASS

All category scores are below your configured PASS thresholds. Safe to allow.

REVIEW

One or more scores are between PASS and BLOCK thresholds. Route to human review queue.

BLOCK

One or more scores exceed your configured BLOCK threshold. Do not allow.

Error Codes

FieldTypeDescription
401 UnauthorizedInvalid or missing API key, or key has been revoked.
400 Bad RequestMalformed request body, text exceeds 10,000 characters, or invalid category threshold.
429 Too Many RequestsRate limit exceeded. Check Retry-After header.
502 Bad GatewayInference service temporarily unavailable. Retry with exponential backoff.
503 Service UnavailableML models not loaded — service is starting up or degraded.

Rate Limits

PlanRequests/hourRequests/day
Free1,0001,000
Growth10,000100,000
Scale100,0001,000,000
EnterpriseCustomCustom

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/sdk

Python

pip install hushsafe

Both SDKs include TypeScript types, retry logic, and support for all API endpoints. Source code is available on GitHub.