ClevAgent

SDK Quickstart

Add agent monitoring in 2 lines of code. No config files.

1

Install the SDK

terminal
pip install clevagent
2

Add 2 Lines to Your Agent

your_agent.py
# Add these 2 lines at agent startup
import os, clevagent
clevagent.init(api_key=os.environ["CLEVAGENT_API_KEY"], agent="my-agent", endpoint="https://clevagent.io")
# That's it. ClevAgent now:
# - Pings heartbeat every 60s in a background thread
# - Detects if process dies → fires alert → restarts container
# - Tracks token costs if auto_cost=True (default)
# - Alerts on loop detection (on_loop="alert_only", default)
# → on_loop="stop" for immediate shutdown, on_loop=fn for graceful handler

Get your API key from Dashboard → Settings.

Tip: Use a consistent agent name. Typos create duplicate agents. Enable Strict Mode in project settings to block unregistered names.

Two levels of protection:

Liveness (default): clevagent.init() sends heartbeats automatically via background thread. Catches crashes, OOM kills, clean exits.

Work-progress (recommended): Call clevagent.ping() inside your main loop. Also catches zombie states, hung API calls, and logic deadlocks.

3

Watch the Dashboard

Go to clevagent.io/dashboard. Your agent will appear automatically on the first heartbeat. No manual registration needed.

New agents are created automatically via upsert on first ping — just give them a unique agent name.

init() Options

ParameterDefaultDescription
api_keyrequiredYour project API key (starts with cv_)
agentrequiredUnique agent name within your project
interval60Heartbeat interval in seconds (min based on your tier)
auto_costTrueAuto-capture token usage from OpenAI/Anthropic SDK calls
endpoint"https://clevagent.io"ClevAgent API base URL (override for self-hosted deployments)
on_loop"alert_only""alert_only" · "stop" · callable — action when loop is detected
on_cost_exceeded"alert_only""stop" · "alert_only" · callable — action when daily cost budget exceeded

Manual Cost Logging

If auto_cost doesn't work with your SDK version, log costs manually:

# Log cost after each LLM call
clevagent.log_cost(
tokens=1500,
cost_usd=0.045
)

Returns a dict with the same fields echoed back, plus ok: True on success or ok: False with an error key on failure. Raises no exceptions — safe to call from within your main loop.

Capability Matrix

What works automatically vs. what requires manual configuration:

FeatureAutoManualNot supported
Heartbeat✅ 2 lines
Cost tracking✅ OpenAI / Anthropiclog_cost() for others
Auto-restart✅ Docker (SDK or Runner)systemd/launchd/process (via Runner)K8s/supervisor (use native restart)
Loop detection

Heartbeat API (Direct)

You can also send heartbeats directly without the SDK:

MethodPathAuth
POST/api/v1/heartbeatX-API-Key header
POST/api/v1/heartbeat/batchX-API-Key header
GET/api/v1/statusX-API-Key header
# Request body
{
"agent": "my-agent",
"status": "ok", // "ok" | "warning" | "error"
"tokens_used": 1500,
"cost_usd": 0.045,
"tool_calls": 3,
"iteration_count": 42
}
# Success response (200)
{
"received": true,
"agent_id": 7,
"status": "healthy"
}
StatusMeaning
200 OKHeartbeat received
401Invalid or missing API key
422Validation error (missing required field)
429Rate limit exceeded — check Retry-After header

Error response bodies:

# 401 — invalid or missing API key
{
"detail": "Invalid or missing X-API-Key header"
}
# 422 — validation error (missing required field)
{
"detail": [
{
"loc": ["body", "agent"],
"msg": "field required",
"type": "missing"
}
]
}
# 429 — rate limit exceeded
{
"detail": "Rate limit exceeded. Retry after 12 seconds."
}

Rate limit: 200 req/min (Free) · 500 (Starter) · 1,000 (Pro) · 10,000 (Enterprise) per API key

Pagination (status endpoint): ?limit=N&offset=M — default 100, max 1000

GET /api/v1/status — returns status for all enabled agents in the project:

# Response (200)
{
"project": "my-project",
"agents": [
{
"name": "my-trading-bot",
"status": "healthy", // "healthy" | "degraded" | "dead" | "unknown"
"last_heartbeat_at": "2026-03-22T10:00:00Z",
"agent_type": "generic"
}
],
"summary": {
"total": 3,
"healthy": 2,
"degraded": 1,
"dead": 0
}
}

Notification Channels

Real-time alerts go to Telegram, Slack, or Discord. Email delivers periodic digest reports (weekly on Free, daily on Starter+).

Telegram (All plans — free)

Use your own bot — zero extra cost. Three steps:

  1. Create a bot — message @BotFather on Telegram, run /newbot, copy the token.
  2. Connect in Settings — Dashboard → Settings → Telegram Alerts. Paste the bot token + your Chat ID, click Send Test.
  3. Done — all real-time alerts (agent crash, loop, cost spike) go to Telegram.
Finding your Chat ID: Start a chat with your bot, then visit https://api.telegram.org/bot<TOKEN>/getUpdates — the chat.id field is your Chat ID.

Slack & Discord (Starter+)

  • Slack — Create an Incoming Webhook in Slack, paste it in Dashboard → Settings → Slack Webhook, click Send Test.
  • Discord — Create a webhook in your channel settings, paste it in Dashboard → Settings → Discord Webhook.

Email — Periodic digest reports (weekly on Free, daily on Starter+). Not real-time. Sent automatically to your account email.

Custom integrations (Enterprise) — Contact [email protected] for PagerDuty, Opsgenie, or other integrations.

Data Retention

PlanHistory
Free7 days
Starter30 days
Pro90 days
Enterprise1 year

Batch Heartbeat Guide

When managing many agents, send multiple heartbeats in a single request to reduce latency and API overhead.

# POST /api/v1/heartbeat/batch — send 10 agents at once
{
"heartbeats": [
{ "agent": "trading-bot-1", "status": "ok" },
{ "agent": "trading-bot-2", "status": "ok" },
// ... up to 100 agents per request
]
}

Max batch size: 100 agents per request

429 retry strategy: Exponential backoff — wait Retry-After seconds from the response header before retrying. Example: 1s → 2s → 4s → 8s.

Burst allowance: Up to 2× your rate limit is allowed momentarily (1-minute window). Sustained bursts beyond that return 429.

Runner — Zero-Code Monitoring

Monitor and auto-restart your agents without changing any code. Install the runner daemon alongside your agent.

1

Install the Runner

terminal
pip install clevagent-runner
2

Start Monitoring

terminal
export CLEVAGENT_API_KEY=cv_your_project_key
clevagent-runner start \
--watch docker:my-trading-bot

Get your API key from Dashboard → Settings → API Keys.

3

Watch Multiple Agents

terminal
clevagent-runner start \
--watch docker:my-trading-bot \
--watch docker:my-scraper \
--watch process:/var/run/my-classifier.pid

Add multiple --watch flags. Each target is monitored independently.

4

Check the Dashboard

Go to clevagent.io/dashboard. Your agents will appear automatically on the first heartbeat. No manual registration needed.

CLI Flags

FlagDefaultDescription
--api-keyrequiredProject API key (cv_xxx)
--watchrequiredTarget to monitor (type:name). Repeatable.
--endpointhttps://clevagent.ioClevAgent server URL
--heartbeat-interval30Seconds between heartbeats
--log-levelINFODEBUG / INFO / WARNING / ERROR

Supported Watch Types

TypeTargetExampleRestart method
dockerContainer namedocker:my-botdocker restart
systemdService namesystemd:my-agent.servicesystemctl restart
launchdService labellaunchd:com.me.agentlaunchctl kickstart
processPID file path (recommended) or process name substringprocess:/var/run/my-bot.pidPID file or substring matching via pgrep
Process mode supports two sub-modes. PID file (recommended): the runner reads the PID from the file and sends SIGTERM — precise and unambiguous. Process name substring: uses pgrep to find matching processes; if multiple match, the lowest PID (oldest process) is used.
--watch process:/var/run/my-bot.pid # PID file (recommended)
ℹ️ --watch process:my-bot-script.py # substring match via pgrep

Run as a Daemon (systemd)

/etc/systemd/system/clevagent-runner.service
[Unit]
Description=ClevAgent Runner
After=network.target docker.service
[Service]
EnvironmentFile=/etc/clevagent/env
ExecStart=/usr/local/bin/clevagent-runner start --watch docker:my-bot
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now clevagent-runner

Mode A vs Mode B

Mode A — Runner only

Zero code changes. Runner sends heartbeats on behalf of your agent.

Best for: Existing Docker/systemd services you don't want to modify.

Mode B — SDK + Runner

Add 2 lines of SDK code + run the Runner. SDK handles cost tracking and loop detection. Runner handles restarts.

Best for: Full monitoring with cost and loop alerts.

Kubernetes / Native

Use your native restart mechanisms — ClevAgent monitors the heartbeat and alerts you on downtime.

Kubernetes

# Add a liveness probe — K8s restarts if it fails.
# ClevAgent alerts you about the downtime window.
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 30

supervisor

# /etc/supervisor/conf.d/my-agent.conf
[program:my-agent]
command=python3 /opt/my-agent/agent.py
autorestart=true
startretries=3
# supervisor restarts the process; ClevAgent monitors heartbeat and alerts.

Auto-Action on Loop Detection

When ClevAgent detects a loop (repeated tool calls above threshold), the heartbeat response includes a warning field. The SDK reads this and takes action based on your on_loop setting.

on_loop valueBehavior
"alert_only" (default)Prints warning only — agent keeps running, you get the alert
"stop"Prints warning + calls os._exit(1) to stop the agent immediately
callableCalls your function — use this for custom safe shutdown (flush state, close positions, etc.)

Example: Trading bot with safe shutdown

import os, clevagent
# Define safe shutdown — runs before agent exits on loop detection
def safe_shutdown():
# Cancel open orders, flush state, log final position
cancel_all_orders()
log_final_position()
os._exit(1)
clevagent.init(
api_key=os.environ["CLEVAGENT_API_KEY"],
agent="my-trading-bot",
endpoint="https://clevagent.io",
on_loop=safe_shutdown, # call safe_shutdown() instead of hard exit
on_cost_exceeded="stop", # hard stop if daily cost limit hit
)
Note: Auto-action requires SDK 0.4.0+. Update with pip install --upgrade clevagent. The backend warning field is set by the Advanced loop detection engine (available on Starter, Pro, and Enterprise plans).

Loop Detection Thresholds

ClevAgent detects loops using three signals. Default thresholds work for most agents — adjust per-agent if your workload is legitimately intensive.

SignalDefault thresholdAdjustable?
Tool call rate10 calls/min✅ Dashboard · API
Repeated message5 identical messages✅ Dashboard · API
Token spike3× rolling average✅ Dashboard · API

To adjust, go to Dashboard → Agent Detail → Settings, or via API:

# PUT /api/agents/{id} — set per-agent thresholds
{
"max_tool_calls_per_minute": 50, // research agent calling web_search 30×/min
"max_identical_messages": 10,
"token_spike_multiplier": 5
}

Node.js / TypeScript SDK

Available

Full TypeScript types. Zero runtime dependencies. Works with any Node.js agent framework — Vercel AI SDK, LangChain.js, AutoGen, or plain HTTP agents.

npm install clevagent
your_agent.ts
import clevagent from 'clevagent';
 
clevagent.init({
apiKey: process.env.CLEVAGENT_API_KEY!,
agent: 'my-node-agent',
});
 
// Inside your work loop
clevagent.ping({ tokensUsed: result.usage.totalTokens });

init() Options

ParameterTypeDefaultDescription
apiKeystringrequiredProject API key (cv_xxx)
agentstringrequiredUnique agent name within your project
intervalnumber60Heartbeat interval in seconds
endpointstring"https://clevagent.io"API base URL (override for self-hosted)
onLoopstring | () => void"stop""stop" · "alert_only" · custom function — action when loop is detected
onCostExceededstring | () => void"alert_only""stop" · "alert_only" · custom function — action when daily cost budget exceeded
agentTypestringundefinedFramework identifier ("claude", "langchain", etc.)

ping() Options

ParameterTypeDefaultDescription
statusstring"ok""ok" · "warning" · "error" · "shutdown"
messagestringundefinedFree-text status message
tokensUsednumberundefinedToken count for this cycle
costUsdnumberundefinedCost in USD for this cycle
toolCallsnumberundefinedNumber of tool calls this cycle
iterationCountnumberundefinedCurrent iteration number
memoryMbnumberundefinedMemory usage in MB

Manual Logging Functions

Record costs, prompts, tool calls, and iterations explicitly when auto-tracking isn't available:

logging.ts
// Log cost after each LLM call
clevagent.logCost(1500, 0.045);
 
// Record prompt for loop detection
clevagent.logPrompt("Summarize the Q3 earnings report");
 
// Record tool call for drift analysis
clevagent.logToolCall("db_query", "SELECT * FROM orders");
 
// Log iteration count
clevagent.logIteration(42);
 
// Graceful shutdown (auto-called on SIGTERM/SIGINT)
await clevagent.shutdown();

Full Example

agent.ts
import clevagent from 'clevagent';
 
clevagent.init({
apiKey: process.env.CLEVAGENT_API_KEY!,
agent: 'my-node-agent',
onLoop: 'alert_only',
onCostExceeded: () => {
console.log('Cost limit reached, shutting down...');
process.exit(1);
},
});
 
// Inside your work loop
const result = await openai.chat.completions.create({ ... });
clevagent.ping({
tokensUsed: result.usage?.total_tokens,
costUsd: 0.003,
status: 'ok',
});

OpenTelemetry Export

Export ClevAgent metrics to Prometheus, Grafana, Datadog, or any OTLP-compatible backend.

# Enable in your project settings or via API:
POST /api/v1/projects/{id}/otel-config
{
"enabled": true,
"endpoint": "https://your-collector:4318",
"format": "otlp" // or "prometheus"
}

Exported metrics include: agent uptime, heartbeat latency, token cost per cycle, loop detection count, and auto-restart events.

Langfuse Integration

Receive Langfuse error traces and trigger auto-restart. Configure a Langfuse webhook to POST to ClevAgent when a trace has error status.

# Langfuse webhook endpoint:
POST /api/v1/webhooks/langfuse
Header: X-API-Key: cv_xxx
 
# Request body:
{
"agent_name": "my-agent",
"status": "error",
"message": "trace failed",
"trace_id": "abc-123" // optional
}

When status is "error", ClevAgent creates a langfuse_error event. If the matched agent has auto-restart enabled, a restart command is queued automatically.

In Langfuse, set the webhook URL to https://clevagent.io/api/v1/webhooks/langfuse and pass your project API key as the X-API-Key header.

Framework Integrations

Add ClevAgent to your existing agent framework in minutes.

CrewAI

Add heartbeat monitoring to your CrewAI crew. Each agent gets its own heartbeat.

import os, clevagent
from crewai import Agent, Task, Crew
 
# Initialize ClevAgent before creating your crew
clevagent.init(
api_key=os.environ["CLEVAGENT_API_KEY"],
agent="my-crewai-crew",
endpoint="https://clevagent.io"
)
 
# Your crew runs as normal — ClevAgent monitors in the background
crew = Crew(agents=[...], tasks=[...])
result = crew.kickoff()
 
# Optional: ping after each crew run for work-progress tracking
clevagent.ping(status="ok", message=f"Crew completed: {len(result)} tasks")

LangGraph

Monitor your LangGraph agent loops. Ping inside the graph node for work-progress tracking.

import os, clevagent
from langgraph.graph import StateGraph
 
clevagent.init(api_key=os.environ["CLEVAGENT_API_KEY"], agent="my-langgraph-agent")
 
def agent_node(state):
# Your agent logic here
result = llm.invoke(state["messages"])
# Ping after each node execution
clevagent.ping(tokens=result.usage.total_tokens)
return {"messages": [result]}

AutoGen

Add monitoring to your AutoGen multi-agent conversations.

import os, clevagent
from autogen import AssistantAgent, UserProxyAgent
 
clevagent.init(api_key=os.environ["CLEVAGENT_API_KEY"], agent="my-autogen-team")
 
assistant = AssistantAgent("assistant", llm_config=...)
user_proxy = UserProxyAgent("user_proxy")
 
# ClevAgent monitors the process automatically
# If the conversation hangs or loops, you get an alert
user_proxy.initiate_chat(assistant, message="Analyze this data...")

API Error Codes

All error responses follow this format:

{ "detail": "Error message" }
CodeDetailWhen
400Password must be at least 8 charactersRegistration with short password
400Invalid or expired tokenEmail verification with bad/used token
401Not authenticatedMissing or invalid session cookie / API key
401Invalid credentialsWrong email or password at login
402upgrade_requiredAction requires a higher tier (e.g. agent limit reached)
403Access deniedNo permission for this project/agent
403EMAIL_NOT_VERIFIEDLogin before email verification
403Requires editor/admin roleShared member lacks permission
404Agent/Project not foundInvalid ID or wrong project
409Email already registeredDuplicate registration attempt
422Unknown event / validation errorInvalid request body or unknown funnel event
429Rate limit exceededToo many requests (login attempts, heartbeats, funnel events)
502Failed to create checkout/portalStripe API error during billing operations
503Billing not configuredStripe keys missing on server

Full API schema: /api/docs (Swagger) or /api/redoc (ReDoc)

Questions? Email [email protected]