Skip to content

Dashboards API

The Dashboards API enables creation and management of interactive data dashboards. Dashboards aggregate visualizations and metrics from multiple projects and can be shared with teams or externally.

https://api.querri.com/api

All Dashboards API endpoints require JWT authentication. See Authentication for details.

Creating dashboards requires the pro entitlement. Users on free plans can view shared dashboards but cannot create new ones.

Create a new dashboard with widgets and layout configuration.

POST /api/dashboards

Headers:

Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json

Request Body:

{
"name": "Q4 Executive Dashboard",
"description": "Executive summary of Q4 performance metrics",
"layout": {
"columns": 12,
"row_height": 100
},
"widgets": [
{
"id": "widget_01",
"type": "metric",
"title": "Total Revenue",
"position": {"x": 0, "y": 0, "w": 3, "h": 2},
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_01ABCDEF",
"query": "SELECT SUM(revenue) as total FROM results"
},
"config": {
"format": "currency",
"prefix": "$",
"decimals": 0
}
},
{
"id": "widget_02",
"type": "chart",
"title": "Revenue by Month",
"position": {"x": 3, "y": 0, "w": 6, "h": 4},
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_02GHIJKL"
},
"config": {
"chart_type": "line",
"x_axis": "month",
"y_axis": "revenue",
"color_scheme": "blues"
}
}
],
"settings": {
"auto_refresh": true,
"refresh_interval_seconds": 300,
"theme": "light"
}
}

Response: 201 Created

{
"uuid": "dash_01ABCDEF",
"name": "Q4 Executive Dashboard",
"description": "Executive summary of Q4 performance metrics",
"layout": {
"columns": 12,
"row_height": 100
},
"widgets": [
{
"id": "widget_01",
"type": "metric",
"title": "Total Revenue",
"position": {"x": 0, "y": 0, "w": 3, "h": 2},
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_01ABCDEF",
"query": "SELECT SUM(revenue) as total FROM results"
},
"config": {
"format": "currency",
"prefix": "$",
"decimals": 0
},
"status": "pending"
}
],
"settings": {
"auto_refresh": true,
"refresh_interval_seconds": 300,
"theme": "light"
},
"created_by": "user_01ABCDEF",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T10:00:00Z",
"last_refreshed_at": null,
"status": "draft"
}

Permission Required: User must have pro entitlement.

Error Responses:

// 403 Forbidden - No pro entitlement
{
"error": "forbidden",
"message": "Dashboard creation requires 'pro' entitlement",
"required_entitlement": "pro",
"upgrade_url": "https://querri.com/pricing"
}
// 400 Bad Request - Invalid widget configuration
{
"error": "validation_error",
"message": "Invalid widget position: overlapping widgets",
"widget_id": "widget_02"
}

Retrieve all dashboards accessible to the authenticated user.

GET /api/dashboards

Query Parameters:

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Results per page (max 100)
sortstringupdated_atSort field: created_at, updated_at, name
orderstringdescSort order: asc or desc
searchstring-Search in name and description

Example Request:

Terminal window
curl "https://api.querri.com/api/dashboards?page=1&limit=10" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response: 200 OK

{
"data": [
{
"uuid": "dash_01ABCDEF",
"name": "Q4 Executive Dashboard",
"description": "Executive summary of Q4 performance metrics",
"widget_count": 8,
"created_by": "user_01ABCDEF",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T14:30:00Z",
"last_refreshed_at": "2025-01-15T14:25:00Z",
"status": "active",
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": true,
"role": "owner"
},
"share_links": [
{
"share_token": "share_abc123",
"expires_at": "2025-02-15T00:00:00Z",
"access_count": 42
}
]
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 15,
"total_pages": 2,
"has_next": true,
"has_prev": false
}
}

Retrieve a single dashboard with full widget configuration.

GET /api/dashboards/{uuid}

Path Parameters:

ParameterTypeDescription
uuidstringDashboard UUID

Query Parameters:

ParameterTypeDefaultDescription
refreshbooleanfalseTrigger data refresh before returning
share_tokenstring-Share token for public access

Example Request:

Terminal window
curl "https://api.querri.com/api/dashboards/dash_01ABCDEF" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response: 200 OK

{
"uuid": "dash_01ABCDEF",
"name": "Q4 Executive Dashboard",
"description": "Executive summary of Q4 performance metrics",
"layout": {
"columns": 12,
"row_height": 100
},
"widgets": [
{
"id": "widget_01",
"type": "metric",
"title": "Total Revenue",
"position": {"x": 0, "y": 0, "w": 3, "h": 2},
"data": {
"value": 1250000,
"formatted": "$1,250,000",
"change_percent": 15.3,
"trend": "up"
},
"status": "loaded",
"last_updated": "2025-01-15T14:25:00Z"
},
{
"id": "widget_02",
"type": "chart",
"title": "Revenue by Month",
"position": {"x": 3, "y": 0, "w": 6, "h": 4},
"data": {
"labels": ["Oct", "Nov", "Dec"],
"datasets": [
{
"label": "Revenue",
"data": [400000, 425000, 425000]
}
]
},
"status": "loaded",
"last_updated": "2025-01-15T14:25:00Z"
}
],
"settings": {
"auto_refresh": true,
"refresh_interval_seconds": 300,
"theme": "light"
},
"metadata": {
"created_by": "user_01ABCDEF",
"created_at": "2025-01-15T10:00:00Z",
"updated_at": "2025-01-15T14:30:00Z",
"last_refreshed_at": "2025-01-15T14:25:00Z"
},
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": true,
"role": "owner"
}
}

Permission Required: dashboard:read on the specific dashboard, or valid share token.


Update dashboard properties, widgets, or layout.

PUT /api/dashboards/{uuid}

Headers:

Authorization: Bearer {JWT_TOKEN}
Content-Type: application/json

Request Body:

{
"name": "Q4 2024 Executive Dashboard",
"description": "Updated executive summary",
"widgets": [
{
"id": "widget_01",
"type": "metric",
"title": "Total Revenue (Updated)",
"position": {"x": 0, "y": 0, "w": 4, "h": 2},
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_01ABCDEF",
"query": "SELECT SUM(revenue) as total FROM results WHERE year = 2024"
},
"config": {
"format": "currency",
"prefix": "$",
"decimals": 0
}
},
{
"id": "widget_03",
"type": "table",
"title": "Top Products",
"position": {"x": 0, "y": 2, "w": 12, "h": 4},
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_03MNOPQR"
},
"config": {
"columns": ["product", "revenue", "units_sold"],
"sort_by": "revenue",
"sort_order": "desc",
"page_size": 10
}
}
],
"settings": {
"auto_refresh": true,
"refresh_interval_seconds": 600,
"theme": "dark"
}
}

Response: 200 OK

Returns updated dashboard object (same structure as GET response).

Permission Required: dashboard:edit on the specific dashboard.

Error Responses:

// 409 Conflict - Dashboard is currently refreshing
{
"error": "conflict",
"message": "Cannot update dashboard while refresh is in progress"
}

Delete a dashboard permanently.

DELETE /api/dashboards/{uuid}

Example Request:

Terminal window
curl -X DELETE "https://api.querri.com/api/dashboards/dash_01ABCDEF" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

Response: 204 No Content

Permission Required: dashboard:delete on the specific dashboard (typically owner only).


Retrieve the refresh schedule for a dashboard.

GET /api/dashboards/{uuid}/schedule

Response: 200 OK

{
"dashboard_uuid": "dash_01ABCDEF",
"schedule": {
"enabled": true,
"cron": "0 */6 * * *",
"timezone": "America/New_York",
"last_run": "2025-01-15T12:00:00-05:00",
"next_run": "2025-01-15T18:00:00-05:00",
"status": "active"
},
"history": [
{
"execution_id": "exec_01ABCDEF",
"started_at": "2025-01-15T12:00:00-05:00",
"completed_at": "2025-01-15T12:02:35-05:00",
"duration_seconds": 155,
"status": "completed",
"widgets_refreshed": 8
}
]
}

Set up or modify the refresh schedule for a dashboard.

POST /api/dashboards/{uuid}/schedule

Request Body:

{
"enabled": true,
"cron": "0 */6 * * *",
"timezone": "America/New_York",
"notify_on_failure": true,
"notification_channels": ["email", "slack"]
}

Parameters:

FieldTypeRequiredDescription
enabledbooleanYesEnable/disable scheduled refresh
cronstringYesCron expression for schedule
timezonestringNoTimezone for cron (default: UTC)
notify_on_failurebooleanNoSend notification on failure (default: false)
notification_channelsarrayNoChannels: email, slack, webhook

Common Cron Expressions:

ExpressionDescription
0 */1 * * *Every hour
0 */6 * * *Every 6 hours
0 9 * * 1-59 AM weekdays
0 0 * * *Daily at midnight
0 0 * * 0Weekly on Sunday

Response: 200 OK

{
"schedule_id": "sched_01ABCDEF",
"dashboard_uuid": "dash_01ABCDEF",
"enabled": true,
"cron": "0 */6 * * *",
"timezone": "America/New_York",
"next_run": "2025-01-15T18:00:00-05:00",
"created_at": "2025-01-15T15:00:00Z"
}

Permission Required: dashboard:edit on the specific dashboard.


Display a single numeric value with optional comparison.

{
"type": "metric",
"title": "Total Revenue",
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_01ABCDEF",
"query": "SELECT SUM(revenue) as value FROM results"
},
"config": {
"format": "currency",
"prefix": "$",
"suffix": "",
"decimals": 0,
"comparison": {
"enabled": true,
"query": "SELECT SUM(revenue) as value FROM results WHERE period = 'previous'",
"label": "vs. last quarter"
}
}
}

Format Options: number, currency, percentage, duration


Visualize data with various chart types.

{
"type": "chart",
"title": "Revenue Trend",
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_02GHIJKL"
},
"config": {
"chart_type": "line",
"x_axis": "month",
"y_axis": "revenue",
"series": ["revenue", "profit"],
"color_scheme": "blues",
"show_legend": true,
"show_grid": true,
"y_axis_format": "currency"
}
}

Chart Types: line, bar, area, pie, donut, scatter, heatmap


Display tabular data with sorting and pagination.

{
"type": "table",
"title": "Top Customers",
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_03MNOPQR"
},
"config": {
"columns": [
{"field": "name", "label": "Customer", "width": 200},
{"field": "revenue", "label": "Revenue", "format": "currency"},
{"field": "orders", "label": "Orders", "format": "number"}
],
"sort_by": "revenue",
"sort_order": "desc",
"page_size": 20,
"show_pagination": true,
"row_actions": ["view", "export"]
}
}

Visualize geographic data.

{
"type": "map",
"title": "Sales by Region",
"data_source": {
"project_uuid": "proj_01ABCDEF",
"step_id": "step_04STUVWX"
},
"config": {
"map_type": "choropleth",
"location_field": "state",
"value_field": "revenue",
"color_scheme": "greens",
"zoom_level": 4,
"center": {"lat": 39.8283, "lng": -98.5795}
}
}

Map Types: choropleth, markers, heatmap


Display formatted text or markdown.

{
"type": "text",
"title": "Dashboard Overview",
"config": {
"content": "# Q4 Performance\n\nThis dashboard shows key metrics for Q4 2024.",
"format": "markdown",
"text_align": "left"
}
}

Terminal window
curl -X POST "https://api.querri.com/api/dashboards/dash_01ABCDEF/share" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"expires_at": "2025-02-15T00:00:00Z",
"password_protected": false,
"access_level": "view"
}'

Response:

{
"share_link": "https://app.querri.com/dashboards/dash_01ABCDEF?share_token=share_abc123",
"share_token": "share_abc123",
"expires_at": "2025-02-15T00:00:00Z",
"created_at": "2025-01-15T10:00:00Z"
}
Terminal window
# Via query parameter
curl "https://api.querri.com/api/dashboards/dash_01ABCDEF?share_token=share_abc123"
# Via header
curl "https://api.querri.com/api/dashboards/dash_01ABCDEF" \
-H "X-Share-Token: share_abc123"

Share links allow read-only access without authentication.


Terminal window
curl -X POST "https://api.querri.com/api/dashboards/dash_01ABCDEF/refresh" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"widgets": ["widget_01", "widget_02"],
"mode": "async"
}'

Response: 202 Accepted

{
"refresh_id": "refresh_01ABCDEF",
"dashboard_uuid": "dash_01ABCDEF",
"status": "running",
"started_at": "2025-01-15T15:00:00Z",
"widgets_refreshing": ["widget_01", "widget_02"]
}

Enable auto-refresh in dashboard settings:

{
"settings": {
"auto_refresh": true,
"refresh_interval_seconds": 300
}
}

Client-side auto-refresh polls the dashboard endpoint every refresh_interval_seconds.


Terminal window
curl "https://api.querri.com/api/dashboards/dash_01ABCDEF/embed" \
-H "Authorization: Bearer ${JWT_TOKEN}"

Response:

{
"embed_url": "https://app.querri.com/embed/dash_01ABCDEF",
"iframe_code": "<iframe src=\"https://app.querri.com/embed/dash_01ABCDEF?theme=light\" width=\"100%\" height=\"600\"></iframe>",
"allowed_domains": ["example.com", "app.example.com"]
}
ParameterTypeDescription
themestringlight or dark
hide_headerbooleanHide dashboard title and controls
hide_filtersbooleanHide filter controls
auto_refreshbooleanEnable auto-refresh

Dashboards can trigger webhooks on refresh completion or failure. See Webhooks API for configuration.

Event Types:

  • dashboard.refreshed - Dashboard refresh completed
  • dashboard.refresh_failed - Dashboard refresh failed
  • dashboard.shared - Dashboard shared via link

CodeDescription
200Success (GET, PUT)
201Created (POST)
202Accepted (async refresh)
204No Content (DELETE)
400Bad Request (validation error)
401Unauthorized
403Forbidden (requires ‘pro’ entitlement)
404Not Found
409Conflict (refresh in progress)
429Too Many Requests
500Internal Server Error