Messages
Append a turn to a session. Viora scores the conversation-through-this-turn synchronously and returns the result. Sub-second latency under normal load.
Append
POST /api/v1/sessions/{id}/messages
Authorization: Bearer vrk_...
Content-Type: application/json
{
"role": "user", // "user" | "assistant" | "system"
"content": "I haven't slept in days and everything feels pointless",
"sent_at": "2026-05-30T22:00:00Z" // optional, defaults to now
}
Response:
{
"message_id": 4521,
"ordinal": 3,
"prs": 0.72,
"scores": {
"self_harm": 0.04,
"suicidal_ideation": 0.28,
"anxiety": 0.55,
"depression": 0.72,
"substance_use": 0.01,
"eating_disorder": 0.0,
"trauma": 0.08,
"psychosis": 0.0,
"burnout": 0.41,
"crisis_severity": 0.39
},
"r_level": "R1-high",
"session_srs": 0.72,
"session_r_level": "R1-high",
"forced_by_imminence": false
}
How scoring works
Each turn produces:
scores— continuous [0,1] score per signal, from the production model.prs— per-turn risk score, max of the signal scores (lifted higher when structured imminence fields trigger).r_level— categorical bucket on PRS thresholds (R0 < 0.3, R1-mid < 0.6, R1-high < 0.8, R2).session_srs/session_r_level— peak/recency-weighted aggregation over all turns in this session, with sticky-floor (cannot auto-downgrade without explicit structured de-escalation evidence).forced_by_imminence— true when structured imminence fields (intent + plan + accessible means + near timeframe) forced the R-level to R2 regardless of the continuous score.
See the R-level guide for how to use these in your product.
Score-only vs reply
The Viora API is inbound-only. We never generate replies for you. You send us the turn, we score it, we hand back the verdict. Your product handles routing, replies, and any user-facing surface.