Agent monitoring
Agent monitoring runs heuristic anomaly detection over your agents' conversation behavior and produces alerts for quality and safety issues such as hallucinations, tool failure spikes, infinite loops, and unexpected refusals. Alerts are stored per workspace and can be listed, filtered, aggregated into dashboard stats, and acknowledged. You can also submit conversation content directly to run detection on demand.
All endpoints are scoped to the workspace of the authenticated caller. Authenticate with X-API-Key: pk_live_... or Authorization: Bearer <jwt-or-key>.
Alert fields
Every alert object returned by the API has the following fields:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Unique alert identifier |
user_id |
string (UUID) | User that owns the alert |
analysis_id |
string (UUID) | null | Linked analysis, if any |
alert_type |
string | Alert category (see table below) |
severity |
string | info, warning, or critical |
title |
string | Short alert title |
message |
string | Human-readable description of what was detected |
conversation_id |
string | null | Conversation the alert relates to |
agent_name |
string | null | Agent the alert relates to |
confidence_score |
number | null | Detector confidence (0–1) |
metadata_json |
object | null | Detector-specific details (e.g. turn index, tool name) |
acknowledged_at |
string (ISO 8601) | null | When the alert was acknowledged |
acknowledged_by |
string | null | Who acknowledged the alert |
created_at |
string (ISO 8601) | When the alert was created |
Alert types
alert_type |
Severity | Trigger |
|---|---|---|
hallucination |
critical |
Agent claims a policy exception not present in the knowledge base |
out_of_context |
warning |
Agent switches to product recommendations during an active return request |
tool_failure_spike |
critical |
3 or more consecutive tool call failures |
infinite_loop |
critical |
Identical response repeated 3 times in a row, or a repeating topic cycle |
context_loss |
warning |
Agent forgets the original user intent after a tool call |
unexpected_refusal |
warning |
Agent refuses a routine request (return, refund, help, question) |
confidence_drift |
warning |
Explicit confidence score below 0.70, or 3+ vague responses |
GET /v1/agent-monitoring/alerts
List agent monitoring alerts for the authenticated workspace, newest first.
Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
severity |
query | string | — | Filter by severity: info, warning, or critical |
alert_type |
query | string | — | Filter by alert type (see table above) |
acknowledged |
query | boolean | — | true = only acknowledged alerts, false = only unacknowledged |
limit |
query | integer | 50 |
Page size (1–200) |
offset |
query | integer | 0 |
Number of alerts to skip |
Response
{
"alerts": [
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"user_id": "3f6b0a2e-1c5d-4b8a-9e2f-5d7a9c1b3e4f",
"analysis_id": null,
"alert_type": "tool_failure_spike",
"severity": "critical",
"title": "Tool failure spike",
"message": "4 consecutive tool call failures for 'order_lookup' starting at turn 3.",
"conversation_id": "conv_123",
"agent_name": "support-agent",
"confidence_score": 0.92,
"metadata_json": {
"failure_count": 4,
"first_failure_turn": 2,
"tool_name": "order_lookup"
},
"acknowledged_at": null,
"acknowledged_by": null,
"created_at": "2026-08-18T14:32:10"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
curl "https://api.perceive8.com/v1/agent-monitoring/alerts?severity=critical&acknowledged=false&limit=20" \
-H "X-API-Key: pk_live_xxxxxxxxxxxx"
GET /v1/agent-monitoring/alerts/stats
Aggregate counts of unacknowledged alerts for the authenticated workspace, grouped by severity, plus a rolling 24-hour count.
Response
{
"critical": 2,
"warning": 5,
"info": 1,
"total": 8,
"recent_24h": 3
}
| Field | Type | Description |
|---|---|---|
critical |
integer | Unacknowledged critical alerts |
warning |
integer | Unacknowledged warning alerts |
info |
integer | Unacknowledged info alerts |
total |
integer | Sum of all unacknowledged alerts |
recent_24h |
integer | Unacknowledged alerts created in the last 24 hours |
POST /v1/agent-monitoring/alerts/{alert_id}/acknowledge
Mark a single alert as acknowledged. Returns 404 if the alert does not exist in the authenticated workspace, and 400 if alert_id is not a valid UUID.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
alert_id |
path | string (UUID) | The alert to acknowledge |
Response
{
"status": "acknowledged",
"alert_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
POST /v1/agent-monitoring/detect
Run all detectors against provided conversation content and persist any resulting alerts. Intended for testing and manually triggered playbooks.
The content field is parsed as JSONL: each non-empty line must be a JSON object representing one conversation turn (non-JSON lines are ignored). Detectors read these keys from each turn:
| Key | Used for |
|---|---|
response / content / text |
The agent's reply text (first present key wins) |
user / input / query |
The user's message text |
metadata.tool_status |
Tool call outcome; error, failed, 400, 429, or timeout count as failures |
metadata.tool_name |
Name of the failing tool |
metadata.tool_called |
Set to true when the turn included a tool call |
metadata.confidence |
Numeric confidence score; below 0.70 triggers confidence_drift |
Request body
{
"content": "{\"user\": \"I want to return my order\"}\n{\"response\": \"How can I help you today?\", \"metadata\": {\"tool_called\": true}}",
"analysis_id": null,
"conversation_id": "conv_123",
"agent_name": "support-agent"
}
| Field | Type | Required | Description |
|---|---|---|---|
content |
string | yes | Conversation turns as JSONL (one JSON object per line) |
analysis_id |
string (UUID) | null | no | Link generated alerts to an analysis; 400 if not a valid UUID |
conversation_id |
string | null | no | Stored on generated alerts for trace linking |
agent_name |
string | null | no | Stored on generated alerts for trace linking |
Returns 400 if content is empty. If no structured turns can be parsed, the response contains zero alerts.
Response
{
"alerts_generated": 1,
"alerts": [
{
"id": "9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"user_id": "3f6b0a2e-1c5d-4b8a-9e2f-5d7a9c1b3e4f",
"analysis_id": null,
"alert_type": "context_loss",
"severity": "warning",
"title": "Context loss",
"message": "Turn 2: Agent forgot the original return request after a tool call and restarted the conversation.",
"conversation_id": "conv_123",
"agent_name": "support-agent",
"confidence_score": 0.8,
"metadata_json": {
"turn_index": 1,
"original_intent": "return"
},
"acknowledged_at": null,
"acknowledged_by": null,
"created_at": "2026-08-19T06:15:00"
}
]
}
Newly created alerts are immediately visible via GET /v1/agent-monitoring/alerts and counted in the stats endpoint until acknowledged.