Dashboards
Dashboards are your own views across every dataset Errora stores: a line chart of error volume next to p95 latency next to a table of your slowest transactions.
Create one
Dashboards → New dashboard, name it, then add widgets. Dashboards belong to the organization, so everyone with access sees the same board.
Widget anatomy
Each widget is: a dataset, a visualization, one or more aggregates, an optional group-by, and optional filters.
Visualizations
line, area, bar, table, big_number.
Datasets and what they can answer
| Dataset | Aggregates | Group by / filter |
|---|---|---|
| errors | count(), count_unique(issue) | level, environment, release, platform, server_name |
| transactions | count(), avg(duration), sum(duration), failure_rate(), p50–p99``(duration) | transaction, op, status, environment, release, platform |
| logs | count() | level, environment, release |
| metrics | the metric's own aggregates (sum, avg, min, max, percentiles, count_unique) | any tag the metric carries |
| profiles | count(), avg(duration), sum(samples), p50–p99(duration) | transaction, environment, release, platform |
| issues | count(), sum(events), sum(users) | issue attributes |
The builder reads this catalog from the server (GET /dashboards/catalog), so it can only
offer queries the backend can actually answer — and a widget you saved last month still
renders, because the serializer validates against the same registry.
Example widgets
| Question | Dataset | Visualization | Aggregate | Group by |
|---|---|---|---|---|
| Are we getting worse? | errors | line | count() | level |
| Which endpoint is slow? | transactions | table | p95(duration) | transaction |
| How healthy is checkout? | transactions | big number | failure_rate() | — (filter transaction:/checkout) |
| Log volume by severity | logs | area | count() | level |
| Orders today | metrics | big number | sum of orders.created | — |
| Slowest profiled routes | profiles | bar | p99(duration) | transaction |
Arranging and sharing
Widgets can be reordered (drag, or PATCH .../widgets/reorder). Everyone in the
organization with project:read can view the board; editing needs the usual write
capabilities. A dashboard is scoped to the organization, and each widget resolves against
the projects you can see.
API
GET /api/v1/dashboards/catalog
GET /api/v1/organizations/{org_id}/dashboards
POST /api/v1/organizations/{org_id}/dashboards
GET /api/v1/organizations/{org_id}/dashboards/{id}
PATCH /api/v1/organizations/{org_id}/dashboards/{id}
DELETE /api/v1/organizations/{org_id}/dashboards/{id}
POST /api/v1/organizations/{org_id}/dashboards/{id}/widgets
PATCH /api/v1/organizations/{org_id}/dashboards/{id}/widgets/reorder
PATCH /api/v1/organizations/{org_id}/dashboards/{id}/widgets/{widget_id}
DELETE /api/v1/organizations/{org_id}/dashboards/{id}/widgets/{widget_id}
GET /api/v1/organizations/{org_id}/dashboards/{id}/widgets/{widget_id}/data
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| An aggregate isn't offered | It isn't in that dataset's catalog entry — percentiles exist for durations, not for counts |
| Widget is empty | No data in the period, or a filter value that never occurs (check spelling of environment/release) |
| Percentile looks off | Percentiles are estimated from a bounded sample of the underlying values |
| Group-by column missing | Only the catalog's declared columns are selectable; anything else would let user input reach the ORM as a field name |