Access provider status, incidents, and historical data programmatically.
Three endpoints need no API key. They are rate limited to 120 requests/minute per IP and built for pipelines and failover rules.
The verdict is the HTTP status code: 200 when
every requested service is healthy, 503
otherwise, so curl -f is the entire
integration. Gate several services with
?services=claude,openai, and loosen the
policy with ?allow=degraded (comma-separated
status levels to accept besides
operational). Unknown service ids return
404 and an allow value that is
not a status level returns 400, so a typo
fails your pipeline loudly instead of silently passing.
# exits non-zero unless Claude is operational
curl -fsS https://canivibe.ai/api/healthy/claude
# gate on several providers, tolerating degraded performance
curl -fsS "https://canivibe.ai/api/healthy?services=claude,openai&allow=degraded"
The JSON body carries the per-service verdicts:
{
"healthy": false,
"checked_at": "2026-07-07T12:00:00Z",
"services": [
{ "id": "claude", "status": "degraded", "healthy": false,
"status_since": "2026-07-07T05:41:12Z" },
{ "id": "openai", "status": "operational", "healthy": true }
]
}
{
"id": "claude",
"name": "Claude (Anthropic)",
"status": "degraded",
"description": "Claude Code (degraded_performance)",
"status_since": "2026-07-07T05:41:12Z",
"last_checked": "2026-07-07T11:59:40Z"
}
Everything above in one document, plus
overall_status. Cached for 30 seconds; CORS
enabled (Access-Control-Allow-Origin: *).
Status levels are operational,
degraded, partial_outage,
major_outage, maintenance and
unknown.
All API requests require authentication using an API key. API keys are available to Pro and Enterprise subscribers. You can create and manage your API keys from the dashboard.
Include your API key using one of these two methods:
Authorization Header (recommended):
Authorization: Bearer civ_your_api_key_here
The "Bearer " prefix is required per RFC 6750.
X-API-Key Header:
X-API-Key: civ_your_api_key_here
Rate limit headers are included in all responses:
Base URL: https://canivibe.com/api/v1
List all tracked AI providers with their current status.
{
"providers": [
{
"id": "claude",
"name": "Claude (Anthropic)",
"status": "operational",
"last_checked": "2025-01-15T10:30:00Z"
},
{
"id": "openai",
"name": "OpenAI",
"status": "operational",
"last_checked": "2025-01-15T10:30:00Z"
}
]
}
Get current status for all or specific providers.
| Parameter | Description |
|---|---|
| provider optional |
Filter by provider ID. Comma-separated for
multiple providers; surrounding spaces are
ignored. An unrecognised ID returns 404
unknown_provider rather than an
empty result — see
GET /api/v1/providers for the
full ID list.
|
GET /api/v1/status?provider=claude,openai
{
"overall": "operational",
"providers": [
{
"id": "claude",
"name": "Claude (Anthropic)",
"status": "operational",
"description": "All systems operational",
"last_checked": "2025-01-15T10:30:00Z"
}
],
"timestamp": "2025-01-15T10:30:00Z"
}
Get historical incidents within a date range.
| Parameter | Description |
|---|---|
| provider optional |
Filter by provider ID. Comma-separated for
multiple providers; an unrecognised ID returns
404 unknown_provider.
|
| start optional | Start date (YYYY-MM-DD). Defaults to 30 days ago. |
| end optional | End date (YYYY-MM-DD). Defaults to today. |
{
"incidents": [
{
"id": "inc_123",
"provider_id": "claude",
"provider_name": "Claude (Anthropic)",
"title": "API Performance Degradation",
"status": "resolved",
"impact": "minor",
"started_at": "2025-01-10T14:00:00Z",
"resolved_at": "2025-01-10T16:30:00Z"
}
],
"query": {
"start": "2024-12-16",
"end": "2025-01-15",
"provider": null
}
}
Get daily status history for providers.
| Parameter | Description |
|---|---|
| provider optional |
Filter by provider ID. Comma-separated for
multiple providers; an unrecognised ID returns
404 unknown_provider.
|
| days optional | Number of days of history (1-90). Defaults to 30. |
{
"history": [
{
"provider_id": "claude",
"provider_name": "Claude (Anthropic)",
"days": [
{"date": "2025-01-15", "status": "operational"},
{"date": "2025-01-14", "status": "degraded"},
{"date": "2025-01-13", "status": "operational"}
]
}
],
"query": {
"days": 30,
"provider": null
}
}
Every webhook delivery is signed so you can verify the
payload really came from canivibe. When you add a webhook
you receive a signing secret (prefixed
whsec_) exactly once — store it like a
password; it is never shown again. Webhooks created
before signatures shipped have no secret: delete and
re-add them to get one.
Deliveries carry a signature header in the following
form, where t is the unix timestamp at
sending time and v1 is a hex-encoded
HMAC-SHA256:
X-Canivibe-Signature: t=1756000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
1. Split the header on , and read the
t and v1 values.
2. Concatenate the timestamp string, a literal
., and the raw (unparsed) request body.
3. Compute HMAC-SHA256 over that string with your
whsec_... secret as the key.
4. Compare the hex digest to v1 with a
constant-time comparison.
5. Reject deliveries whose timestamp is older than a few
minutes — the signed timestamp is what makes replayed
deliveries detectable.
# Python
import hmac, hashlib, time
def verify(header, body_bytes, secret):
parts = dict(p.split("=", 1) for p in header.split(","))
signed = parts["t"].encode() + b"." + body_bytes
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
fresh = abs(time.time() - int(parts["t"])) < 300
return fresh and hmac.compare_digest(expected, parts["v1"])
Slack and Discord webhooks are signed too, but those platforms ignore the header; verification only applies to generic endpoints you host yourself.
The API returns standard HTTP status codes and JSON error responses.
{
"error": "Unauthorized",
"code": "invalid_api_key",
"message": "Invalid or expired API key"
}
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad request (invalid parameters) |
| 401 | Unauthorized (missing or invalid API key) |
| 403 | Forbidden (valid key but insufficient subscription) |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
| Code | Description |
|---|---|
| missing_api_key | No API key provided in the request |
| invalid_api_key | API key is invalid or has been revoked |
| subscription_required | API access requires a Pro or Enterprise subscription |
| rate_limit_exceeded | Too many requests, try again later |