Get Project Metrics
Scope: this page documents metrics and logs from the running application. GitHub build logs use separate endpoints in GitHub Builds.
Returns the usage metrics of the project (CPU, memory, etc.).
Required permissions
Use project.metrics.read on project:<project-id> for metrics, capabilities, storage usage, and network analytics. Use project.logs.read on the same project for application logs and builds. owner has full access; assistant, member, and organization API Keys need the corresponding scope.
GET /v1/project/:id/metricsRate limit: 100 requests per minute (counted per source IP).
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Project ID |
Headers
| Header | Required | Description |
|---|---|---|
x-api-key or Authorization | Yes | Organization API Key or user token |
x-organization-id | With a user token | Active project organization. Not needed with an organization API key |
Query Parameters (optional)
| Parameter | Type | Description |
|---|---|---|
instance | string | Specific instance identifier. When omitted, HTTP projects return aggregated network metrics and PostgreSQL and MariaDB projects return a list with one snapshot per instance. Required for Analytics, Key-Value, Cache, and Queue projects. |
Response
The uptime field represents the current uptime of the instance returned by the metrics endpoint. It should not be interpreted as application uptime, SLA, or public availability history.
{
"status": "success",
"message": "get metrics with success",
"data": {
"type": "application",
"aggregate": true,
"network": {
"requests": 1200,
"bytes_received": 420000,
"bytes_sent": 1800000,
"status_codes": {
"200": 1160,
"500": 5
},
"user_agents": {
"Mozilla/5.0": 900,
"curl/8.0": 300
},
"window_seconds": 300
}
}
}Native metrics for Valkey projects
Valkey projects use the same metrics route with the instance parameter, but return a sanitized native snapshot. Check the project's capabilities before requesting it.
Check capabilities
GET /v1/project/:id/metrics/capabilitiesFor tiers with snapshot access, data returns the available groups, the refresh interval, and the absence of historical data:
{
"data": {
"access": "snapshot",
"groups": [
"resources",
"capacity",
"clients",
"activity",
"key_lifecycle",
"profile",
"reliability"
],
"refresh_seconds": 60,
"history": null
}
}The Premium and Enterprise Key-Value, Cache, and Queue plans (db-premium, db-enterprise, cache-premium, cache-enterprise, queue-premium, and queue-enterprise) provide snapshots. When access is none, do not request the snapshot; the Console shows observability as unavailable.
Request a snapshot
GET /v1/project/:id/metrics?instance=instance-1The metrics object in data has the following shape. The top-level cpu and memory fields are legacy resource fields; native data is under valkey.
{
"data": {
"instance": "instance-1",
"type": "valkey",
"cpu": 0.25,
"memory": 134217728,
"observed_at": "2026-08-28T12:00:00.000Z",
"availability": "available",
"valkey": {
"schema_version": 1,
"profile": "cache",
"availability": "available",
"memory": {
"used_bytes": 104857600,
"peak_bytes": 125829120,
"limit_bytes": 536870912,
"fragmentation_ratio": 1.02
},
"clients": {
"connected": 12,
"blocked": 0
},
"activity": {
"operations_per_second": 240,
"input_bytes_per_second": 1048576,
"output_bytes_per_second": 2097152
},
"keys": {
"expired_total": 120,
"evicted_total": 3
},
"uptime_seconds": 86400,
"cache": {
"hits_total": 3900,
"misses_total": 100,
"hit_ratio": 0.975
},
"reliability": {
"replication": {
"status": "not_applicable",
"replicas_available": null,
"replicas_expected": 1,
"lag_seconds": null
},
"persistence": {
"enabled": true,
"status": "healthy",
"last_success_at": "2026-08-28T11:59:55.000Z"
}
}
}
}
}The optional cache and key_value fields depend on the project profile:
cache:hits_total,misses_total, andhit_ratio;key_value:keys_totalandkeys_with_expiration.
Snapshot availability can be available, partial, stale, or unavailable. Fields without sufficient evidence return null; the API does not replace them with fabricated values.
When no valid snapshot exists, the response keeps the public metadata and returns valkey: null:
{
"data": {
"instance": "instance-1",
"type": "valkey",
"cpu": 0,
"memory": 0,
"observed_at": null,
"availability": "unavailable",
"valkey": null
}
}This capability does not provide historical data (history: null). Queue-specific metrics such as queue depth, item age, or consumer lag are not part of the verified snapshot.
Native PostgreSQL and MariaDB metrics
PostgreSQL and MariaDB projects on the db-premium and db-enterprise plans use the same stable endpoints. Without instance, the route returns a list with one snapshot per instance. Check capabilities before requesting an instance snapshot:
GET /v1/project/:id/metrics/capabilities
GET /v1/project/:id/metrics?instance=instance-1Capabilities report access, available groups, and refresh interval. history: null means the capability provides only the latest snapshot, with no time-series retention or historical charts.
{
"data": {
"access": "snapshot",
"groups": [
"resources",
"connections",
"activity",
"cache",
"storage",
"locks",
"latency",
"reliability"
],
"refresh_seconds": 60,
"history": null
}
}Snapshot envelope
The response preserves the existing route and returns a versioned envelope for each instance. This PostgreSQL example contains representative values; conditional fields may be null.
{
"status": "success",
"data": {
"schema_version": 1,
"project_id": "507f1f77bcf86cd799439011",
"instance": "instance-1",
"type": "postgresql",
"observed_at": "2026-08-29T12:00:00.000Z",
"collected_at": "2026-08-29T12:00:01.000Z",
"availability": "available",
"resource": {
"cpu_usage_cores": 0.42,
"memory_usage_bytes": 268435456,
"storage_used_bytes": 2147483648,
"storage_capacity_bytes": 10737418240
},
"native": {
"connections": {
"current": 12,
"max": 100,
"utilization_ratio": 0.12,
"active": 3,
"idle": 9
},
"activity": {
"commits_total": 24000,
"rollbacks_total": 120,
"transactions_per_second": 18.5,
"rows_returned_total": 980000,
"rows_fetched_total": 310000,
"rows_written_total": 42000,
"temp_files_total": 7,
"temp_bytes_total": 1048576
},
"cache": {
"buffer_hits_total": 950000,
"buffer_reads_total": 50000,
"hit_ratio": 0.95
},
"storage": {
"database_size_bytes": 1610612736
},
"locks": {
"waiting_total": 1,
"deadlocks_total": 2
},
"latency": {
"average_query_latency_ms": null,
"slow_queries_total": null
},
"reliability": {
"up": true,
"uptime_seconds": 86400,
"wal_bytes_total": 734003200,
"wal_bytes_per_second": 32768,
"checkpoints_total": 36,
"checkpoint_buffers_total": 4200,
"role": "primary",
"replicas_available": 1,
"replicas_expected": 1,
"lag_seconds": 0.4,
"lag_bytes": 4096
}
}
}
}schema_versionidentifies the envelope version.typedistinguishespostgresqlfrommariadb; each project receives only its engine's groups.observed_atis when values were observed on the instance.collected_atis when the snapshot became available for retrieval.resourcecontains CPU in cores and memory/storage in bytes.nativecontains only product fields defined for the engine.
PostgreSQL fields
| Group | Fields |
|---|---|
| Connections | current, max, utilization_ratio, active, idle |
| Activity and transactions | commits_total, rollbacks_total, transactions_per_second, rows_returned_total, rows_fetched_total, rows_written_total, temp_files_total, temp_bytes_total |
| Read cache | buffer_hits_total, buffer_reads_total, hit_ratio |
| Storage | database_size_bytes |
| Locks | waiting_total, deadlocks_total |
| Latency | average_query_latency_ms, slow_queries_total, when available |
| Health, WAL, and checkpoints | up, uptime_seconds, wal_bytes_total, wal_bytes_per_second, checkpoints_total, checkpoint_buffers_total |
| Replication | role, replicas_available, replicas_expected, lag_seconds, lag_bytes |
MariaDB fields
| Group | Fields |
|---|---|
| Connections and threads | current, max, utilization_ratio, threads_connected, threads_running, aborted_connects_total |
| Activity | queries_total, questions_total, queries_per_second, bytes_received_per_second, bytes_sent_per_second, slow_queries_total |
| Read cache | buffer_pool_size_bytes, buffer_pool_data_bytes, buffer_pool_free_bytes, buffer_pool_dirty_pages, buffer_pool_reads_total, buffer_pool_read_requests_total, hit_ratio |
| Redo and I/O | log_writes_total, log_waits_total, fsyncs_total, io_per_second, when available |
| Storage | database_size_bytes |
| Locks | row_lock_waits_total, row_lock_time_ms_total, current_waits, deadlocks_total |
| Latency | average_query_latency_ms, when available |
| Health | up, uptime_seconds |
| Replication | status, replicas_available, replicas_expected, lag_seconds |
For MariaDB, threads_connected represents open sessions; threads_running represents threads doing work at sample time. The fields are not equivalent.
Counters, rates, ratios, and units
_totalfields are cumulative counters since the last restart or reset._per_secondfields are rates calculated between two valid samples.- After a reset, the related rate returns
nulluntil a new valid baseline exists; it never returns a negative value. _ratiofields are fractions from0to1.- Bytes are integers; latency uses milliseconds; lag uses seconds or bytes as indicated by the field name; CPU uses cores.
- Read cache is the engine's internal cache and does not represent the operating system cache.
Availability and nullable fields
availability can be:
available: the sample completed;partial: only some groups or fields were obtained;stale: a previous valid sample is returned with its original timestamps;unavailable: no valid sample can be presented.
A missing, unsupported, or uncomputable field returns null, never a synthetic zero. The snapshot presents aggregate values and does not include query text or parameters.
Native Analytics metrics
Analytics projects on the analytics-starter, analytics-production, and analytics-enterprise plans also provide a snapshot through the same routes, with the resources, connections, activity, storage, and reliability groups, refreshed every 60 seconds and without history. The instance parameter is required; use the values from GET /v1/project/:id/instances. On analytics-sandbox, access is none and the metrics route responds 402.
Get Project Logs
Returns the logs of the running project.
GET /v1/project/:id/logsAvailable on every plan. Requires project.logs.read. Rate limit: 200 requests per minute (counted per source IP). Only HTTP applications have logs through this route; other project types respond 400. For scheduled Jobs, use per-run logs in Scheduled Jobs.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Project ID |
Query Parameters (optional)
| Parameter | Type | Description |
|---|---|---|
instance | string | Instance identifier used to return logs from a single instance |
Response
{
"status": "success",
"message": "get instances logs with success",
"data": [
"2024-01-15T10:30:00Z Starting application...\n2024-01-15T10:30:01Z Server listening on port 3000",
"2024-01-15T10:30:05Z GET /health 200"
]
}When instance is sent, data can be a single string containing the logs for the requested instance.
Errors (metrics and logs)
| Status | When it happens |
|---|---|
400 | instance is required or invalid (Analytics, Key-Value, Cache, and Queue metrics); the given instance does not exist (logs); or the project is not an HTTP application (logs) |
402 | The project plan does not include metrics (logs are available on every plan) |
404 | Project or instance not found |
Examples
Get Metrics
curl -X GET "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011/metrics" \
-H "x-api-key: your-api-key" \
-H "x-organization-id: your-organization-id"Get Logs
curl -X GET "https://api.zenifra.com/v1/project/507f1f77bcf86cd799439011/logs?instance=abc" \
-H "x-api-key: your-api-key" \
-H "x-organization-id: your-organization-id"Python
import requests
API_KEY = "your-api-key"
ORGANIZATION_ID = "your-organization-id"
PROJECT_ID = "507f1f77bcf86cd799439011"
headers = {"x-api-key": API_KEY, "x-organization-id": ORGANIZATION_ID}
# Get metrics
metrics = requests.get(
f"https://api.zenifra.com/v1/project/{PROJECT_ID}/metrics",
headers=headers
).json()
print(metrics)
# Get logs
logs = requests.get(
f"https://api.zenifra.com/v1/project/{PROJECT_ID}/logs",
params={"instance": "abc"},
headers=headers
).json()
print(logs)Last updated on