We are currently building something exciting and will be launching soon. Registration is temporarily closed. Launching soon — registration temporarily closed.

Concepts

Understanding Sentiqra signals

Every analysis returns a flat list of structured signals. Each signal is a piece of machine-readable evidence - not a verdict.

The anatomy of a signal

{
    "analyzer": "trust-safety",
    "code": "insult",
    "label": "Insult",
    "score": 0.99,
    "level": "label",
    "parent": "insults_derogation"
}
FieldMeaning
analyzerWhich analyzer produced the signal (e.g. trust-safety). A stable identifier.
codeThe stable, machine-readable identifier. Safe to use in policy logic - stable in spelling and in meaning (see signal versioning).
labelThe human-readable name. For display only - do not branch on it.
scoreSignal-match strength, 0.0–1.0 - see score semantics below. Precision depends on the output profile.
confidenceOptional. Present only in the reduced.v1 output profile - the band name whose representative value score then carries.
levelcategory (a broad mechanism) or label (specific evidence).
parentFor label-level signals, the code of the category it belongs to. Absent on category-level signals.

Category vs label

Category-level signals describe a broader mechanism; label-level signals provide more specific evidence nested under a category via parent.

{ "code": "insults_derogation", "level": "category", "score": 0.86 }
{ "code": "insult", "level": "label", "score": 0.99, "parent": "insults_derogation" }
{ "code": "belittling", "level": "label", "score": 0.99, "parent": "insults_derogation" }

Use the category for coarse routing and the labels for fine-grained policy.

What a score does - and does not - mean

A score expresses signal-match strength under a particular analyzer configuration. It is not a probability that the signal or a downstream action is correct. Validate action thresholds on representative labeled data.

  • •A high score means the text is a strong match for the signal under that analyzer configuration - not that acting on it is correct.
  • •Scores are not comparable across labels or analyzers unless you validate them on your own labeled traffic.
  • •Always validate action thresholds against representative labeled data and your policy.

Output profiles

Two versioned output profiles intentionally expose different score precision. A profile's field set and semantics never change in place - a different shape ships as a new profile name and version.

Output profileApplies toscoreconfidence
full.v1 All non-free entitlement tiers Continuous value in [0, 1] Absent
reduced.v1 Anonymous traffic (playgrounds, demos) and free-tier API keys Band's representative value (at most 5 signals) Present - band name

Under reduced.v1, confidence names the band and score carries that band's representative value:

confidenceReturned scoreBand boundary (public)
very_high 0.9 ≥ 0.85
high 0.7 0.65 – < 0.85
medium 0.5 0.45 – < 0.65
low 0.3 0.00 – < 0.45

Signal absence

A missing signal means the analyzer did not detect it above threshold - it does not prove the content is safe. Treat absence as "not detected," never as "cleared." Check meta.analyzers[].assessment to distinguish a completed no_signals run from an abstained run (validated off-domain rejection), and applicability/status for inputs that never executed at all (not_applicable: unsupported language or insufficient content). Full conditions table →

Multiple signals

One input can produce many signals across categories and analyzers. Consume the whole list - the combination is often the meaningful evidence.

Stable codes, reproducible output

Signal code values are stable identifiers - in spelling and in meaning. A code keeps its definition for its lifetime: a materially changed meaning is never silently loaded onto an existing code. It ships as a new code with its own introduction date, while the old code is marked deprecated with a named successor and a migration note, then retired once no supported configuration emits it. Retired records are never deleted, so historical integrations can always resolve what a code meant.

Combined with a pinned configuration and fingerprint, the same input always produces the same canonical signals under the same output profile - so your policy logic and audit trail stay valid over time.

Version streamWhat it pins
API contractRequest/response schema and field semantics (registry_version).
configurationThe deployed detection configuration per analyzer set - the sqcfg_* alias in every receipt, pinnable via detection_config.
taxonomy semanticsWhat each code means - per-analyzer taxonomy_version; every label's definition, exclusions, parent, introduction date, and deprecation status are recorded in the label registry.
your policyYour own mapping of codes to actions. Owned and versioned by you - we never migrate it.

Before moving a pin, run your own evaluation set against both configurations with sentiqra-compare.py (in the evaluation toolkit). It runs locally, reports added/removed signals and - with your policy map - changed downstream actions. A pinned integration is never silently migrated: a pin replays the pinned configuration or fails; the current configuration is never substituted.

See the full response contract →