Documentation

Quickstart

Get your AI agent sending events to Canary in under 60 seconds.

1. Register your agent

Your agent can self-register by calling the registration endpoint:

curl -X POST https://canary.bot/api/agents/register \
  -H "Content-Type: application/json" \
  -d '{"name": "My Agent", "platform": "custom"}'

Save the api_key from the response — you'll need it for all requests.

Self-hosting? Replace https://canary.bot with your deployment's base URL.

2. Send events

Send events to track your agent's activity:

curl -X POST https://canary.bot/api/ingest \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{ 
    "type": "tool_call",
    "session_id": "session_123",
    "payload": {
      "tool": "web_search",
      "input": "weather in NYC"
    }
  }'

3. Claim your agent

The registration response includes a claim_url. Open it in your browser and sign in with GitHub to link the agent to your account.

The same host replacement applies here if you run your own stack.

OpenClaw Integration

Canary has native support for OpenClaw agents. Just install the hook and you're done.

Automatic setup

Tell your OpenClaw agent to join Canary:

Read https://canary.bot/skill.md and follow the instructions

Manual setup

Run the install script:

curl -fsSL https://canary.bot/install | bash

This installs the Canary hook and configures your OpenClaw agent automatically.

Agent-First API

These endpoints are designed for agents to consume — not just humans. An agent can self-monitor, declare behavioral contracts, and receive alerts via webhook callback so it can autonomously decide to slow down, escalate, or abort without a human in the loop.

POST/api/agents/registerAgent-first

Register with behavioral contracts and an alert webhook so Canary can call back into the agent when something is wrong.

curl -X POST https://canary.bot/api/agents/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Prime Orbit",
    "platform": "openclaw",
    "alert_webhook": "https://my-agent.example.com/canary-alert",
    "contracts": {
      "max_daily_cost_usd": 2.00,
      "max_consecutive_errors": 3,
      "expected_tools": ["browser", "exec", "read", "write"],
      "heartbeat_interval_minutes": 30
    }
  }'

contracts declares the agent's own behavioral expectations. Canary monitors drift from them automatically and fires your alert_webhook when a contract is breached.

POST/api/agents/{id}/heartbeatAgent-first

Liveness ping. Call this periodically. Returns a health snapshot so the agent can check in AND self-assess in a single round-trip. If heartbeats stop, Canary marks the agent offline.

curl -X POST https://canary.bot/api/agents/AGENT_ID/heartbeat \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "current-session-id",
    "status_message": "processing task 3 of 10"
  }'

Response

{
  "status": "ok | warning | critical",
  "heartbeat_recorded_at": "ISO timestamp",
  "last_hour": {
    "events": 42,
    "cost_usd": 0.012,
    "error_count": 0,
    "error_rate": 0.0
  },
  "warnings": [],
  "next_heartbeat_in_minutes": 30
}
GET/api/agents/{id}/healthAgent-first

Full structured health assessment. The agent can call this and use recommended_action to autonomously decide whether to continue, reduce activity, or abort.

curl https://canary.bot/api/agents/AGENT_ID/health?period=1h \
  -H "X-API-Key: YOUR_API_KEY"

Response

{
  "health": {
    "score": 87,
    "status": "healthy | degraded | warning | critical",
    "recommended_action": "continue | reduce_activity | monitor_closely | abort_or_escalate",
    "deductions": [{ "reason": "...", "points": 5 }]
  },
  "metrics": {
    "total_cost_usd": 0.24,
    "error_rate": 2.1,
    "active_alerts": 0,
    "tool_usage": { "browser": 12, "exec": 4 }
  },
  "contracts": {
    "declared": { ... },
    "violations": [],
    "warnings": [],
    "compliant": true
  },
  "active_alerts": []
}
GET/api/agents/{id}/anomaliesAgent-first

Compares recent behavior against the agent's own historical baseline. Returns deviations in error rate, cost, event volume, and tool distribution.

curl "https://canary.bot/api/agents/AGENT_ID/anomalies?window=1h&baseline=7d" \
  -H "X-API-Key: YOUR_API_KEY"

Response

{
  "anomaly_count": 1,
  "anomalies": [{
    "type": "cost_rate_spike",
    "severity": "warning",
    "message": "Spend rate $0.042/hr vs baseline $0.008/hr",
    "current_value": 0.042,
    "baseline_value": 0.008,
    "deviation_pct": 425.0
  }],
  "summary": {
    "has_critical": false,
    "has_warnings": true
  }
}

Alert Webhook (Canary → Agent)

When an alert fires, Canary POSTs to your registered alert_webhook. The payload is machine-readable and includes a recommended_action the agent can act on directly.

// Incoming POST to your agent's alert_webhook URL:
{
  "canary_event": "alert",
  "schema_version": "1",
  "alert": {
    "id": "...",
    "type": "cost_spike",
    "severity": "warning",
    "message": "Unusual cost: $4.20 (avg: $0.12)",
    "triggered_at": "2025-03-27T14:00:00Z"
  },
  "agent": { "id": "...", "name": "Prime Orbit", "platform": "openclaw" },
  "recommended_action": "reduce_verbosity"
  // abort_session | reduce_verbosity | retry_with_backoff |
  // pause_and_retry | surface_to_human | log_and_continue
}

API Reference

POST/api/agents/register

Register a new agent (no auth required)

Request body

{
  "name": "string (required)",
  "platform": "openclaw | claude-code | custom",
  "description": "string (optional)",
  "alert_webhook": "https://... (optional, POST alerts back to agent)",
  "contracts": {
    "max_daily_cost_usd": number,
    "max_consecutive_errors": number,
    "expected_tools": ["browser", "exec", ...],
    "heartbeat_interval_minutes": number
  }
}
POST/api/ingest

Send events (requires API key)

Headers

X-API-Key: your_api_key

Request body

{
  "type": "tool_start | tool_result | message_in | message_out | error | cost",
  "session_id": "string (optional)",
  "payload": {
    "tool": "string (for tool events)",
    "tool_call_id": "string (links start/result)",
    "input": "any",
    "output": "any",
    "status": "success | error | timeout",
    "tokens_in": "number",
    "tokens_out": "number",
    "model": "string",
    "cost_usd": "number",
    "duration_ms": "number (auto-calculated)",
    "error": "string (for errors)"
  }
}
GET/api/events

Retrieve events (requires auth or API key)

Query parameters

agent_id: Filter by agent
session_id: Filter by session
type: Filter by event type
since: ISO timestamp
limit: Max results (default 100)
GET/api/stats

Get aggregated statistics

Query parameters

agent_id: Filter by agent
period: 24h | 7d | 30d
GET/api/agents/me

Agent self-query: check your own stats (requires API key)

Query parameters

period: 1h | 24h | 7d | 30d (default: 24h)

Response

{
  "agent": { "id", "name", "status" },
  "stats": {
    "total_events", "total_cost", "tokens_in",
    "tokens_out", "error_rate", "session_count"
  },
  "plan": {
    "events_this_month", "events_limit",
    "events_remaining", "events_percentage"
  },
  "alerts": ["warnings if any"]
}
GET/api/events?format=csv

Export events as CSV (requires auth or API key)

Query parameters

format: json (default) | csv
agent_id: Filter by agent
session_id: Filter by session
since: ISO timestamp
limit: Max results (default 10000 for CSV)
GET/api/sessions/{id}

Get detailed session replay data (requires auth)

Response

{
  "session": {
    "id", "agent_name", "started_at", "ended_at",
    "duration_formatted", "child_sessions"
  },
  "stats": {
    "total_events", "total_cost", "tokens_total",
    "tool_calls", "unique_tools", "messages", "errors"
  },
  "events": [...],
  "conversation": [...]  // Simplified chat view
}

Event Types

▶️

tool_start

When your agent begins using a tool. Include tool_call_id to correlate with result.

tool_result

When a tool completes. Duration auto-calculated if tool_call_id matches a tool_start.

tool_call

Legacy: single event for tool start+result combined. Still supported.

📨

message_in

Messages received by your agent

📤

message_out

Messages sent by your agent

error

Errors and exceptions

💰

cost

API cost events (tokens, model usage)

Alerts

Canary automatically detects anomalies and sends alerts. Available on Pro and Team plans.

Error Rate Alerts

Triggered when error rate exceeds 10% over a 5-minute window.

Cost Spike Alerts

Triggered when a single event costs more than $1.00.

Notification Channels

Alerts can be sent to Discord webhooks or email. Configure in your environment variables.

Rate Limits & Plans

LimitFreeProTeam
Agents2UnlimitedUnlimited
Events per month50K200K500K
Data retention7 days30 days90 days
Team members2UnlimitedUnlimited
Alerts
API access

Ready to get started?

Start monitoring your AI agents in under a minute.

Register Your Agent →