Usage Stats & Analytics
Endpoints for viewing app usage statistics, workspace storage, and server route invocation history.
GET /api/apps/{id}/stats
Get aggregated usage statistics for an app including view counts, API invocations, and workspace storage.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
{
"appId": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"totalViews": 142,
"uniqueViewers": 23,
"views7d": 45,
"views30d": 89,
"lastViewedAt": "2024-02-23T14:30:00.000Z",
"viewsByDay": [
{ "day": "2024-02-23", "count": 12 },
{ "day": "2024-02-22", "count": 8 },
{ "day": "2024-02-21", "count": 5 }
],
"api": {
"totalInvocations": 1200,
"invocations7d": 340,
"invocations30d": 780,
"avgDurationMs": 245,
"errorCount30d": 12,
"errorRate30d": 1.54,
"peakMemoryBytes": 52428800,
"totalComputeMs": 190740
},
"storage": {
"hasWorkspace": true,
"schemaSize": 2097152,
"tableCount": 3,
"quotaBytes": 1073741824,
"quotaPercent": 0.2
}
}
Key Fields:
| Field | Description |
|---|---|
totalViews | All-time view count |
uniqueViewers | Distinct users who viewed the app |
views7d / views30d | View counts over the last 7 and 30 days |
viewsByDay | Daily breakdown for the last 7 days |
api.totalInvocations | Total server route invocations |
api.errorRate30d | Error percentage over last 30 days |
storage.hasWorkspace | Whether the app has a Postgres workspace |
storage.schemaSize | Workspace disk usage in bytes |
storage.quotaPercent | Percentage of storage quota used |
Permissions Required: None (404 if user cannot read this app)
GET /api/apps/{id}/stats/tables
List all tables in the app's Postgres workspace with column metadata.
Authentication: Required
Permissions Required: Member+ role (write permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns an empty array if the app has no workspace schema.
[
{
"name": "users",
"rowCount": 1250,
"sizeBytes": 524288,
"columns": [
{
"name": "id",
"type": "uuid",
"nullable": false,
"primaryKey": true
},
{
"name": "email",
"type": "character varying",
"nullable": false,
"indexed": true
},
{
"name": "created_at",
"type": "timestamp with time zone",
"nullable": true
}
]
}
]
Key Fields:
| Field | Description |
|---|---|
rowCount | Approximate row count from pg_stat_user_tables |
sizeBytes | Total relation size from pg_total_relation_size() |
columns[].primaryKey | Whether the column is part of the primary key |
columns[].indexed | Whether the column has an index |
The _migrations table used for tracking applied migrations is excluded from the response.
POST /api/apps/{id}/stats/tables/{table}/preview
Preview rows from a table in the app's workspace.
Authentication: Required
Permissions Required: Member+ role (write permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
table | string | Table name |
Payload:
{
"limit": 25,
"offset": 0
}
| Field | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Rows per page (1-100) |
offset | integer | 0 | Row offset for pagination |
Response:
{
"rows": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"created_at": "2024-02-01T10:00:00Z"
}
],
"rowCount": 1,
"totalRows": 1250,
"fields": [
{ "name": "id", "dataTypeID": 2950 },
{ "name": "email", "dataTypeID": 1043 },
{ "name": "created_at", "dataTypeID": 1184 }
]
}
Key Fields:
| Field | Description |
|---|---|
rowCount | Number of rows returned in this page |
totalRows | Total rows in the table |
fields | Column metadata with Postgres data type OIDs |
The table name is validated against information_schema to prevent SQL injection. Requests for non-existent tables or the _migrations table return 404 Not Found.
GET /api/apps/{id}/stats/api
Get detailed server route invocation history and daily aggregates.
Authentication: Required
Permissions Required: Member+ role (write permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
{
"recent": [
{
"method": "GET",
"path": "/api/datasets/123/search",
"username": "john.doe",
"startedAt": "2024-02-23T14:30:00.000Z",
"durationMs": 245,
"statusCode": 200,
"memoryPeakBytes": 52428800,
"error": null
}
],
"daily": [
{
"day": "2024-02-23",
"count": 45,
"avgDurationMs": 234,
"errorCount": 1
}
]
}
Key Fields:
| Field | Description |
|---|---|
recent | Last 100 invocations, ordered by startedAt descending |
recent[].memoryPeakBytes | Peak memory usage of the V8 isolate |
recent[].error | Error message if the invocation failed, null otherwise |
daily | Daily aggregates for the last 30 days |
daily[].avgDurationMs | Average handler execution time for the day |