Metrics API
Query per-project activity metrics. Counts are derived from accepted non-heartbeat minute samples. No raw events are logged or stored.
Endpoint
GET /api/metrics?granularity={granularity}&range={range}&project={project}
Authentication
A server-issued Bearer token with read permission is required.
Authorization: Bearer <token>
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
granularity |
string | Yes | Aggregation unit: MIN, HOUR, DAY, WEEK (case-insensitive, converted to uppercase internally) |
range |
string | Yes | Query range: 1h, 3h, 6h, 12h, 24h, 7d, 14d, 30d |
project |
string | No | Filter by normalized project label (may match several accounts) |
sourceId |
string | No | Query one exact agent source owned by the caller |
Success (200)
All projects (project parameter omitted): each data point is returned separately per project. Multiple projects may share the same timestamp; the server only sorts by timestamp in ascending order and does not sum across projects.
{
"success": true,
"granularity": "HOUR",
"range": "24h",
"project": "all",
"data": [
{ "timestamp": "2026-02-01T09:00:00.000Z", "count": 45, "project": "vibemon" },
{ "timestamp": "2026-02-01T09:00:00.000Z", "count": 44, "project": "my-project" },
{ "timestamp": "2026-02-01T10:00:00.000Z", "count": 62, "project": "vibemon" }
]
}
A project filter can match several accounts. Every point keeps its project, sourceId, optional accountId, and display label; use sourceId to select one source.
{
"success": true,
"granularity": "HOUR",
"range": "24h",
"project": "my-project",
"data": [
{ "timestamp": "2026-02-01T09:00:00.000Z", "count": 45, "project": "my-project", "sourceId": "agent-work", "label": "my-project" },
{ "timestamp": "2026-02-01T10:00:00.000Z", "count": 62, "project": "my-project", "sourceId": "agent-work", "label": "my-project" }
]
}
Errors
| Status | Error | Description |
|---|---|---|
| 400 | Invalid granularity... |
Invalid granularity value |
| 400 | Invalid range... |
Invalid range value |
| 400 | project must be a string |
e.g. the project query parameter is specified multiple times and passed as an array |
| 401 | Invalid or expired API token | Missing, malformed, unknown, or revoked credential |
| 403 | Token requires read permission | Token lacks read scope |
| 429 | Request limit exceeded | Shared owner request budget exceeded |
| 405 | Method not allowed |
Method other than GET |
| 503 | Service temporarily unavailable | Storage failure; retry with backoff |
Examples
# Hourly over 24 hours
curl -X GET "https://vibemon.io/api/metrics?granularity=HOUR&range=24h" \
-H "Authorization: Bearer <issued-read-token>"
# Daily over 7 days for a specific project
curl -X GET "https://vibemon.io/api/metrics?granularity=DAY&range=7d&project=my-project" \
-H "Authorization: Bearer <issued-read-token>"
const params = new URLSearchParams({
granularity: 'HOUR',
range: '24h',
project: 'my-project',
});
const response = await fetch(`https://vibemon.io/api/metrics?${params}`, {
headers: { 'Authorization': 'Bearer <issued-read-token>' },
});
const { data } = await response.json();
Note: Only the last 24 hours are retained. Longer ranges remain accepted for compatibility but contain no older samples.
Related Documentation
- Status API - Sending status (the source event for metrics)
- Entity Definitions - Metric data model