POST

/v1/analyze

Analyze a message and return its behavioral annotation plus a routing recommendation. Pass a conversation id to correlate it with earlier messages.

Request body

  • message (string, required) — the text to analyze. text is accepted as a compatibility alias.
  • conversation_id (string, optional) — your reference id. Supplying it correlates this message with earlier messages sharing the same id.
  • speaker (string, optional)customer (default) or agent. Send agent replies too if you want false-resolution detection.
  • metadata (object, optional) — passthrough metadata.
JSON
{
  "message": "Cancel my account immediately. Your bot is completely useless.",
  "conversation_id": "conv_123"
}

Response

JSON
{
  "status": "ok",
  "session_id": "…",
  "framework": "E-Model v2.0 (EVOKE → EXPRESS → ELEVATE)",
  "latency_ms": 1,
  "annotation": {
    "emotional_valence": "negative",
    "cognitive_load": "low",
    "urgency_level": "high",
    "engagement_state": "disengaged",
    "social_register": "informal",
    "cultural_context": ["global"]
  },
  "signal_confidence": 0.68,
  "signals_fired": 4,
  "routing": {
    "response_posture": "GENTLE_REFRAME",
    "recommended_tone": "soft_warm",
    "suggested_action": "reframe_positively"
  },
  "_meta": { "tenant_remaining": 4999, "overage": false, "gateway_latency_ms": 3 }
}

Conversation context

Send each message as it happens, with the same conversation_id. Nothing else changes: the request and response keep the shape above. Once there is history to compare against, the response gains a conversation block with findings a single message cannot carry.

Send the agent's replies too, with "speaker": "agent". Detecting a false resolution requires both what was claimed and how the customer reacted.

JSON
{
  "conversation_id": "conv_456",
  "speaker": "customer",
  "message": "It is not resolved, I still have nothing."
}

The added block:

JSON
"conversation": {
  "conversation_id": "conv_456",
  "storage_mode": "full",
  "prior_turns": 2,
  "failure_flags": {
    "false_resolution": true,
    "false_resolution_reason": "The agent stated \"is resolved\" without supporting evidence, but the customer's following message still signals an unresolved problem.",
    "repeat_contact_risk": false
  },
  "derived": {
    "repetition": false,
    "repetition_similarity": 0.12,
    "escalating": true,
    "peak_severity": 4
  },
  "recommendation": {
    "action": "handoff",
    "reason": "The case was presented as resolved while the customer remains unresolved.",
    "safe_response_guidance": "Acknowledge the problem, confirm the case is being passed to a person, and do not claim it is resolved."
  },
  "review_status": "needs_review"
}
  • false_resolution — the agent presented the issue as settled while the customer still signals it is not.
  • repetition — the customer re-asked, so the previous answer did not land.
  • escalating — the conversation is deteriorating rather than merely negative.
  • action — one of clarify, simplify, resolve, route or handoff.

The full message is retained so a conversation can be read back as it happened. If redaction is enabled for your environment or plan, the redacted form is stored instead and the response reports storage_mode as redacted. Either way, what was stored is exactly what was analyzed. If context cannot be built the block is marked degraded and recommends handoff. It will never report a problem as resolved.

cURL

Shell
curl -X POST https://api.bactlabs.africa/v1/analyze \
  -H "Authorization: Bearer sk_bact_your_key" \
  -H "Content-Type: application/json" \
  -d '{"message": "Cancel my account. Your bot is useless."}'

TypeScript

TypeScript
const res = await fetch("https://api.bactlabs.africa/v1/analyze", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BACT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ message }),
});
const { annotation, routing } = await res.json();

Live

Try it with your key

Paste an sk_bact_ key and send a message to see a live behavioral annotation.