Dashboards API
Every Dashboards action (6) and data model (2): endpoints, scopes, input, preconditions, events and examples.
Dashboards of numbers, charts and tables built from your Base tables and your reports.
Module code dashboards · 6 actions · 2 data models · 3 events. A key or token never does more here than the person behind it can; row-level security applies exactly as in the app. Scopes: dashboards (everything), dashboards:read (read only) or dashboards:<capability>.
Resources
| Resource | Table | List and read | POST | PATCH | DELETE |
|---|---|---|---|---|---|
dashboard_widgets | dashboard_widget | /api/v1/dashboard_widgets | |||
dashboards | dashboard | /api/v1/dashboards | dashboards.create_dashboard | dashboards.update_dashboard | dashboards.delete_dashboard |
Lists take limit (up to 200), cursor, order (e.g. -created_at), fields and q; every other query parameter is a column filter: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.
Actions
| Action | Needs | What it does |
|---|---|---|
dashboards.arrange_widgets | dashboards:write | Rearrange widgets |
dashboards.create_dashboard | dashboards:write | New dashboard |
dashboards.delete_dashboard | dashboards:delete | Delete a dashboard |
dashboards.remove_widget | dashboards:write | Remove a widget |
dashboards.save_widget | dashboards:write | Add or edit a widget |
dashboards.update_dashboard | dashboards:write | Rename a dashboard |
dashboards.arrange_widgets
Rearrange widgets — Puts a board’s widgets in a new order.
Needs dashboards:write · changes data
https://app.getera.io/api/v1/dashboard_widgets/actions/arrange_widgets- Canonical address:
POST /api/v1/actions/dashboards.arrange_widgets
Input
| Field | Type | Required | Notes |
|---|---|---|---|
dashboardId | uuid | yes | Dashboard · id of dashboard |
order | object / array | yes | Order |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
dashboard_not_found | The dashboard must exist. |
Events it publishes: dashboards.dashboard_changed
What it writes: dashboard_widget (update) — Renumbers the widgets
curl -X POST https://app.getera.io/api/v1/dashboard_widgets/actions/arrange_widgets \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"dashboardId":"DASHBOARD_ID","order":{}}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboardWidgets.arrangeWidgets({
dashboardId: "DASHBOARD_ID",
order: {}
})era dashboard_widgets arrange_widgets --data '{"dashboardId":"DASHBOARD_ID","order":{}}'{
"name": "era__dashboards__arrange_widgets",
"arguments": {
"dashboardId": "DASHBOARD_ID",
"order": {}
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 dashboard_not_found · 429 slow down
dashboards.create_dashboard
New dashboard — Opens an empty board to put figures and charts on.
Needs dashboards:write · changes data
https://app.getera.io/api/v1/dashboards/actions/create_dashboard- REST alias:
POST /api/v1/dashboards - Canonical address:
POST /api/v1/actions/dashboards.create_dashboard
Input
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | yes | Name · max 200 |
description | string | Description · max 2000 |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
title_required | A dashboard needs a name. |
name_taken | Two dashboards may not share a name. |
Events it publishes: dashboards.dashboard_created
What it writes: dashboard (insert) — Creates the board
curl -X POST https://app.getera.io/api/v1/dashboards/actions/create_dashboard \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"title":"Name"}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_created"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboards.create({
title: "Name"
})era dashboards create \
--title "Name"{
"name": "era__dashboards__create_dashboard",
"arguments": {
"title": "Name"
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 title_required, name_taken · 429 slow down
dashboards.delete_dashboard
Delete a dashboard — Removes a board and its widgets. The tables it read are untouched.
Needs dashboards:delete · removes or cannot be undone · asks a person to confirm when Era runs it
https://app.getera.io/api/v1/dashboards/{id}/actions/delete_dashboard- REST alias:
DELETE /api/v1/dashboards/{id} - Canonical address:
POST /api/v1/actions/dashboards.delete_dashboard
Input
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Filled from the path {id} · Dashboard · id of dashboard |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
dashboard_not_found | The dashboard must exist. |
Events it publishes: dashboards.dashboard_deleted
What it writes: dashboard (delete) — Deletes the board; dashboard_widget (delete) — And every widget on it
curl -X POST https://app.getera.io/api/v1/dashboards/DASHBOARD_ID/actions/delete_dashboard \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_deleted"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboards.deleteDashboard("DASHBOARD_ID")era dashboards delete_dashboard DASHBOARD_ID{
"name": "era__dashboards__delete_dashboard",
"arguments": {
"id": "DASHBOARD_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 dashboard_not_found · 429 slow down
dashboards.remove_widget
Remove a widget — Takes one widget off its board.
Needs dashboards:write · removes or cannot be undone · asks a person to confirm when Era runs it
https://app.getera.io/api/v1/dashboard_widgets/{id}/actions/remove_widget- Canonical address:
POST /api/v1/actions/dashboards.remove_widget
Input
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Filled from the path {id} · Widget · id of dashboard_widget |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
widget_not_found | The widget must exist. |
Events it publishes: dashboards.dashboard_changed
What it writes: dashboard_widget (delete) — Deletes the widget
curl -X POST https://app.getera.io/api/v1/dashboard_widgets/DASHBOARD_WIDGET_ID/actions/remove_widget \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboardWidgets.removeWidget("DASHBOARD_WIDGET_ID")era dashboard_widgets remove_widget DASHBOARD_WIDGET_ID{
"name": "era__dashboards__remove_widget",
"arguments": {
"id": "DASHBOARD_WIDGET_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 widget_not_found · 429 slow down
dashboards.save_widget
Add or edit a widget — Puts a figure, chart, table or note on a board, reading one Base table or view, or one of the modules’ reports.
Needs dashboards:write · changes data
https://app.getera.io/api/v1/dashboard_widgets/{id}/actions/save_widget- Canonical address:
POST /api/v1/actions/dashboards.save_widget
Input
| Field | Type | Required | Notes |
|---|---|---|---|
dashboardId | uuid | yes | Dashboard · id of dashboard |
id | uuid | Filled from the path {id} · Widget · id of dashboard_widget | |
kind | string (enum) | yes | Kind · Allowed values: metric, bar, line, donut, table, text |
title | string | yes | Title · max 200 |
dataTableId | uuid | Table · id of data_table | |
savedViewId | uuid | View · id of saved_view | |
datasetKey | string | Report · max 120 | |
config | object / array | Settings | |
width | number | Width · min 1 · max 4 |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
dashboard_not_found | The dashboard must exist. |
widget_not_found | An edited widget must be on this dashboard. |
source_table_not_found | A data widget reads a Base table, and a view of that table. |
dataset_not_found | A report widget reads a report this workspace has and the builder can open. |
invalid_widget_config | The fields a widget sums or groups by must suit it. |
Events it publishes: dashboards.dashboard_changed
What it writes: dashboard_widget (upsert) — Writes the widget
curl -X POST https://app.getera.io/api/v1/dashboard_widgets/DASHBOARD_WIDGET_ID/actions/save_widget \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"dashboardId":"DASHBOARD_ID","kind":"metric","title":"Title"}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboardWidgets.saveWidget("DASHBOARD_WIDGET_ID", {
dashboardId: "DASHBOARD_ID",
kind: "metric",
title: "Title"
})era dashboard_widgets save_widget DASHBOARD_WIDGET_ID \
--dashboard-id "DASHBOARD_ID" \
--kind "metric" \
--title "Title"{
"name": "era__dashboards__save_widget",
"arguments": {
"id": "DASHBOARD_WIDGET_ID",
"dashboardId": "DASHBOARD_ID",
"kind": "metric",
"title": "Title"
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 dashboard_not_found, widget_not_found, source_table_not_found, dataset_not_found, invalid_widget_config · 429 slow down
dashboards.update_dashboard
Rename a dashboard — Changes a board’s name or description.
Needs dashboards:write · changes data
https://app.getera.io/api/v1/dashboards/{id}/actions/update_dashboard- REST alias:
PATCH /api/v1/dashboards/{id} - Canonical address:
POST /api/v1/actions/dashboards.update_dashboard
Input
| Field | Type | Required | Notes |
|---|---|---|---|
id | uuid | yes | Filled from the path {id} · Dashboard · id of dashboard |
title | string | Name · max 200 | |
description | string | Description · max 2000 |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
dashboard_not_found | The dashboard must exist. |
name_taken | Two dashboards may not share a name. |
no_change | Something has to change. |
Events it publishes: dashboards.dashboard_changed
What it writes: dashboard (update) — Renames the board
curl -X POST https://app.getera.io/api/v1/dashboards/DASHBOARD_ID/actions/update_dashboard \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"title":"Name"}'{
"ok": true,
"result": "…",
"events": [
"dashboards.dashboard_changed"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.dashboards.updateDashboard("DASHBOARD_ID", {
title: "Name"
})era dashboards update_dashboard DASHBOARD_ID \
--title "Name"{
"name": "era__dashboards__update_dashboard",
"arguments": {
"id": "DASHBOARD_ID",
"title": "Name"
}
}Errors: 401 no or expired credential · 403 the credential does not hold dashboards:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 dashboard_not_found, name_taken, no_change · 429 slow down
Data models
DashboardWidget
Table dashboard_widget · Resource dashboard_widgets
GET /api/v1/dashboard_widgetsGET /api/v1/dashboard_widgets/{id}
| Column | Type | Nullable | Allowed values | References |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
dashboard_id | string (uuid) · uuid | dashboard | ||
kind | string · text | metric, bar, line, donut, table, text | ||
title | string · text | |||
data_table_id | string (uuid) · uuid | yes | ||
saved_view_id | string (uuid) · uuid | yes | ||
config | object · jsonb | |||
width | integer · int2 | |||
position | number · float8 | |||
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz | |||
dataset_key | string · text | yes |
Primary key: id
Checks:
CHECK ((jsonb_typeof(config) = 'object'::text))CHECK (((dataset_key IS NULL) OR (dataset_key ~ '^[a-z0-9_]+\.[a-z0-9_]+$'::text)))CHECK (((kind = 'text'::text) OR (data_table_id IS NOT NULL) OR (dataset_key IS NOT NULL)))CHECK (((width >= 1) AND (width <= 4)))
Dashboard
Table dashboard · Resource dashboards
GET /api/v1/dashboardsGET /api/v1/dashboards/{id}POST /api/v1/dashboards→dashboards.create_dashboardPATCH /api/v1/dashboards/{id}→dashboards.update_dashboardDELETE /api/v1/dashboards/{id}→dashboards.delete_dashboard
| Column | Type | Nullable | Allowed values | References |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
title | string · text | |||
description | string · text | yes | ||
sort_order | number · float8 | |||
created_by | string (uuid) · uuid | yes | app_user | |
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz |
Primary key: id
Checks:
CHECK ((btrim(title) <> ''::text))
Events
Workflows and webhooks react to these events.
| Event | What happens | Payload |
|---|---|---|
dashboards.dashboard_changed | A dashboard or its widgets changed. | id |
dashboards.dashboard_created | A dashboard was created. | id |
dashboards.dashboard_deleted | A dashboard was deleted. | id |