CapyDB/ docs
ReferenceAPI

Observability

Live database metrics for a project.

Get live project metrics

GET
/v1/projects/{projectID}/observability

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Response Body

Observability snapshot.

application/json
  1. response
observability*
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/observability'
{  "observability": {    "active_queries": [      {        "duration_ms": 0,        "pid": 0,        "query": "string",        "state": "string",        "username": "string",        "wait_event": "string",        "wait_event_type": "string"      }    ],    "alerts": [      "string"    ],    "connection_count": 0,    "connection_limit": 0,    "connection_usage_percent": 0,    "database_size_bytes": 0,    "pg_stat_statements": true,    "slow_queries": [      {        "calls": 0,        "mean_time_ms": 0,        "query": "string",        "rows": 0,        "total_time_ms": 0,        "query_id": 0,        "shared_blks_hit": 0,        "shared_blks_read": 0,        "temp_blks_read": 0,        "temp_blks_written": 0,        "jit_time_ms": 0.1      }    ],    "storage_limit_bytes": 0,    "storage_usage_percent": 0,    "wake": {      "max_ms": 0,      "p50_ms": 0,      "p95_ms": 0,      "timed_wakes": 0,      "wakes": 0,      "window_hours": 0    }  }}
GET
/v1/projects/{projectID}/observability/history

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

hours?integer

Trailing window in hours, between 1 and 720 (default 24).

Range1 <= value <= 720
Default24

Response Body

Metrics history samples, ascending by sampled_at.

application/json
  1. response
samples*array<>
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/observability/history'
{  "samples": [    {      "active_queries": 0,      "avg_query_ms": 0,      "blocked_queries": 0,      "cache_hit_ratio": 0,      "connection_limit": 0,      "connections": 0,      "cpu_cores_used": 0,      "cpu_quota_cores": 0,      "dead_tuples": 0,      "deadlocks": 0,      "mem_limit_bytes": 0,      "mem_usage_bytes": 0,      "rollback_ratio": 0,      "rows_read_per_sec": 0,      "rows_written_per_sec": 0,      "sampled_at": "2019-08-24T14:15:22Z",      "slow_queries": 0,      "storage_bytes": 0,      "storage_limit_bytes": 0,      "temp_bytes": 0,      "tps": 0    }  ]}
GET
/v1/projects/{projectID}/observability/queries

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

hours?integer

Trailing window in hours, between 1 and 168 (default 24).

Range1 <= value <= 168
Default24

Response Body

Per-statement window activity, heaviest first.

application/json
  1. response
queries*array<>
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/observability/queries'
{  "queries": [    {      "query_hash": "string",      "calls": 0,      "mean_exec_ms": 0,      "query": "string",      "rows": 0,      "total_exec_ms": 0    }  ]}

List project alerts

GET
/v1/projects/{projectID}/alerts

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Response Body

Open and recently resolved alerts.

application/json
  1. response
alerts*array<>
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/alerts'
{  "alerts": [    {      "acknowledged_at": "2019-08-24T14:15:22Z",      "id": "string",      "kind": "storage",      "last_notified_at": "2019-08-24T14:15:22Z",      "limit_value": 0,      "observed_value": 0,      "project_id": "string",      "resolved_at": "2019-08-24T14:15:22Z",      "severity": "warning",      "triggered_at": "2019-08-24T14:15:22Z"    }  ]}
POST
/v1/projects/{projectID}/alerts/{alertID}/acknowledge

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

alertID*string

Project alert identifier.

Response Body

Acknowledged alert.

application/json
  1. response
alert*

An alert on the project's health. At most one open (unresolved) alert exists per project and kind; severity moves in place and the alert closes by setting resolved_at. Three families share this shape: threshold alerts (storage, connections) compare usage against plan limits and notify by webhook and email; the backup alert opens critical when a backup job terminally fails, notifies by webhook and email, and auto-resolves on the next successful backup; health advisories (cache_hit, blocked_queries, deadlocks, vacuum, long_transaction, subtransactions, oom_kill, temp_spill) are warning-severity hints derived from the periodic metrics sweep that surface ONLY through this API - they never send email or webhook events. temp_spill opens when the database sustains writing temporary files, meaning a sort or hash did not fit in work_mem and was materialized on disk; the remedy is per-statement (SET LOCAL work_mem, or a plan change that stops the sort), and SlowQuerySample.temp_blks_written names the statement.

curl -X POST 'https://capydb.dev/api/capydb/v1/projects/string/alerts/string/acknowledge'
{  "alert": {    "acknowledged_at": "2019-08-24T14:15:22Z",    "id": "string",    "kind": "storage",    "last_notified_at": "2019-08-24T14:15:22Z",    "limit_value": 0,    "observed_value": 0,    "project_id": "string",    "resolved_at": "2019-08-24T14:15:22Z",    "severity": "warning",    "triggered_at": "2019-08-24T14:15:22Z"  }}
GET
/v1/projects/{projectID}/observability/queries/{queryHash}

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

queryHash*string

The statement's identity hash from the top-queries listing (32-character hex digest).

Match^[0-9a-f]{32}$

Query Parameters

hours?integer

Trailing window in hours, between 1 and 168 (default 24).

Range1 <= value <= 168
Default24

Response Body

The statement's window totals and interval history.

application/json
  1. response
query*

One statement's drill-down: whole-window totals plus the per-interval history the latency/volume charts render.

curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/observability/queries/string'
{  "query": {    "query_hash": "string",    "query": "string",    "window_calls": 0,    "window_total_exec_ms": 0,    "window_mean_exec_ms": 0,    "window_rows": 0,    "points": [      {        "captured_at": "2019-08-24T14:15:22Z",        "calls": 0,        "total_exec_ms": 0,        "rows": 0,        "mean_exec_ms": 0,        "calls_per_sec": 0      }    ]  }}
GET
/v1/projects/{projectID}/logs

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

hours?integer

Trailing window in hours (default 1). Up to 720 (30 days) on deployments with the shipped-log archive; 168 (7 days) otherwise - the API rejects windows beyond the deployment's cap. Windows older than 168 hours are served from the archive. Ignored when cursor is set.

Range1 <= value <= 720
Default1
cursor?string

Resume strictly after a previously returned entry's cursor (tail mode). Takes precedence over hours.

severity?string

Comma-separated severity filter (debug, log, info, notice, warning, error, fatal, panic, detail). Empty means all severities.

limit?integer

Maximum entries returned, between 1 and 500 (default 200). The newest entries are kept.

Range1 <= value <= 500
Default200

Response Body

Log entries plus the cursor to resume a tail from.

application/json
  1. response
logs*

One log fetch: entries ascending by time plus the cursor to resume a tail from. next_cursor is absent when the fetch returned nothing - keep tailing with the previous cursor.

curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/logs'
{  "logs": {    "entries": [      {        "timestamp": "2019-08-24T14:15:22Z",        "severity": "debug",        "message": "string",        "cursor": "string",        "sqlstate": "string",        "pid": 0,        "user": "string",        "database": "string"      }    ],    "next_cursor": "string"  }}
GET
/v1/projects/{projectID}/logs/stream

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

hours?integer

Trailing window in hours, between 1 and 168 (default 1). Ignored when cursor is set.

Range1 <= value <= 168
Default1
cursor?string

Resume strictly after a previously returned entry's cursor (tail mode). Takes precedence over hours.

severity?string

Comma-separated severity filter (debug, log, info, notice, warning, error, fatal, panic, detail). Empty means all severities.

limit?integer

Maximum entries returned, between 1 and 500 (default 200). The newest entries are kept.

Range1 <= value <= 500
Default200

Response Body

An SSE stream of logs events.

response?stringtext/event-stream
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/logs/stream'
"string"
GET
/v1/projects/{projectID}/logs/search

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

sqlstate?string

Comma-separated SQLSTATE filter. A five-character code matches exactly (42P01); a two-character class matches every code in it (23 = integrity constraint violations). Lines without a code never match a sqlstate filter.

severity?string

Comma-separated severity filter (debug, log, info, notice, warning, error, fatal, panic, detail). Empty means all severities.

q?string

Case-insensitive substring the message must contain (at most 200 characters).

Lengthlength <= 200
since?string

Window start (RFC 3339). Defaults to 24 hours before until. The window may span at most 720 hours.

Formatdate-time
until?string

Window end (RFC 3339). Defaults to now.

Formatdate-time
limit?integer

Maximum entries returned, between 1 and 500 (default 100).

Range1 <= value <= 500
Default100
cursor?string

next_cursor from the previous page of the same search.

Response Body

One page of matching log entries, newest first.

application/json
  1. response
search*

One page of log search results, newest first. Continue with next_cursor (repeating the other parameters unchanged) until it is absent. truncated means the per-request scan budget ran out before the page filled: the page may be short or empty although older matches exist.

curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/logs/search'
{  "search": {    "entries": [      {        "timestamp": "2019-08-24T14:15:22Z",        "severity": "debug",        "message": "string",        "cursor": "string",        "sqlstate": "string",        "pid": 0,        "user": "string",        "database": "string"      }    ],    "next_cursor": "string",    "truncated": true  }}
GET
/v1/projects/{projectID}/events

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Response Body

An SSE stream of project events.

response?stringtext/event-stream

An SSE stream. Each project event's data field is a JSON-encoded ProjectEvent.

curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/events'
"string"
GET
/v1/projects/{projectID}/advisor/indexes

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Query Parameters

min_filter?integer

Minimum average number of rows a predicate must filter before it is considered (default 1000). Lower it on a quiet database.

Range1 <= value <= 10000000
Default1000
min_selectivity?integer

Minimum average selectivity percentage for a predicate to be considered (default 30).

Range1 <= value <= 100
Default30

Response Body

Index suggestions for the project's workload.

application/json
  1. response
advisor*
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/advisor/indexes'
{  "advisor": {    "available": true,    "min_filter": 0,    "min_selectivity": 0,    "missing_extensions": [      "string"    ],    "reason": "string",    "cost_estimates_available": true,    "size_estimates_available": true,    "suggestions": [      {        "ddl": "string",        "estimated_cost_reduction_pct": 0.1,        "estimated_size_bytes": 0,        "index_method": "string",        "query_id": 0,        "table": "string"      }    ]  }}
GET
/v1/projects/{projectID}/advisor/index-hygiene

Authorization

headerAuthorizationBearer <token>

Org or project-scoped API key, format capy_live_...; Clerk session tokens also accepted.

Path Parameters

projectID*string

Project id.

Response Body

Index hygiene report for the project's database.

application/json
  1. response
hygiene*
curl -X GET 'https://capydb.dev/api/capydb/v1/projects/string/advisor/index-hygiene'
{  "hygiene": {    "available": true,    "reason": "string",    "observation_window_seconds": 0,    "stats_reset_at": "2019-08-24T14:15:22Z",    "min_index_size_bytes": 0,    "unused_indexes": [      {        "schema": "string",        "table": "string",        "index": "string",        "size_bytes": 0,        "index_scans": 0,        "definition": "string",        "drop_statement": "string"      }    ],    "redundant_indexes": [      {        "schema": "string",        "table": "string",        "index": "string",        "size_bytes": 0,        "covered_by": "string",        "definition": "string",        "drop_statement": "string"      }    ],    "reclaimable_bytes": 0  }}