# Observability Enhancements
Source: https://docs.usedatabrain.com/changelog/observability-release
New optional OpenTelemetry support and configurable log levels for self-hosted deployments
# New: Observability Enhancements
This release adds optional OpenTelemetry support for improved monitoring and configurable log levels for self-hosted Databrain deployments.
## Upgrade Notes
**No action required for upgrade** - all defaults maintain current behavior. Your existing deployment will work exactly as before without any configuration changes.
## New Features
### Configurable Log Levels
You can now control the verbosity of application logs via the `LOG_LEVEL` environment variable:
```bash theme={"dark"}
LOG_LEVEL=info # Default - same as current behavior
LOG_LEVEL=debug # Enable detailed debug logs for troubleshooting
LOG_LEVEL=warn # Only warnings and errors
LOG_LEVEL=error # Only errors
```
### OpenTelemetry Integration (Optional)
Enable comprehensive observability with OpenTelemetry to get:
* **API Latency Tracking**: Automatic timing for all endpoints
* **Error Rate Metrics**: Monitor application health
* **Distributed Tracing**: See exactly where time is spent in each request
* **Log Correlation**: Link logs to specific request traces
To enable, add these to your `.env`:
```bash theme={"dark"}
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://your-collector:4318
```
OpenTelemetry data can be exported to any OTLP-compatible backend including:
* Grafana (Tempo + Loki + Prometheus)
* SigNoz
* Jaeger
* Datadog
* New Relic
## New Environment Variables
| Variable | Default | Description |
| ----------------------------- | --------------- | ------------------------------------- |
| `LOG_LEVEL` | `info` | Log verbosity (debug/info/warn/error) |
| `OTEL_ENABLED` | `false` | Enable OpenTelemetry |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | - | OTLP collector URL |
| `OTEL_SERVICE_NAME` | `databrain-api` | Service name in traces |
## Documentation
See the [Observability Setup Guide](/guides/observability-setup) for detailed configuration instructions.
# Product changelog
Source: https://docs.usedatabrain.com/changelog/product-changelog
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Baselines for Line and Bar Charts:** Users can now add horizontal or vertical baseline lines on the X-axis or Y-axis.
### Enhancements:
1. **Import `DashboardProps` and `MetricProps` from the DataBrain Plugin:** Added ambient declarations to support importing `DashboardProps` and `MetricProps` from the DataBrain Plugin.
2. **Customize Metric Borders in Manage Metrics:** Users can now customize metric borders from Manage Metrics or Gallery.
3. **Wrap Axis Text in Line and Bar Charts:** Added support to wrap text on the horizontal or vertical axis for line and bar charts.
4. **[Export Dashboard API](/developer-docs/helpers/api-reference/export-dashboard):** `workspaceName` is now optional in the Export Dashboard API.
5. **Guest Token API: [Hide Selected Dashboard Metrics](/developer-docs/helpers/api-reference/token) for Embedded Clients:** Added a new optional parameter to Guest Token API V2 to hide selected dashboard metrics for embedded clients.
```json theme={"dark"}
{
"clientId": "client-123",
"dataAppName": "Customer Portal",
"params": {
"hideDashboardMetrics": [
{
"dashboardId": "sales-dashboard",
"metricIds": ["revenue-by-region", "gross-margin"]
}
]
}
}
```
### Fixes:
1. We have added retry handling for Hasura query and layout insert calls to improve reliability.
2. We have fixed the frontend behavior during active Drill-Down V2 saved dashboard reload/render. `datasetMetricCreation` is now skipped when `sqlQuery` already owns the chart rendering, preventing the temporary SQL error flicker.
Regards,
**The DataBrain Team**
**Cloud Updates:** August 17th, 2026
**DataBrain Updates: Features, Enhancements, Fixes: Release Week 111** 📢
### Features:
1. **Customize Metric Gallery via API:** We have extended the Update Workspace Dashboards API to support incremental updates to metric galleries on existing dashboards. Specific metrics can now be added or removed without recreating the dashboard or impacting other dashboard settings.
```json theme={"dark"}
{
"dashboardId": "dashboard_id",
"appendMetrics": ["metric_id_1", "metric_id_2"],
"removedMetrics": ["metric_id_3"]
}
```
`appendMetrics` adds the specified metrics to the existing gallery, while `removedMetrics` removes the selected metrics.
### Enhancements:
1. **Prefix and Suffix Options for Conditional Formatting:** Conditional prefix and suffix options are now supported for all table-type charts. (Image 1)
2. **Personalized Suggestion in Chat Mode:** Chat Mode suggestions have been improved from static examples to smarter, personalized suggestions. These suggestions can consider history, memory, schema, and examples, with deduplication support to surface the top 6 most relevant suggestions.
3. **Updated Chart Settings Column List:** The chart settings column list now reflects dimension and measure changes accurately.
4. **Trino Schema Cache Refactor:** Improved Trino schema refresh performance by moving large schema syncs to an async cache flow.
### Fixes:
1. **OpenSearch Object Value Display:** Fixed object value pairs showing as `[object Object]` when dragged into charts.
Regards,
**The DataBrain Team.**
**Plugin Version:** 0.16.66
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Mandatory Admin-created Filters with Custom Alias Support:** End users can rename dashboard or metric filters configured by the Admin.
2. **Sort Options in Dashboard and Metric Filters:** End users can use ASC/DESC sort options in dashboard and metric filters configured by the Admin. Admins can enable this using the **Allow Sorting** toggle. (Image 1, 2)
3. **Metric Filters for End Users:** End users can now add metric filters. The below guest token request body enables end-user metric filter creation:
```json theme={"dark"}
{
"params": {
"accessPermissions": {
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "schemaName.tableName",
"columns": ["columnName", "columnName"]
}
]
}
}
}
```
The `metricFilterColumns` setting ensures end users can create filters only on admin approved columns.
### Enhancements:
1. **Single Value Card Underlying Data Enhancement:** Added a toggle in the UI Theming page to show complete underlying data in fullscreen mode. (Image 3)
2. **Drill Down Enhancements:** Drill Down now retains chart settings such as renamed column aliases, measure aggregations, filters, sort order, joins, group by, calculated fields, and LIMIT clauses.
3. **Pagination Enhancement in Full Screen Mode:** Added the ability to control pagination for underlying data in full screen mode. (Image 3)
4. **Pivot Table Enhancements:** Added UI Styling section for Pivot Table Chart V1 and V2.
5. **Number Formatting Enhancement:** Increased the maximum supported limit for digits before the decimal point using custom SQL query.
6. **Dashboard Scroll Minimap Prop:** The dashboard scroll minimap is now disabled by default. It can be enabled using the prop: `enableDashboardMinimap: true`
### Fixes:
1. **Enhanced Mobile View:** Improved filter indication for applied and saved filters, and added a clear filter option for date filters.
2. **Bar Chart Underlying Data:** Resolved an issue where underlying data showed "No data found" when group by was enabled in bar charts.
3. **Trino Compatibility:** Implemented support for MEDIAN or PERCENTILE\_CONT functions compatible with Trino syntax in the DataBrain UI.
4. **Datamart Update API:** Resolved an issue where the update API failed due to invalid GraphQL while syncing the linked access tableList JSONB field.
5. **MSSQL/Fabric Query Fix:** Fixed an issue where SELECT DISTINCT metric queries failed because of a synthetic pagination ORDER BY clause.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Default Aggregation for End Users:**\
Admins can now configure a default aggregation for measures at the Datamart level. The configured aggregation is applied automatically when end users add those measures.
2. **Default Sorting for End Users:**\
Admins can now configure default metric sorting, allowing end users to view metrics sorted by measure in ascending or descending order.
### Enhancements:
1. **Conditional Formatting Improvements:**\
Improved the conditional formatting workflow for Table Charts and Pivot Table Chart V3, making it easier to apply formatting rules to table columns.
2. **Log Scale Support for Horizontal Bar Charts:**\
Added a **Log Scale (Base 10)** toggle for Horizontal Bar Charts, similar to the existing Vertical Bar Chart option.
### Fixes:
1. **Custom Dataset CTE Queries:**\
Resolved an issue where creating a custom query using a CTE and publishing it as a Custom Dataset could result in an error.
2. **Achieved Metrics Without a Client:**\
Resolved intermittent issues observed when achieved metrics were calculated without a client.
**DataBrain Updates: Features, Enhancements, Fixes**
### Enhancements:
1. **MCP Server (`@databrainhq/mcp-server` v0.2.17) — Workspace Metric Upsert:**\
`create_workspace_metric` is now create-or-update. Pass an existing `metricId` to update a workspace metric in place; Dimensions and Measures are re-hydrated from the new SQL so the metric editor stays populated. Publish/archived/draft state is preserved on update. Omit `metricId` to create.
2. **MCP Prompt — `sql-to-workspace-metric`:**\
Added a guided prompt for internal (non-embed) SQL → workspace metric create/update, with dry-run by default and `confirm: "APPLY_TO_PRODUCTION"` before apply. Use `sql-to-metric-migration` when the metric should land on a customer dashboard instead.
See the updated tools, prompts, and workspace-metric workflow
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Dashboard Scroll Minimap:**\
Dense dashboards now show a compact overview of all metrics, your current position, and your progress through the dashboard. Click a metric in the minimap to jump directly to it, including metrics that have not rendered yet.
2. **Pivot Table V3 Enhancements:**\
Added support for renaming and reordering custom calculated measures, as well as displaying comma-separated distinct values at higher hierarchical levels.
3. **Single Value Card Null Display:**\
When a column returns no value in a Single Value Card, users can now display either a blank space or `-`.
### Fixes:
1. **Underlying Data:**\
Fixed an issue where underlying data was not filtered based on the selected chart point. Also fixed an issue where the modal continued loading after the network request completed.
2. **Plugin and Self-Hosted Deployments:**\
Fixed duplicate PDF downloads in self-hosted deployments, refactored the Save Layout and Reports flows in the plugin, and resolved token variable errors in Powerful LLM.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Dashboard Filters in Scheduled Reports:**\
Added support for selecting dashboard filters and their values when configuring Scheduled Reports.
### Enhancements:
1. **Pivot Table Chart V3 — Hide Measure Columns:**\
Added a toggle to hide selected measure columns from the chart.
2. **Pivot Table V3 Dimension Display Options:**\
Users can now choose whether a dimension is treated as a hierarchical row level or displayed as a regular non-pivot column.
### Fixes:
1. **ECharts Chart Resolution:**\
Improved the resolution scale of ECharts React charts in the app and plugin to prevent pixelation when zooming. Chart resolution has also been increased for PDF downloads and Scheduled Reports.
2. **Dropdown Text Wrapping:**\
Fixed a CSS issue that caused dropdown text to wrap incorrectly.
3. **Trino Custom Measure SQL:**\
Fixed an issue where a custom measure using `CAST(ROUND(...))` without an aggregate failed because of `GROUP BY (ExtPrice)`.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Microsoft Fabric Data Source:**\
Added support for Microsoft Fabric as a new data source.
2. **Multi-Dimension Support for End Users:**\
End users can now create metrics using multiple dimensions.
3. **[Dashboard Filters for End Users](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/token#paramsaccesspermissionsdashboardfiltercolumns):**\
End users can now create dashboard filters from client-specified columns. The below guest token request body enables end-user dashboard filter creation:
```json theme={"dark"}
{
"clientId": "client_id",
"dataAppName": "test_dataapp",
"params": {
"accessPermissions": {
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "schema_name.table_name",
"columns": ["col1", "col2", "col3"]
}
]
}
}
}
```
The `dashboardFilterColumns` setting ensures end users can create filters only on approved columns.
### Enhancements:
1. **Single Value Card Enhancement:**\
Added support for comparison values in the Single Value Card, along with a **Show Aggregated Value** toggle to display the aggregated value instead of the current period value.
2. **Date Filter Dependency Support:**\
Dashboard Filters (Auto & Custom), Metric Filters (Auto & Custom), and Dynamic Properties can now depend on Date Filters.
3. **Metric Card Appearance Controls:**\
Added options to show or hide the card stroke and hover shadow for individual metric cards. These settings are available in the **Save to Dashboard** dialog.
4. **Wrap Text Support for Y-Axis Labels:**\
Added a **Wrap Text** toggle under **Axis Label Setup** for vertical charts. Long category labels are now wrapped into an aligned column for improved readability.
### Fixes:
1. **Dashboard Export/Import:**\
Fixed an issue where Metric IDs referenced in Metric Expressions were not updated after importing a dashboard, resulting in connection errors.
2. **Schema Caching:**\
Improved schema caching performance for data sources containing 500+ databases.
3. **Chart Legend Colors:**\
Fixed an issue where legend colors were not applied correctly when the dimension column was of INT data type.
4. **Table Chart Number Formatting:**\
Fixed an issue where number formatting was not applied to the value 0 in Table Charts.
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **GBP Formatting Option:**\
Users can now format numeric values in GBP for supported chart types.
2. **PDF Export Date Formatting:**\
Users can now customize the date format used in exported PDFs.
3. **Line Breaks in Table Chart:**\
We have added **Allow Line Breaks** under **Chart Settings > UI Styling > Enable Content Text Wrap**. When enabled, newline characters from raw data are preserved.
4. **Conditional Formatting for Formatted Values:**\
We have added an option to compare conditional formatting rules against either **Raw Data** or **Formatted Data**. The **Formatted Data** option is available only when number formatting is applied to the selected column.
5. **Dashboard Range Filter Enhancement:**\
Dashboard range filters now support cases where only a minimum or maximum value is provided.
6. **Adding Tenancy Column to Datasource Page:**\
Added a **Tenancy** column on the **Datasource** page to display each datasource's tenancy as a badge.
### Fixes:
1. **Pivot Table V3 Downloads:**\
Fixed an issue where Pivot Table V3 downloads did not include calculated measures from Pivot Settings.
2. **Athena Dashboard Metric Download:**\
Fixed an issue in the Athena dashboard metric download flow when a row limit was applied.
3. **Datamart Table Selection:**\
Fixed an issue in Datamart table selection where **Select All Tables** selected all datamart tables instead of only the filtered search results.
Plugin Version: `0.16.55`
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Tooltip Dotted Data Point Line:**\
We have implemented the ability to manage dotted data point lines in chart settings.
2. **Styling the Tooltip Container:**\
We have added a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** to style the tooltip card, including padding, border radius, background color, and border color.
3. **Hide the Adjust Spacing Feature in Customize Layout:**\
We have included a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** to hide the **Adjust Spacing** feature in the **Customize Layout** section.
4. **Display All Chart Settings:**\
We have added a prop that bypasses the default chart settings and displays **[all possible settings](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference#custom-chart-settings-reference)**, unless otherwise configured through **[custom-chart-settings](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference#custom-chart-settings-reference)**.
5. **Customize Available Chart Types in End User Create Metric:**\
We have added a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** that allows users to customize the available chart types in the **End User Create Metric** feature.
6. **Export As PDF Server Events:**\
We have added server events to monitor the initiation and completion of the **Export As PDF** operation.
### Fixes:
1. **Hide Enabled Columns for Respective Roles in Datamart:**\
Columns can now be hidden for specific roles when the **Hide To** function is enabled.
2. **Update Dashboard API Error Message:**\
The API now returns a proper error message instead of a 500 error for an invalid `workspaceName`.
3. **Pivot V3 Calculated Columns:**\
We have resolved an issue where exponent-type numeric data, such as `1.91618e-11`, was treated as `-`.
4. **Dashboard Workspace API Validation:**\
Passing an invalid filter name to the Dashboard Workspace API now returns an error response instead of a success response.
5. **Dynamic Properties Filtering:**\
We have fixed an issue where Dynamic Properties were not filtering correctly when Dashboard Filters changed.
6. **Board's Metric Filter:**\
We have resolved an issue where a metric filter applied to a board was not removed after deselecting the board.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **[Update Dashboard Filter in Update Dashboard API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-workspace-dashboards):**\
Support has been added for updating dashboard filters via the Create Dashboard Embed API.
2. **Global Search Feature:**\
You can now search for any workspace, dashboard, or metric within your account.
### Enhancements:
1. **Dashboard Element Font Color in UI Theming Page:**\
Added support for customizing dashboard element font color in the UI theming page.
2. **Dashboard Component Customization:**\
Introduced props for:
* **[Controlling dashboard component padding](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)**
* **[Customizing top CTA buttons (Settings, Create Metric)](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)**
### Fixes:
1. **Scheduling & Formatting**
* Added support for scheduling reports in minutes.
* Resolved issues with duration-based conditional formatting.
2. **Pivot Table Improvements (V2 & V3)**
* Fixed rendering issues with multiple dimensions.
* Corrected incorrect (0) values in numerical dimensions.
3. **Dashboard UI & Layout Fixes**
* Fixed overlapping axis labels in horizontal bar charts (embed).
* Resolved alignment issues in single value cards.
* Fixed font size randomly reducing.
* Removed left padding in top-level filters.
4. **Dropdown & Data Sync Issues**
* Fixed client dropdown not reflecting updated primary key changes.
* Resolved missing dropdown options in dashboard view.
5. **SQL Editor:**\
Fixed an issue where comments were removed during execution due to auto-formatting.
6. **Authentication & Data Integrity**
* Fixed expired guest token issues in scheduled email reports.
* Resolved duplicate column issues in MSSQL metric creation.
7. **Datamart & Metric Consistency:**\
Fixed an issue where deleted datamart columns continued to appear in the network tab, causing custom columns to show connection errors and invalid metrics to expose the fullscreen action.
**DataBrain Updates: Features, Enhancements, Fixes** 📢
### Features:
1. **Alerts:**\
We have introduced a new feature, *Alerts*, which notifies users when there is an error in the data source connection or when a datamart is broken, making the dashboard unviewable.
### Enhancements:
1. **Color Selection from Colors Tab:**\
Users can now drag and reorder colors directly from the Colors tab.
2. **Context Window Indicator in AI Copilot:**\
Displays token usage per session (input and output). The limit varies by LLM and determines how much conversation can be retained. Once reached, the chat cannot continue.
3. **Delete Datamart API:**\
Added validation and improved error messaging to prevent the deletion of datamarts that are connected to a workspace.
### Fixes:
1. **Pivot Table V3:**\
Fixed an issue where conditional formatting was not rendering when a suffix was applied.
2. **Horizontal Bar Chart:**\
Added support for the Group By functionality.
3. **Elasticsearch:**\
Fixed issues related to schema sync and index handling.
Regards,\
**The DataBrain Team.**
**Introducing the Databrain MCP Server**
We're excited to announce the public release of the **Databrain MCP Server** (`@databrainhq/mcp-server` v0.2.0) — a new way to manage embedded analytics through your AI assistant.
### What is it?
The MCP server implements the [Model Context Protocol](https://modelcontextprotocol.io), connecting AI assistants like **Cursor**, **Claude Desktop**, **Claude Code**, and **Windsurf** directly to the Databrain API. Describe what you want in natural language and the assistant handles the rest.
### Key Features:
1. **Embed Setup via Conversation:** Discover data apps, select dashboards, create embeds, and generate framework-specific frontend code — all through your AI assistant.
2. **Natural Language Data Querying:** Ask questions about your data in plain English. The AI converts them to SQL, executes the query, and returns results with chart suggestions.
3. **24 Tools:** Full embed lifecycle management — creation, theming, filters, localization, permissions, guest tokens, and code generation.
4. **10 Guided Prompts:** Pre-built workflows for common tasks like embedding dashboards, multi-tenant setup, branding, and semantic layer management.
5. **Semantic Layer Management:** Populate and maintain table/column descriptions, synonyms, and example questions entirely through MCP tools.
6. **Multi-Tenant Support:** Create per-client embeds with row-level security using `clientId`.
### Getting Started:
Set up in 2 minutes — get your service token, add the config to your AI client, and start talking.
```bash theme={"dark"}
npx @databrainhq/mcp-server
```
Full setup guide, workflows, tools reference, and troubleshooting
**DataBrain Updates: Features, Enhancements, Fixes** 📢
### Features:
1. **[Multiple Datamart Connection Support](https://docs.usedatabrain.com/guides/workspace/multi-datamart-workspace):**\
Introduced multi-datamart support, allowing users to select and manage multiple datamarts.
2. **[CRUD API Support for Semantic Layer](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/semantic-layer-api):**\
Users can now **[create](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-semantic-layer)**, **[rename and update](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-semantic-layer)**, and **[delete](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-semantic-layer)** the Semantic Layer via APIs.
3. **[Delete Workspace API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-workspace):**\
Introduced a new DELETE endpoint to enable workspace deletion via API.
### Enhancements:
1. **Pivot Table Chart V3 Calculated Fields:**\
Added support for custom calculated measures, allowing users to create and edit calculated columns.
2. **Add Conditional Formatting Support to Pivot Table V3:**\
Introduced conditional styling with dynamic badge colors and background styles.
3. **[Refinement of List Datamart API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-datamarts#user-content-get-only-query--not-raw-booleans):**
We have introduced an `expandDetails` option to the Datamart List API, enabling users to control the inclusion of detailed properties in responses.
### Fixes:
1. **Pagination Sync Issue in Table Charts:**\
Fixed an issue where the default row size option was not in sync with the pagination value for server-side pagination-enabled table charts.
2. **Plugin Manage Metrics: Messaging & Settings Access:**\
When all metrics are hidden, an appropriate message will now be displayed. The settings/manage metrics button remains accessible even when all metrics are hidden.
3. **Addition of Server Events in Embed:**\
Added server-side event tracking for key user actions, including metric creation/editing, data exploration (search, table selection, drag-and-drop, aggregation), chart changes, dashboard interactions (filters, manage metrics, layout), and exports/downloads.
4. **Retaining Primary Database Selection in Update Datamart:**\
Ensured that the primary database selection is preserved during the Update Datamart operation.
Regards,\
**The DataBrain Team.**
**Plugin Version:** 0.16.34
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Chart Appearance and Chart Actions Props for End Users:**\
We have added properties to the `dbn-dashboard` component that set default values for certain chart settings when a user creates a metric. Additionally, we have introduced properties for each of these settings that can lock the values, making them non-configurable for end users.
2. **Wildcard Support for OpenSearch:**\
We have introduced wildcard syntax support for datamart tables, allowing users to specify flexible patterns when creating or updating tables.
3. **Workspace LLM Configuration via API:**\
We have introduced optional LLM integration in workspace creation and update processes, allowing users to specify an LLM by name.
4. **User-Defined Click Action on Charts:**\
We have introduced a `chartClickFunction` prop to enable custom click actions on charts. The **Pass Complete Data to Function** option allows you to pass the entire row data to the function, enabling dynamic customization of the panel content through the prop.
***
### Enhancements:
1. Admin users can now delete data apps and embeds directly from the UI.
2. **Median as an Aggregate Function:**\
We have introduced support for the `MEDIAN` aggregate function for measures. Users can now use `MEDIAN` for numeric column aggregation, enhancing data analysis capabilities.
3. Newly created or added embeds now appear at the top of the list under Data Apps.
4. **Extended timezone functionality to dashboard and metric filters** for ClickHouse, Trino, Redshift, CockroachDB, PostgreSQL, and MSSQL data sources.
5. **End User Chart Click Function Enhancement:**\
Added support to send the entire clicked row data instead of just a specific value:
* When all data is passed:
* For Table and Single Val: `{ columnName: value, }` e.g. `{"product name": "Product A1", "price": 4.444}`
* For Tree Map and Sankey: `{ name: xVal, value: yVal }`
* For others: `{ name: xVal, value: yVal, columnName: colName }`
6. Added support to import data files in the dashboard embedding API.
7. **Adding Flag in Connection Form for MSSQL Read Replica:**\
We have introduced a `readOnlyIntent` checkbox option in the MSSQL integration configuration, allowing users to connect as a read replica for read-only operations.
### Fixes:
1. Fixed datetime issues in Trino.
2. **Fixed an issue with chart reset in in-app and plugin views:**\
When updating already applied popup filters, charts in the dashboard were resetting before clicking Apply.
3. Fixed issues with using the percentile function for measures in embeds.
4. Fixed connection errors with metrics that include custom SQL queries or calculated fields.
5. Fixed an issue with the OpenSearch alias for end-user metric creation.
**Plugin Version:** 0.16.33
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Create Empty Dashboard Embed API:**\
We have introduced a prop that allows users to pass data from the Export API response when creating an empty dashboard embed.
2. **Export Embedded Dashboard API:**\
We have introduced an endpoint to export embed data, enhancing data retrieval capabilities for users.
### Enhancements:
1. **Description and Details for Embeds:**\
We have added **Description** and **Details** fields for embeds.
### Fixes:
1. We have optimized the bundle size of the plugin.
**Plugin Version:** 0.16.32
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Cast or Convert Datetime Columns Based on Guest Token Timezone:**\
Introduced timezone application functionality for datamart and end-user metric creation. Users can now toggle timezone adjustments for date-time columns via a new switch component in Datamart.
2. **CRUD on CockroachDB Datasource with API:**\
Added API support to create, read, update, and delete CockroachDB datasource configurations programmatically.
### Enhancements:
1. **SSH Tunneling Support for Redis:**\
Introduced SSH tunneling support for Redis connections, enhancing configuration options when creating company Redis instances.
2. **Dynamic Adjustment of Axis Limits in Charts:**\
Users can now dynamically adjust the lower and upper limits of the vertical axis in all charts with axes.
3. **Chart Actions Enhancement for Table Chart:**\
Added row redirection and column redirection options for table charts.
4. **Enhancement of Import Dashboard API:**\
Introduced `dashboardId` and `dashboardName` as parameters in the API.
5. **Support for Reflecting Embed Name While Creating an Empty Dashboard Embed:**\
Added an optional `isRenameDashboard` parameter to the dashboard creation functions, allowing users to conditionally rename dashboards during the creation process.
### Fixes:
1. **Export as PDF Download Speed:**\
Improved performance for exporting dashboards as PDF.
2. **Alias Mismatch After Editing Metrics in Imported Dashboards:**\
Resolved an issue where aliases did not match properly when users edited metrics by adding filters or sorting.
3. **Export Dashboard API Error Handling:**\
Enhanced error handling by introducing a specific error message for invalid dashboard IDs or workspace names, improving API response clarity.
4. **Boolean Dashboard Filter in Postgres:**\
Fixed issues with boolean filters in Postgres-backed dashboards.
5. **OpenSearch Connection Issue:**\
Fixed a connection issue affecting OpenSearch.
**Plugin Version:** 0.16.31
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API to Whitelist Domains:**\
We have introduced a new API endpoint `whitelist-domains` to manage whitelisted domains associated with a company.
2. **API for SMTP Settings:**\
We have introduced a new API endpoint `smtp-settings` to save and update company SMTP settings, improving email configuration management.
### Enhancements:
1. **Rotate Data App API using Self Auth:**\
Updated the authentication method for Data App API key rotation from the master token to the current API key.
2. **Customization of "Exporting Dashboard" Prompt Position:**\
Added a property in the dashboard component to customize the position of the Exporting Dashboard prompt:\
`exportMsgPosition: "bottom" | "bottom-left" | "bottom-right" | "center" | "top" | "top-left" | "top-right"`.
### Fixes:
1. **Cockroach DB:**\
Resolved SSL certificate verification and date filter issues.
2. **BigQuery:**\
Fixed an issue with underlying data in the time-series chart.
3. **OpenSearch:**\
Fixed a connection issue.
4. **Datamart:**\
Added unique name constraints in app and APIs.
5. **Data App API Keys:**\
Updated to accept `expiryTime` as a string instead of a number.
**Plugin Version:** 0.16.30
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **New Data Source - Cockroach DB:**\
Support has been added for Cockroach DB as a new data source.
2. **Import & Export Dashboard API:**\
API support has been added for exporting and importing dashboards.
3. **Include Metrics in Template Dashboard:**\
Metrics have been included in the template dashboard for the create dashboard embed API.
### Enhancements:
1. **Table Search Position Options:**\
Configurable search positioning has been introduced for table charts and components.
2. **Waterfall Chart:**\
Measures can now be treated as difference values by selecting the "Difference" option in the Waterfall Settings section.
3. **Fullscreen Trigger via Title Click in Embed:**\
A new prop, `enable-title-click-fullscreen={true}`, has been added to enable fullscreen mode when clicking the chart title.
### Fixes:
1. **Waterfall Chart:**\
Issues with chart labels have been resolved.
2. **ExpiryTime Type in Guest Token Creation & Rotate Token API:**\
Handling of the `expiryTime` parameter in `guestToken` and `guestTokenV2` functions has been improved to ensure consistent data types.
3. **Invite User & Resend Mail Flow:**\
Issues in the invite user and resend mail flow have been resolved.
**DataBrain Updates: API Documentation**
### Enhancements:
1. **Create Dashboard Embed API – Response field documented:**\
The [Create an Empty Dashboard Embed](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-dashboard-embed) API response now documents the `name` field. Successful responses from `POST /api/v2/data-app/dashboard-embeds` include `id`, `error`, and `name` (the embed configuration name, or `dashboardId` when `name` is not provided). Request examples and response examples in the docs have been updated accordingly.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **AI Suggestions for SQL Editor:**\
Connect your LLM to enable AI-powered suggestions for table names, schema names, and column names.
2. **Validation of Allowed Embeds in Guest Token Creation:**\
We have added a feature to validate allowed embeds during the process of guest token creation.
### Enhancements:
1. **Subtotals at all Hierarchy Levels in Pivot Table V3 Chart:**\
Enable the "Show for all Levels" toggle to display subtotals across all hierarchy levels.
2. **Individual Column Formatting for Table Charts:**\
We have added support for formatting columns individually in Table, Horizontal Table, Pivot V2 & V3 charts.
3. **Raw Values as Chart Labels in Waterfall Charts (V1 & V2):**\
Turn on the "Show Actual Value Label" toggle to view raw values in Chart Label instead of increase or decrease.
4. **Customizable Total Column in Waterfall Chart V2:**\
We have added support to customize the name of the "Total" column in Waterfall Chart V2.
### Fixes:
1. **Limit and Rows per Page Settings:**\
Resolved an issue where settings for limit and rows per page settings were not retained in the dashboard.
2. **Improved LLM Settings Behavior:**\
Model dropdown is enabled only after API key validation, model selection is enforced post-validation, the first validated LLM is auto-set as default, and redundant UI status messages have been removed.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Improved Join Handling in End-User Metric Creation:**\
Updated the join logic to apply joins only between selected tables and disabled column selection from tables that are not directly connected, reducing invalid joins and improving metric accuracy.\
For example, when a One-to-Many relationship is defined between Orders and Shipments, dragging a column from Shipments will surface only the Shipments and Orders tables for selection. (Gif 1)
2. **Revert Option to Default Date in Metric and Dashboard Filters:**\
Users can now switch back to the default date in both metric-level and dashboard-level filters.
### Enhancements:
1. **Settings Button Enhancement in Embed:**\
Added `settings-icon` prop to the `dbn-dashboard` component.
`settings-icon={JSON.stringify({name: 'random',iconSvg: 'svg'})}`
2. **PDF Table Header Wrapping:**\
Enabled text wrapping for table headers when downloading dashboards as PDFs.
3. **UI Styling Support for Pivot Table V3 Chart:**\
Added UI styling options to the Pivot Table V3 chart.
4. **Dynamic Label Positioning for Waterfall Charts:**\
Labels now dynamically adjust their position based on increases or decreases in values.
5. **Cumulative Start and End Labels for Waterfall Charts:**\
Added support for displaying cumulative start and cumulative end (running total) labels, making it easier to understand how individual increases or decreases impact the overall total. (Image 5)
6. **Font Size Customization for Tables and Underlying Data:**\
Users can now control font sizes via Chart Settings for UI-styled table charts, and via Theme Settings for table charts and underlying data views (popup and fullscreen), ensuring improved readability and visual consistency. (Images 6, 7)
### Fixes:
1. **Fullscreen and Download Metric Options in Embed:**\
Fixed an issue where Fullscreen and Download options were not visible in embedded dashboards containing merged metrics.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Sticky Dashboard Filters:** We've added a Sticky option to the Dashboard Filter in the `dbn-component`, allowing dashboard filters to remain fixed while scrolling. Prop: `is-sticky-dashboard-filters = {true}`
2. **Datamart & Semantic Layer Revamp:**\
We're introducing a Datamart revamp to improve scalability and simplify data modeling.
**What's changing:**
* **Define Relationships section:** Table relationships (Joins) and Cardinality will now be defined in the Datamart.
* **Configure Tenancy section:** Tenancy is configured first during Datamart creation to set up the base and Client ID mapping should be defined in Datamart
* **Datamart APIs** will support joins and client ID mapping
**Benefits:** cleaner models, consistent tenancy, reusable Datamarts, and simpler Semantic Layer setup.
### Enhancements:
1. **Palette Configuration for Dashboards:** We've added palette props to the `dbn-dashboard` component to set default palette used in dashboard and specify the ones which can be used in chart settings.
2. **Chart Color Configuration for App & End-User Metrics:** We have added an option in chart settings for users to configure chart colors. (Image 1)
3. **Year-over-Year Comparison in Single Value Cards:** Users can now compare the current month’s value with the same period from the previous year. (Image 2)
4. **Calculated Fields Support in Datamart APIs:** We have added Calculated fields support in Update Datamart and Create Datamart API. (Gif 1)
5. **Switch Y-Axis Option for Time-Series Charts:** We've added an option to switch the X-axis in time-series charts.
6. **Measure breakdown in Pie Chart for end users:** Added measure-based breakdown for Pie Charts for end users, where wedges are generated based on the number of measures.
7. **Never Repeat Option in Frequency of Scheduled Reports:** We have added 'Never Repeat' Option in Frequency of Scheduled Reports.
### Fixes:
1. **Join Query Support:** Fixed an issue to support joins that use `,` in queries along with filters.
2. **Horizontal Bar Chart Label Overlap:** Resolved an overlapping issue in horizontal bar charts where chart labels overlapped with Y-axis values.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Create Datamart API – Hide Table:** Added support for `tableList.isHide` to hide entire tables from the Datamart interface. Refer to the [Create Datamart API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datamart#:~:text=tableList.isHide,the%20datamart%20interface) documentation for details.
2. **Create Datamart API – Hide Table Column List:** Added support for `tableList.columns.isHide` to hide specific columns from the Datamart interface. Learn more in the [Create Datamart API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datamart#:~:text=tableList.isHide,the%20datamart%20interface) documentation.
3. **CRUD APIs for Datasource:** Introduced full CRUD API support for managing datasources. See the [Datasource API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datasource) documentation.
4. **Pie Chart – Measure Breakdown:** Added measure-based breakdown for Pie Charts, where wedges are generated based on the number of measures.
5. **Waterfall Chart V2:** Introduced Waterfall Chart V2 with cumulative value support.
6. **Multiple Scheduled Reports:** Enabled end users to create and manage multiple scheduled reports.
7. **API for Listing User-Created Reports:** Added API support to list user-created scheduled reports by embed. Refer to the [List Schedule Reports API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-schedule-reports-by-embed) documentation.
8. **Embed Renaming API:** Added API support to assign and update embed names. See the [Rename Embed API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/rename-embed) documentation.
### Enhancements:
1. **Dashboard Embed Metadata API:** Added new parameters to fetch additional embed metadata, including `createdAt`, `updatedAt`, `externalMetricId`, `dataAppId`, `embedId`, and `name`. Learn more in the List Embed API documentation.
2. **Whitelist Domain Support:** Added wildcard support and improved Top-Level Domain handling for whitelisted domains.
### Fixes:
1. **Whitelist Domain Validation:** Fixed issues related to incorrect Top-Level Domain handling in whitelisted domains.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Service Tokens + API Key Rotation:** You can now create and manage service tokens directly within the app, enabling secure API key rotation through the Data App for safer long-term usage.
2. **Dashboard Deletion via Embed Config:** Added support for dashboard deletion using the URL parameter: `isDeleteDashboard: true`
### Enhancements:
1. **CSV and XLSX Support in Scheduled Reports:** Users can now schedule reports in CSV and Excel (.xlsx) formats, expanding export flexibility in automated schedules.
### Fixes:
1. **Resolved Metric Loading Issue:** Fixed an issue where loading a metric caused the entire dashboard to load instead of just the selected metric.
2. **Dashboard Filters on Empty Dashboards:** Filters now work correctly even when a dashboard contains no visualizations.
3. **Schedule Report in Embed:** Scheduled reports within embedded dashboards now work contextually based on the selected dashboard and client.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Publish Metric API:** Added support to publish all metrics via API using the property `isPublished: true`.
2. **Update Datamart API:** Added support to update datamarts via API.
3. **Workspace APIs:** Added APIs for Create Workspace, Update Workspace, and List Workspaces.
### Enhancements:
1. **Embed Axis Color Properties:** Chart axis colors can now be customized using:
```json theme={"dark"}
{
"chartAppearance": {
"horizontalAxis": { "color": "#cd00e0ff", "axisColor": "#0009b6ff" },
"verticalAxis": { "color": "#b6a700ff", "axisColor": "#b60000ff" }
}
}
```
### Fixes:
1. **Filter Dropdown in Metric Creation:** Resolved issues affecting simple filter dropdown values.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Auto Joins in End-User Metric:** You can now set up auto joins in the Semantic layer. End users can drag and drop to create metrics from different tables seamlessly.
### Enhancements:
1. **LLM Model Selection in Settings:** You can now choose and configure your preferred LLM model (e.g., `gemini-2.5-flash`, `gemini-2.5-pro-preview`, etc.) directly in the LLM settings.
2. **Custom Field Support in End-User Metric Creation:** Added support for custom fields during end-user metric creation.
### Fixes:
1. **Bar Length:** Fixed an issue where bar lengths were not consistent.
2. **Optimized Embedded Dashboards for Mobile/Tablet:** Improved layout consistency for smaller screens, including better handling of Dashboard Filters, Filter Popups, and View Boards.
3. **Encryption in End-User Metric Creation:** Enabled encryption during end-user metric creation.
4. **Filter Value in MSSQL:** Resolved the “Metric already exists” error during end-user metric creation.
**DataBrain Updates: Features, Fixes**
### Features:
1. **User Defined Fields (UDF):** Easily customize dashboards with your own data fields — no schema changes needed. DataBrain now auto-detects and supports both common and client-specific fields as dynamic filters and chart axes for flexible, personalized insights.
### Fixes:
1. **Iceberg + Trino SQL:** Resolved a server error caused by empty or undefined filter values. Added validation to ensure all required fields are filled before adding a new filter.
2. **Metric Cards:** Removed extra spacing in Metric Cards and Full-Screen View.
3. **Invite User Settings:** Added validation for user invites.
4. **Alias Modification:** Fixed issues related to alias name updates.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Gemini LLM**: Added a new connector for LLMs — Gemini.
### Enhancements:
1. **Filter Elements for Fetch Metrics API**: Added a new parameter `isMetric=true` to the Fetch Metrics API.
2. **Prop for Download Dashboard as PDF**: Introduced a new embed prop `enable-download-all-pdf={true}` to enable dashboard PDF downloads.
3. **Naming Conventions & Methods in End User APIs**: Updated HTTP methods to `POST`, `GET`, `PUT`, and `DELETE` for improved consistency.
### Fixes:
1. **Trino**: Resolved a server error when creating a metric caused by “Zero-length delimited identifier not allowed.”
2. **Logs in Playground**: Implemented a logging mechanism in the playground environment for better traceability.
3. **Chat Mode**: Fixed query-related and limit issues in chat mode.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API Endpoint for End User Dashboard Creation**: End users can now create dashboards directly through the API.
2. **New Data Source – Trino**: Added support for a new data source — Trino.
3. **Single-Click Download for Metrics Data in Embed**: End users can now download the underlying data for all metrics with one click by adding the prop:\
`enable-download-csv="true"`
4. **Fullscreen Metrics in Embed**: Metrics can now fit fullscreen in embeds using the prop:\
`shouldFitFullScreen="true"`
### Enhancements:
1. **Support for Label and Hide Options in Datamart & Create Metric**: You can now add labels to columns and hide columns on the create metric page by configuring them in the Datamart layer.
2. **Variable Value Support for Next Preset Date Filter**: Added variable value support for the “Next” preset date option in metric and dashboard filters.
### Fixes:
1. **Removed Background Color from Dashboard PDFs**: Dashboard PDF exports no longer include unwanted background colors.
\*\*DataBrain Updates: Features, Enhancements, Fixes \*\*
### Features:
1. **Single Click Download for Metrics Data**: Users can now download the underlying data for all metrics with just one click.
### Enhancements:
1. **Customizable Fonts for Table Chart**: Added options to configure font family, font color, and font weight in table charts.
2. **UI Theming for Underlying Data**: Introduced settings to customize header text, background color, content text, spacing, and font weight for underlying data.
### Fixes:
1. **UI Theming Fixes**: Resolved inconsistencies in theme fonts, labels, and background styling in Single Select, Preset Date, and Range dropdowns.
2. **Metric Filter in Dashboard View**: Fixed issues affecting the proper functioning of metric filters in dashboard views.
3. **Datasource Logo in Dropdowns**: Datasource logos are now displayed alongside datasource names in dropdown menus.
4. **Auto Filter Reset Defaults**: Corrected issues where default values in Single Select and Multi Select auto filters were not resetting properly.
**Plugin Version:** 0.16.5
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Boards**: Users can now create multiple views of a dashboard based on applied dashboard filters and easily switch between them.
### Enhancements:
1. **Set Default Client Per Dashboard**: Users can set a default client for each dashboard.
2. **Edit Metric**: Users can edit a metric by clicking the edit icon next to the metric name.
3. **Lifetime Option in Single Value Card**: A new option, *Lifetime*, has been added to Single Value Cards to perform aggregate calculations without comparisons.
4. **Customize Dashboard Layout in UI Theming**: Users can now configure vertical and horizontal gaps for dashboard layouts in the UI Theming page.
5. **Height-Based Auto Pagination in Table Charts**: Table charts now support automatic pagination based on height, adjusting the number of rows dynamically.
6. **Prop for Breadcrumb (Drill Down) Color and Font Family**: Users can now add color and font family to breadcrumbs when drill down is enabled in embed.
7. **Prop to Change Badge Color of Multi-Select Filter**: Introduced a property for pill color in the multi-select badges in embed.
### Fixes:
1. **Updated Results Table for No Data**: The image displayed when a query returns no results in the Query Builder has been updated.
2. **Drill-Down Issue with Unselected Dimensions**: Fixed an issue where an unselected dimension appeared in the drill-down hierarchy.
3. **Date Filter Font Consistency**: Fixed font inconsistencies in date-based metric filters.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Rules Builder**: Users can now hide or unhide metrics based on selected charts.
### Enhancements:
1. **Download Properties & Full-Screen Mode in Embed Options**: Added the ability to download data without applying filters to the underlying data and introduced a full-screen option for an improved user experience.
2. **Separate Alignment for Table Chart Columns**: Users can now align table chart columns individually as Left, Center, or Right.
3. **'Next' Support in Dashboard & Metric Date Filters**: Users can now preset future date ranges using the *Next* option.
4. **Multi-Database Support**: Added support for multiple databases when configuring data sources.
***
### Fixes:
1. **Metric Filter Apostrophe Issue**: Resolved an issue where multi-select filters with values containing an apostrophe (`'`) were not working correctly.
2. **Redshift Column Aliases**: Fixed an issue where column aliases containing `#` caused errors.
3. **Dashboard Filter Defaults**: Fixed an issue with the Auto and Manual options in the default value setting of dashboard filters.
**DataBrain Updates: Enhancements, Fixes** :loudspeaker:
### Enhancements:
1. **'percentile\_cont' and 'percentile\_disc' Functions for Measures**: You can now calculate continuous and discrete percentiles using these new functions.
2. **Download Dashboard as PDF**: Users can now download dashboards in PDF format.
3. **Dropdown Multi-select Filter for String Columns in Table Chart**: A dropdown multi-select filter can now be added to any string column in a table chart.
4. **Trendline Support**: We have introduced trendline functionality in table charts using custom SQL.
***
### Fixes:
1. **Default option for LLMs**: You can now set any LLM as the default option.
2. **Metric Filter Styling Issue**: Fixed font and font size inconsistencies in date-type metric filters.
3. **Underlying Data Download in OpenSearch**: Resolved issues related to downloading underlying data in OpenSearch.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API Endpoint for Datamart**: Users can now perform CRUD operations on datamarts using the API endpoint.
2. **Hybrid (Stacked + Bar) Chart**: A new chart type, *Hybrid Bar*, has been introduced.
***
### Enhancements:
1. **Metric Filter Interaction**: Improved workflow for switching between 'Apply On' and 'Filter Options' in Metric Filters for smoother navigation.
2. **Gantt Chart Styling**: Added bar styling options for Gantt Chart, including Bar Height, Top Radius, and Bottom Radius.
***
### Fixes:
1. **Hide App Filter in Filter Box**: The App Filter is now hidden in the dashboard filter box to enhance security and ensure proper functionality.
2. **Elastic Search**: Fixed an issue that occurred when creating custom datasets.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Gantt Chart**: Introducing the Gantt Chart for enhanced timeline-based visualization of tasks and projects.
2. **Y Axis - Log Scale**: Added the ability to convert the Y-axis to a logarithmic scale for improved visualization of wide-ranging values.
3. **New Data Source - OpenSearch**: Now supporting OpenSearch as a data source, expanding your integration options.
4. **Optional Variable Filters**: Variable filters can now be made optional using square brackets in code blocks for greater flexibility.
5. **Click Action on Single Value Card**: Enable interactive experiences by configuring click actions on Single Value Cards.
***
### Enhancements:
1. **Multi-Select Y-Axis**: You can now enable multi-selection for the Y-axis in bar, line, and area charts.
2. **Underlying Data Download**: Added support to download filtered underlying data for deeper offline analysis.
3. **Badge Color in Table Chart**: Introduced the ability to set badge colors in table chart conditional formatting.
4. **Default Dynamic Dates in Filters**: Set default values like Today, Tomorrow, and Yesterday in single-date filters.
5. **Multi-Column Click Actions in Table Charts**: Configure click actions for multiple columns in table charts.
***
### Fixes:
1. **Switch Select Default Value**: Resolved inconsistencies in Switch Select options by setting a default value.
2. **Dynamic Properties in Descriptive Elements**: Fixed loading issues in dynamic properties across footnote, title, description, and long description.
3. **Athena Load Time Disparity**: Addressed inconsistencies in load time between Query Editor and Chart Builder for Athena data source.
4. **Dashboard Filter**: Ad the ability to clear default values in dashboard filters.
5. **Scheduled Reports**: Fixed formatting issues in PDF exports for scheduled reports.
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Drill Down Revamp**: We've updated the UI of Drill Down Feature to ensure better clarity and visibility.
2. **Custom SQL Revamp**: We've enhanced the Custom SQL interface to offer a cleaner editing experience and improved validation feedback for better query building. Users can write custom SQL queries and save them as Table Chart, Table Chart with Dynamic Table, New Chart or Custom Dataset.
3. **Single Value Card**: We've added alignment and font options, along with dynamic property support for sub-header text in the Single Value Card. String-based conditional formatting support has also been introduced.
4. **Metric Border Color**: Users can now specify the metric border color globally from the UI Theming page.
### Fixes:
1. **Filter Disappearance on Sync in Metric Page**: Resolved an issue with the variable metric filter for the Redshift data source.
2. **Custom Columns in Simple Filter**: Fixed an issue where custom columns were not appearing in the simple filter.
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Syntax Validation for Calculated Fields**: We've added an icon to validate the syntax of SQL queries when creating calculated fields.
2. **Background Color Option for Metric Summary**: You can now set a background color for the metric summary card.
3. **Letter Spacing, Line Height in Metric Summary Prompt**: You can now specify letter spacing (in px) and line height in the metric summary prompt.
4. **Delete Option for Custom Roles**: A delete option is now available for custom roles.
5. **Chart settings for chart title, axis labels, axis values, and legend** have been added globally under the 'UI Theming' section on the Embed Settings page.
### Fixes:
1. **Switch Y Axis Enablement with Individual Number Formatting**: When the "Switch Y-Axis" option is enabled, each measure now correctly applies its own number formatting settings.
**DataBrain Updates: Enhancements**
### Enhancements:
1. **Auto-suggest Joins on Create Metric with AI**: You can now automatically join data using AI suggestions.
2. **Auto-Select All in Multi-Select Filters**: We've added a toggle to automatically select all values in metric and dashboard filters by default.
3. **Variable Support in Custom Query of Metric Filter**: You can now pass the variable value from one metric filter into the custom query of another — for example, using the “Product Category” filter value in the “Product Name” filter.
4. **New Number Formatting Options**: We've introduced new number formatting options like “Thousands,” “Millions,” and “Billions”.
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Date Restriction Feature in Preset Date Dashboard Filters**: We have added an "Enable Restrictions" toggle to the Preset Date Dashboard filter, similar to the Metric Filter.
2. **OIDC Identity Provider (IDP) Support**: Users can now create an OIDC-based IDP for Single Sign-On (SSO) under MFA & SSO Settings
### Fixes:
1. **Dashboard UI Fix**: Resolved an issue where the 'Reset' button overlapped with other UI elements on the dashboard page.
2. **Report Scheduling**: Added user prompts for improved clarity and guidance during report scheduling.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **New Data Source – Athena**: We've added support for a new data source: Athena.
2. **Horizontal Combo Chart**: A new chart type has been introduced, similar to the combo multi-scale chart but arranged horizontally.
3. **Bubble Chart V2**: The updated version of the Bubble Chart now allows users to specify bubble size. You can now set a measure for bubble size and drag & drop measures into dimensions.
### Enhancements:
1. **Date Range Mapping for Single Value Card Comparison**: Single value cards now automatically reflect the selected dashboard date filter range. If "Lifetime" is chosen, the card uses the comparison value set in its settings.
2. **Grid Dividers in Merge Metric**: Users can now add grid dividers between different metrics and enhance them with background colors.
### Fixes:
1. Resolved an issue with the preset date dashboard filter in Firebolt.
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Add Alignment Option for Single-Value Card**: You can now align the value in Single-Value Cards.\
Navigate to Settings > Appearance > Customizations > Alignment for more control over layout.
### Enhancements:
1. **Table Chart Minimum Height**: Reduced the minimum height of Table Charts in dashboards for better space utilization and layout flexibility.
### Fixes:
1. **Download Array Datatype Column Values**: Fixed an issue where array-type column values were not downloaded correctly.
2. **Single Value Card Resizing**: Resolved inconsistencies in resizing behavior for Single-Value Cards.
3. **Progress V2 Number Formatting**: Addressed incorrect number formatting on upper limit when using dynamic properties.
4. **Combo Chart Duplicate Axis**: Fixed an issue where duplicate axes appeared in Combo Charts.
**DataBrain Update: Enhancements**
### Enhancements
1. **Complex Sort in Metrics**: Added a feature to generate SQL for custom sorting beyond the default lexicographical ASC and DESC provided by SQL.
2. **Role Permissions for Metric Elements**: Introduced an option to manage role-based permissions for metric elements.
3. **"All Clients" Option**: Added an "All Clients" selection on the metric creation page.
4. **Transpose Data in Table Charts**: Introduced a toggle to switch rows and columns in table charts.
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Metric Expression Support in Elements**: We have introduced metric expression support in elements, allowing users to compute values using metric ID.
2. **Added Variable Filter for Preset Date Filter**: Implemented a variable filter in the preset date option for dashboards.
### Fixes
1. **Improved Pagination on the Explore Data Page**: Fixed an issue where pagination did not display correctly, ensuring a smoother navigation experience.
2. **UI Update**: Resolved an issue with tooltips for better usability.
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Font Style Options in Axis Charts**: Added Font Family, Font Size, and Font Weight options for horizontal and vertical axis names
2. **Font Styling for Metric AI Summary**: Users can now customize font styles in the Metric AI Summary
3. **Text Wrap in Combo Multi-Scales Chart**: Users can now define a value to break text in the Y-axis name of the combo multi-scales chart
4. **Customize Date Format**: Users can now set their preferred date format for the date filter in the "UI Theming" page
### Fixes
1. **Explore Data**: Fixed a download issue in the Explore Data feature
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Sorting and Number Formatting for Pivot Table V2**: Added options for sorting and number formatting in Pivot Table V2
2. **Custom Value Redirection in Table Chart**: Users can now click on a specific value in the Table Chart to be redirected to a designated link
### Fixes
1. **UI Update**: Chart Tooltip settings will remain hidden until the "Label Tooltip" toggle is enabled
2. **Metric Alignment Fix**: Resolved an issue where metric alignment changed after exporting and importing a dashboard.
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Editability of Created Views in Custom Datasets**: Exploring the feasibility of enabling editing and deleting capabilities for previously created views within custom datasets.
2. **Enhanced Pivot Table V3**
3. **Improved UI for Table Chart Pagination**
4. **Metric Background Color in Single Value Card**: Users can now add a background color to Single Value Cards.
5. **Set Config**: User can now set Data Config Options in Embedded Dashboards.
### Fixes
1. **Fixed flickering issue in bar charts.**
2. **BigQuery Data Source Fixes**: Resolved issues with `GROUP BY`, single quotes in filters, and AI-powered query formatting.
**DataBrain Update: Features, Enhancements & Fixes**
### Feature:
1. **Datasource Sync API**: Exposed an API for syncing the datasource
### Enhancements:
1. **Dashboard Date Filter & Time-Series Chart Integration**: We have added support for mapping dashboard date filter options with time-series charts for improved synchronization
2. **Bar Styling for Combo Multi-Scales Chart**: Added a "Bar Styling" option to the combo multi-scales chart for better customization. This feature allows users to fine-tune the appearance of bars for improved visualization and readability with key Customization Options:
* Bar Width – Adjust the width of bars to control spacing and visual clarity
* Bar Top Radius – Round the top edges of bars for a softer, modern look
* Bar Bottom Radius – Customize the bottom edge roundness for a polished appearance
### Fixes:
1. **Bubble Chart in Firebolt**: Resolved an issue affecting the Bubble chart when using the Firebolt datasource
2. **UI Update (Fullscreen Dropdown Component)**: Fixed an inconsistency in dropdown behavior when in fullscreen mode
### DataBrain Update: Enhancements & Fixes
#### Enhancements
1. **Horizontal Chart:** Added Switch X-Axis and Switch Y-Axis features for improved flexibility
2. **Sankey Chart:** Introduced Switch Measure functionality for better customization
#### Fixes
1. Resolved an issue where the Switch X-Axis Dropdowns displayed removed dimension values
2. Fixed duplicate values appearing in the Filter Panel dropdown in Custom Query Mode
**DataBrain Updates: Features, Enhancements, Fixes**:
### Features:
1. **Rearrange Metric Filters**: You can now rearrange metric filters on the update/create metric page using drag-and-drop, making customization easier and more intuitive.
2. **Save a Custom Dataset (View) to Multi-Selected Datasource**: You can now save a custom dataset across multiple selected data sources, enabling seamless data management and greater flexibility. Refer to the document below:
3. **Support Fiscal Year in Date Filter**: You can now set up a custom fiscal year filter in DataBrain to filter data based on the Indian Financial Year. Refer to the documentation below:
4. **Easier Access to Frequently Used Tables**: Frequently used tables now appear at the top of the schema sidebar on the metric creation page, improving accessibility and efficiency.
### Enhancements:
1. **Adaptive formatting for Indian decimals**: The Indian Number System now considers values up to two decimal places.
2. **Enhanced Chart Controls for End Users**: End users can now access additional chart options, including Enable Cumulative Behavior, Dynamic Behavior, and Chart Zoom, for improved data visualization and interaction.
### Fixes:
1. **UI update**: We have enhanced the user experience by eliminating flickering when switching between the Charts Panel and Settings Panel, ensuring a smoother and more seamless transition.
2. **Improved Reset Password Flow**: Expired Reset Password links now immediately display a “Reset Password Link Expired” message, preventing unnecessary input.
3. **Date filter**: The Date Filter now accepts only four-digit years, preventing incorrect inputs.
**DataBrain Updates: Features, Enhancements, Fixes:**
**Features:**
1. **Archive Metrics**: End users can now archive metrics for better organization.
**Enhancements:**
1. **Copy Generated SQL with One Click**: A new "Copy" button allows you to easily copy the generated SQL query.
2. **Customizable Color Palettes**: Modify colors in existing palettes anytime to match your theme by clicking on the edit icon.
3. **Improved Dashboard and Metric Filters**: Added a "Clear All" option for Dashboard/Metric filters.
4. **Enhanced Table Charts**: Introduced an input field to customize view text in table charts.
**Fixes:**
1. **Drill Query Filtering**: Resolved an issue that previously prevented proper handling of number-type columns in drill query filters.
**Features, Enhancements, Fixes:**
### Features:
1. **Drill Down for Tree Map:** Introducing drill-down functionality in Tree Map charts! Click on a section to explore deeper levels of data effortlessly.
2. **Add RHS Custom SQL Support:** Added the ability to control how selected options from a dashboard dropdown are applied on the RHS of the `WHERE` clause. Use the `{{global_selected_values}}` variable to modify selected values dynamically (e.g., applying transformations like `CONCAT`).
3. **Chart Click Action with Metric:** Now, clicking on a metric within a chart allows seamless navigation to another related metric for enhanced data exploration.
4. **Add View Button in Table Chart:** Added a "View" button in table charts, enabling users to expand selected columns within a row for better data visibility.
### Enhancements:
1. **Adaptive Formatting – Indian Number System:** Added support for number formatting in the Indian system (e.g., lakh, crore) for improved readability.
### Features, Enhancements, Fixes:
#### Features:
1. **Footnote as a Rich Text Box:** Footnotes are now powered by a React text box, allowing you to add links, change colors, and apply formatting like bold and italics for better customization.
2. **Hide Dashboard Filter in Embed Code:** You can now control the visibility of dashboard filters in embedded dashboards. This is useful for cases where different user groups need different filter options. For example, US customers can see the US fiscal year, while Indian customers see the Indian fiscal year—without displaying unnecessary filters. Please refer the below link:
3. **Cumulative Option for Line and Area Charts:** A new "Cumulative" option has been added to Line and Area charts, accessible under Chart Settings > Appearance > Features > Cumulative for better trend analysis.
#### Enhancements:
1. **Open Dashboards & Metrics in a New Tab:** You can now right-click on a dashboard or metric from the homepage to open it in a new tab for easier navigation.
2. **UI Theming Update:** You now have the option to remove the stroke around metric cards for a cleaner visual experience.
**Features, Enhancements, Fixes:**
### Features:
1. **New Geo Region Map**: We’ve expanded our list of available geographic visualizations by adding an Indian states map, expanding our visualizing abilities.
2. **Preview Link Management**: Track all preview links generated for dashboards and delete those no longer needed for improved link management.
### Enhancements:
1. **Dynamic Property Support**: Added support for dynamic property implementation in the lower and upper limit setup.
2. **Clear All Option**: Easily clear all columns added in measures or dimensions with a single click using the "Clear All" functionality.
### Fixes:
1. **Date Restriction in Metric Filter**: Resolved an issue with date restrictions in the metric filter for accurate filtering.
2. **Time Series for MSSQL**: Fixed time series functionality for MSSQL to ensure proper data representation.
### Features, Enhancements, Fixes
#### **Features**
1. **New Progress Bar Chart**\
Introducing a progress bar chart with conditional formatting! It effectively handles cases where values exceed limits for accurate data representation.
3MB
2. **Merge Layouts**\
Easily merge multiple metrics and rearrange them with the same flexibility as the dashboard's custom layout.
6MB
3. **New Data Sources – Firebolt and SingleStore**\
Added support for Firebolt and SingleStore for enhanced data connectivity.
***
#### **Enhancements**
1. **Revamped Chart Panel in Create Metric Page**\
Charts are now grouped under categories, making it easier to find and search for the desired visualizations.
2MB
# Self hosted changelog
Source: https://docs.usedatabrain.com/changelog/self-hosted-changelog
**Self - Hosted Updates:** August 12th, 2026
**Image Version:** 1.2.32
**Plugin Version:** 0.16.65
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Default Aggregation for Users:** Admins can now configure a default aggregation for measures at the Datamart level, and the aggregate will be added by default for measures for end users. (Image 1)
2. **Default Sorting for Users:** Admins can now configure default metric sorting, allowing end users to view metrics sorted by measure in ascending or descending order. (Image 1)
3. **Mandatory Admin-created Filters with Custom Alias Support:** End users can rename dashboard or metric filters configured by the Admin.
4. **Sort Options in Dashboard and Metric Filters:** End users can use ASC/DESC sort options in dashboard and metric filters configured by the Admin. Admins can enable this using the **Allow Sorting** toggle. (Image 2, 3)
5. **Metric Filters for End Users:** End users can now add metric filters. The below guest token request body enables end-user metric filter creation:
```json theme={"dark"}
{
"params": {
"accessPermissions": {
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "schemaName.tableName",
"columns": ["columnName", "columnName"]
}
]
}
}
}
```
The `metricFilterColumns` setting ensures end users can create filters only on admin approved columns.
### Enhancements:
1. **Single Value Card Underlying Data Enhancement:** Added a toggle in the UI Theming page to show complete underlying data in fullscreen mode. (Image 4)
2. **Drill Down Enhancements:** Drill Down now retains chart settings such as renamed column aliases, measure aggregations, filters, sort order, joins, group by, calculated fields, and LIMIT clauses.
3. **Pagination Enhancement in Full Screen Mode:** Added the ability to control pagination for underlying data in full screen mode. (Image 4)
4. **Conditional Formatting Improvements:** Improved the conditional formatting workflow for table charts and Pivot Table Chart V3, making it easier to apply formatting rules to table columns. (Image 5)
5. **Log Scale Support for Horizontal Bar Charts:** Added a **Log Scale (Base 10)** toggle for horizontal bar charts, similar to the existing vertical bar chart option. (Image 6)
6. **Pivot Table Enhancements:** Added UI Styling section for Pivot Table Chart V1 and V2.
7. **Number Formatting Enhancement:** Increased the maximum supported limit for digits before the decimal point using custom SQL query.
8. **Dashboard Scroll Minimap Prop:** The dashboard scroll minimap is now disabled by default. It can be enabled using the prop: `enableDashboardMinimap: true`
### Fixes:
1. **Enhanced Mobile View:** Improved filter indication for applied and saved filters, and added a clear filter option for date filters.
2. **Bar Chart Underlying Data:** Resolved an issue where underlying data showed "No data found" when group by was enabled in bar charts.
3. **Trino Compatibility:** Implemented support for MEDIAN or PERCENTILE\_CONT functions compatible with Trino syntax in the DataBrain UI.
4. **Datamart Update API:** Resolved an issue where the update API failed due to invalid GraphQL while syncing the linked access tableList JSONB field.
5. **MSSQL/Fabric Query Fix:** Fixed an issue where SELECT DISTINCT metric queries failed because of a synthetic pagination ORDER BY clause.
**Image Version:** 1.2.31\
**Plugin Version:** 0.16.61
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Dashboard Filters in Scheduled Reports:**\
Added support for selecting dashboard filters and their values when configuring Scheduled Reports.
### Enhancements:
1. **Pivot Table V3 Enhancements:**\
Added support for hiding measure columns, choosing whether dimensions appear as hierarchical row levels or regular columns, renaming and reordering custom calculated measures, and displaying comma-separated distinct values at higher hierarchical levels.
2. **Dashboard Scroll Minimap:**\
Dense dashboards now show a compact overview of all metrics, your current position, and your progress through the dashboard. Click a metric in the minimap to jump directly to it, including metrics that have not rendered yet.
3. **Single Value Card Null Display:**\
When a column returns no value in a Single Value Card, users can now display either a blank space or `-`.
### Fixes:
1. **Chart Resolution and UI:**\
Improved ECharts resolution in the app, plugin, PDF downloads, and Scheduled Reports. Also fixed dropdown text wrapping issues.
2. **Data and SQL:**\
Fixed Trino custom measure SQL errors and underlying data issues where chart-point filters were not applied correctly.
3. **Plugin and Self-Hosted Deployments:**\
Fixed duplicate PDF downloads in self-hosted deployments, refactored the Save Layout and Reports flows in the plugin, and resolved token variable errors in Powerful LLM.
**Image Version:** 1.2.28\
**Plugin Version:** 0.16.56
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Microsoft Fabric Data Source:**\
Added support for Microsoft Fabric as a new data source.
2. **Multi-Dimension Support for End Users:**\
End users can now create metrics using multiple dimensions.
3. **[Dashboard Filters for End Users](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/token#paramsaccesspermissionsdashboardfiltercolumns):**\
End users can now create dashboard filters from client-specified columns. The following guest token request body enables end-user dashboard filter creation:
```json theme={"dark"}
{
"clientId": "client_id",
"dataAppName": "test_dataapp",
"params": {
"accessPermissions": {
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "schema_name.table_name",
"columns": ["col1", "col2", "col3"]
}
]
}
}
}
```
The `dashboardFilterColumns` setting ensures end users can create filters only on approved columns.
### Enhancements:
1. **Single Value Card Enhancement:**\
Added support for comparison values in the Single Value Card, along with a **Show Aggregated Value** toggle to display the aggregated value instead of the current period value.
2. **Date Filter Dependency Support:**\
Dashboard Filters (Auto & Custom), Metric Filters (Auto & Custom), and Dynamic Properties can now depend on Date Filters.
3. **Metric Card Appearance Controls:**\
Added options to show or hide the card stroke and hover shadow for individual metric cards. These settings are available in the **Save to Dashboard** dialog.
4. **Wrap Text Support for Y-Axis Labels:**\
Added a **Wrap Text** toggle under **Axis Label Setup** for vertical charts. Long category labels are now wrapped into an aligned column for improved readability.
### Fixes:
1. **Dashboard Export/Import:**\
Fixed an issue where Metric IDs referenced in Metric Expressions were not updated after importing a dashboard, resulting in connection errors.
2. **Schema Caching:**\
Improved schema caching performance for data sources containing 500+ databases.
3. **Chart Legend Colors:**\
Fixed an issue where legend colors were not applied correctly when the dimension column was of INT data type.
4. **Table Chart Number Formatting:**\
Fixed an issue where number formatting was not applied to the value 0 in Table Charts.
Regards,\
**The DataBrain Team.**
**Image Version:** 1.2.25\
**Plugin Version:** 0.16.55
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **GBP Formatting Option:**\
Users can now format numeric values in GBP for supported chart types.
2. **PDF Export Date Formatting:**\
Users can now customize the date format used in exported PDFs.
3. **Line Breaks in Table Chart:**\
We have added **Allow Line Breaks** under **Chart Settings > UI Styling > Enable Content Text Wrap**. When enabled, newline characters from raw data are preserved.
4. **Conditional Formatting for Formatted Values:**\
We have added an option to compare conditional formatting rules against either **Raw Data** or **Formatted Data**. The **Formatted Data** option is available only when number formatting is applied to the selected column.
5. **Dashboard Range Filter Enhancement:**\
Dashboard range filters now support cases where only a minimum or maximum value is provided.
6. **Adding Tenancy Column to Datasource Page:**\
Added a **Tenancy** column on the **Datasource** page to display each datasource's tenancy as a badge.
### Fixes:
1. **Pivot Table V3 Downloads:**\
Fixed an issue where Pivot Table V3 downloads did not include calculated measures from Pivot Settings.
2. **Athena Dashboard Metric Download:**\
Fixed an issue in the Athena dashboard metric download flow when a row limit was applied.
3. **Datamart Table Selection:**\
Fixed an issue in Datamart table selection where **Select All Tables** selected all datamart tables instead of only the filtered search results.
Regards,\
**The DataBrain Team.**
**Image Version:** 1.2.24\
**Plugin Version:** 0.16.51
**DataBrain Updates: Enhancements, Fixes** 📢
### Enhancements:
1. **Tooltip Dotted Data Point Line:**\
We have implemented the ability to manage dotted data point lines in chart settings.
2. **Styling the Tooltip Container:**\
We have added a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** to style the tooltip card, including padding, border radius, background color, and border color.
3. **Hide the Adjust Spacing Feature in Customize Layout:**\
We have included a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** to hide the **Adjust Spacing** feature in the **Customize Layout** section.
4. **Display All Chart Settings:**\
We have added a prop that bypasses the default chart settings and displays **[all possible settings](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference#custom-chart-settings-reference)**, unless otherwise configured through **[custom-chart-settings](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference#custom-chart-settings-reference)**.
5. **Customize Available Chart Types in End User Create Metric:**\
We have added a **[prop](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)** that allows users to customize the available chart types in the **End User Create Metric** feature.
6. **Export As PDF Server Events:**\
We have added server events to monitor the initiation and completion of the **Export As PDF** operation.
7. **Client Dropdown Visibility for Editor Users:**\
Added a **View Clients** permission under the Dashboard section in Roles. This permission controls the visibility of the client dropdown in multi-tenancy scenarios on Dashboard and Create Metric pages.
8. **Hide Enabled Columns for Respective Roles in Datamart:**\
Columns can now be hidden for specific roles when the **Hide To** function is enabled.
### Fixes:
1. **Update Dashboard API Error Message:**\
The API now returns a proper error message instead of a 500 error for an invalid `workspaceName`.
2. **Pivot V3 Calculated Columns:**\
We have resolved an issue where exponent-type numeric data, such as `1.91618e-11`, was treated as `-`.
3. **Range Filter:**\
Fixed an issue where underlying data was not filtered correctly when a range filter was applied.
Regards,\
**The DataBrain Team.**
**Image Version:** 1.2.18\
**Plugin Version:** 0.16.43
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **[Update Dashboard Filter in Update Dashboard API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-workspace-dashboards):**\
Support has been added for updating dashboard filters via the `Create Dashboard Embed API`.
2. **Global Search Feature:**\
Users can now search for any workspace, dashboard, or metric within their account.
### Enhancements:
1. **Dashboard Element Font Color in UI Theming Page:**\
Added support for customizing dashboard element font colors within the UI theming page.
2. **Dashboard Component Customization:**\
Introduced new props for:
* **[Controlling dashboard component padding](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)**
* **[Customizing top CTA buttons (Settings, Create Metric)](https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference)**
### Fixes:
1. **Scheduling & Formatting**
* Added support for scheduling reports in minutes.
* Resolved issues with duration-based conditional formatting.
2. **Pivot Table Improvements (V2 & V3)**
* Fixed rendering issues when using multiple dimensions.
* Corrected incorrect (0) values appearing in numerical dimensions.
3. **Dashboard UI & Layout Fixes**
* Fixed overlapping axis labels in horizontal bar charts (specifically for embeds).
* Resolved alignment issues in single value cards.
* Fixed an issue where font sizes would randomly reduce.
* Removed left padding in top-level filters.
4. **Dropdown & Data Sync Issues**
* Fixed the client dropdown not reflecting updated primary key changes.
* Resolved missing dropdown options in the dashboard view.
5. **SQL Editor:**\
Fixed an issue where comments were being removed during execution due to auto-formatting.
6. **Authentication & Data Integrity**
* Fixed expired guest token issues occurring in scheduled email reports.
* Resolved duplicate column issues during MSSQL metric creation.
7. **Datamart & Metric Consistency:**\
Fixed an issue where deleted datamart columns continued to appear in the network tab, which caused custom columns to show connection errors and invalid metrics to expose the fullscreen action.
**Image Version:** 1.2.16\
**Plugin Version:** 0.16.38
**DataBrain Updates: Features, Enhancements, Fixes** 📢
### Features:
1. **Alerts:**\
We have introduced a new feature, *Alerts*, which notifies users when there is an error in the data source connection or when a datamart is broken, making the dashboard unviewable.
### Enhancements:
1. **Color Selection from Colors Tab:**\
Users can now drag and reorder colors directly from the Colors tab.
2. **Context Window Indicator in AI Copilot:**\
Displays token usage per session (input and output). The limit varies by LLM and determines how much conversation can be retained. Once reached, the chat cannot continue.
3. **Delete Datamart API:**\
Added validation and improved error messaging to prevent the deletion of datamarts that are connected to a workspace.
### Fixes:
1. **Pivot Table V3:**\
Fixed an issue where conditional formatting was not rendering when a suffix was applied.
2. **Horizontal Bar Chart:**\
Added support for the Group By functionality.
3. **Elasticsearch:**\
Fixed issues related to schema sync and index handling.
4. **Cdb:**\
Fixed an issue with the stable build for fresh installations using a new database.
**Image Version:** 1.2.13\
**Plugin Version:** 0.16.35
**DataBrain Updates: Features, Enhancements, Fixes** 📢
### Features:
1. **[Multiple Datamart Connection Support](https://docs.usedatabrain.com/guides/workspace/multi-datamart-workspace):**\
Introduced multi-datamart support, allowing users to select and manage multiple datamarts.
2. **[CRUD API Support for Semantic Layer](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/semantic-layer-api):**\
Users can now **[create](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-semantic-layer)**, **[rename and update](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-semantic-layer)**, and **[delete](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-semantic-layer)** the Semantic Layer via APIs.
3. **[Delete Workspace API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-workspace):**\
Introduced a new DELETE endpoint to enable workspace deletion via API.
### Enhancements:
1. **Pivot Table Chart V3 Calculated Fields:**\
Added support for custom calculated measures, allowing users to create and edit calculated columns.
2. **Add Conditional Formatting Support to Pivot Table V3:**\
Introduced conditional styling with dynamic badge colors and background styles.
3. **[Refinement of List Datamarts API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-datamarts):**
We have introduced an `expandDetails` option to the Datamart List API, enabling users to control the inclusion of detailed properties in responses.
### Fixes:
1. **Pagination Sync Issue in Table Charts:**\
Fixed an issue where the default row size option was not in sync with the pagination value for server-side pagination-enabled table charts.
2. **Plugin Manage Metrics: Messaging & Settings Access:**\
When all metrics are hidden, an appropriate message will now be displayed. The settings/manage metrics button remains accessible even when all metrics are hidden.
3. **Addition of Server Events in Embed:**\
Added server-side event tracking for key user actions, including metric creation/editing, data exploration (search, table selection, drag-and-drop, aggregation), chart changes, dashboard interactions (filters, manage metrics, layout), and exports/downloads.
4. **Retaining Primary Database Selection in Update Datamart:**\
Ensured that the primary database selection is preserved during the Update Datamart operation.
**Image Version:** 1.2.11\
**Plugin Version:** 0.16.34
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Chart Appearance and Chart Actions Props for End Users:**\
We have added properties to the `dbn-dashboard` component that set default values for certain chart settings when a user creates a metric. Additionally, we have introduced properties for each of these settings that can lock the values, making them non-configurable for end users.
2. **Wildcard Support for OpenSearch:**\
We have introduced wildcard syntax support for datamart tables, allowing users to specify flexible patterns when creating or updating tables.
3. **Workspace LLM Configuration via API:**\
We have introduced optional LLM integration in workspace creation and update processes, allowing users to specify an LLM by name.
4. **User-Defined Click Action on Charts:**\
We have introduced a `chartClickFunction` prop to enable custom click actions on charts. The **Pass Complete Data to Function** option allows you to pass the entire row data to the function, enabling dynamic customization of the panel content through the prop.
***
### Enhancements:
1. Admin users can now delete data apps and embeds directly from the UI.
2. **Median as an Aggregate Function:**\
We have introduced support for the `MEDIAN` aggregate function for measures. Users can now use `MEDIAN` for numeric column aggregation, enhancing data analysis capabilities.
3. Newly created or added embeds now appear at the top of the list under Data Apps.
4. **Extended timezone functionality to dashboard and metric filters** for ClickHouse, Trino, Redshift, CockroachDB, PostgreSQL, and MSSQL data sources.
5. **End User Chart Click Function Enhancement:**\
Added support to send the entire clicked row data instead of just a specific value:
* When all data is passed:
* For Table and Single Val: `{ columnName: value, }` e.g. `{"product name": "Product A1", "price": 4.444}`
* For Tree Map and Sankey: `{ name: xVal, value: yVal }`
* For others: `{ name: xVal, value: yVal, columnName: colName }`
6. Added support to import data files in the dashboard embedding API.
7. **Adding Flag in Connection Form for MSSQL Read Replica:**\
We have introduced a `readOnlyIntent` checkbox option in the MSSQL integration configuration, allowing users to connect as a read replica for read-only operations.
### Fixes:
1. Fixed datetime issues in Trino.
2. **Fixed an issue with chart reset in in-app and plugin views:**\
When updating already applied popup filters, charts in the dashboard were resetting before clicking Apply.
3. Fixed issues with using the percentile function for measures in embeds.
4. Fixed connection errors with metrics that include custom SQL queries or calculated fields.
5. Fixed an issue with the OpenSearch alias for end-user metric creation.
**Image Version:** 1.2.10\
**Plugin Version:** 0.16.33
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Create Empty Dashboard Embed API:**\
We have introduced a prop that allows users to pass data from the Export API response when creating an empty dashboard embed.
2. **Export Embedded Dashboard API:**\
We have introduced an endpoint to export embed data, enhancing data retrieval capabilities for users.
### Enhancements:
1. **Description and Details for Embeds:**\
We have added **Description** and **Details** fields for embeds.
### Fixes:
1. We have optimized the bundle size of the plugin.
**Image Version:** 1.2.9\
**Plugin Version:** 0.16.32
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Cast or Convert Datetime Columns Based on Guest Token Timezone:**\
Introduced timezone application functionality for datamart and end-user metric creation. Users can now toggle timezone adjustments for date-time columns via a new switch component in Datamart.
2. **CRUD on CockroachDB Datasource with API:**\
Added API support to create, read, update, and delete CockroachDB datasource configurations programmatically.
3. **Readiness Endpoints for Self-Hosted Deployments:**\
Introduced health check endpoints to monitor application status.
### Enhancements:
1. **SSH Tunneling Support for Redis:**\
Introduced SSH tunneling support for Redis connections, enhancing configuration options when creating company Redis instances.
2. **Dynamic Adjustment of Axis Limits in Charts:**\
Users can now dynamically adjust the lower and upper limits of the vertical axis in all charts with axes.
3. **Chart Actions Enhancement for Table Chart:**\
Added row redirection and column redirection options for table charts.
4. **Enhancement of Import Dashboard API:**\
Introduced `dashboardId` and `dashboardName` as parameters in the API.
5. **Support for Reflecting Embed Name While Creating an Empty Dashboard Embed:**\
Added an optional `isRenameDashboard` parameter to the dashboard creation functions, allowing users to conditionally rename dashboards during the creation process.
### Fixes:
1. **Export as PDF Download Speed:**\
Improved performance for exporting dashboards as PDF.
2. **Alias Mismatch After Editing Metrics in Imported Dashboards:**\
Resolved an issue where aliases did not match properly when users edited metrics by adding filters or sorting.
3. **Export Dashboard API Error Handling:**\
Enhanced error handling by introducing a specific error message for invalid dashboard IDs or workspace names, improving API response clarity.
4. **Boolean Dashboard Filter in Postgres:**\
Fixed issues with boolean filters in Postgres-backed dashboards.
5. **OpenSearch Connection Issue:**\
Fixed a connection issue affecting OpenSearch.
**Image Version:** 1.2.8\
**Plugin Version:** 0.16.31
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API to Whitelist Domains:**\
We have introduced a new API endpoint `whitelist-domains` to manage whitelisted domains associated with a company.
2. **API for SMTP Settings:**\
We have introduced a new API endpoint `smtp-settings` to save and update company SMTP settings, improving email configuration management.
### Enhancements:
1. **Rotate Data App API using Self Auth:**\
Updated the authentication method for Data App API key rotation from the master token to the current API key.
2. **Customization of "Exporting Dashboard" Prompt Position:**\
Added a property in the dashboard component to customize the position of the Exporting Dashboard prompt:\
`exportMsgPosition: "bottom" | "bottom-left" | "bottom-right" | "center" | "top" | "top-left" | "top-right"`.
### Fixes:
1. **Cockroach DB:**\
Resolved SSL certificate verification and date filter issues.
2. **BigQuery:**\
Fixed an issue with underlying data in the time-series chart.
3. **OpenSearch:**\
Fixed a connection issue.
4. **Datamart:**\
Added unique name constraints in app and APIs.
5. **Data App API Keys:**\
Updated to accept `expiryTime` as a string instead of a number.
**Image Version:** 1.2.7\
**Plugin Version:** 0.16.30
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Create & Rotate Service Token API:**\
We have introduced service token management with two new endpoints for creating and rotating service tokens. Validation schemas have also been added for service token operations to ensure data integrity.
2. **New Data Source - Cockroach DB:**\
Support has been added for a new data source: Cockroach DB.
3. **Import & Export Dashboard API:**\
API support has been added for exporting and importing dashboards.
4. **Include Metrics in Template Dashboard:**\
We have included metrics to the template dashboard for create dashboard embed API.
5. **Create Account using API:**\
We have introduced endpoints for creating self-hosted admin accounts and generating JWT tokens, enhancing support for self-hosted instances: Create Admin Account, Create Admin JWT (Self-Hosted), Reset Admin Password (Self-Hosted).
### Enhancements:
1. **Table Search Position Options:**\
Configurable search positioning has been introduced for table charts and components.
2. **Waterfall Chart:**\
Measures can now be treated as difference values by selecting the Difference option in the Waterfall Settings section.
3. **Fullscreen Trigger via Title Click in Embed:**\
A new prop: `enable-title-click-fullscreen={true}`, has been added to enable fullscreen mode when clicking the chart title.
### Fixes:
1. **Waterfall Chart:**\
Issues with chart labels have been resolved.
2. **ExpiryTime Type in Guest Token Creation & Rotate Token API:**\
Handling of the `expiryTime` parameter in guestToken and guestTokenV2 functions has been improved to ensure consistent data types.
3. **Invite User & Resend Mail Flow:**\
Issues in the invite user and resend mail flow have been resolved.
**Image Version:** 1.2.4\
**Plugin Version:** 0.16.28
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Timezone in Query Execution from Guest Token Parameters:**\
We have implemented a feature to set timezone in query execution using guest token parameters.
2. **Added BYOD Support for CockroachDB:**\
Added BYOD support for CockroachDB (connect your own Cockroach instance).
3. **AI Suggestions for SQL Editor:**\
Connect your LLM to enable AI-powered suggestions for table names, schema names, and column names.
4. **Validation of Allowed Embeds in Guest Token Creation:**\
We have added a feature to validate allowed embeds during the process of guest token creation.
### Enhancements:
1. **Subtotals at All Hierarchy Levels in Pivot Table V3 Chart:**\
Enable the "Show for all Levels" toggle to display subtotals across all hierarchy levels.
2. **Individual Column Formatting for Table Charts:**\
We have added support for formatting columns individually in Table, Horizontal Table, Pivot V2 & V3 charts. (Image 2)
3. **Raw Values as Chart Labels in Waterfall Charts (V1 & V2):**\
Turn on the "Show Actual Value Label" toggle to view raw values in chart labels instead of increase or decrease. (Image 3)
4. **Customizable Total Column in Waterfall Chart V2:**\
We have added support to customize the name of the "Total" column in Waterfall Chart V2. (Image 4)
### Fixes:
1. **Dashboard Row Limit Persistence:**\
Resolved an issue where settings for limit and rows per page were not retained in the dashboard.
2. **Improved LLM Settings Behavior:**\
Model dropdown is enabled only after API key validation, model selection is enforced post-validation, the first validated LLM is auto-set as default, and redundant UI status messages have been removed.
**Image Version:** 1.2.3\
**Plugin Version:** 0.16.23
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Improved Join Handling in End-User Metric Creation:**\
Updated the join logic to apply joins only between selected tables and disabled column selection from tables that are not directly connected, reducing invalid joins and improving metric accuracy.\
For example, when a One-to-Many relationship is defined between Orders and Shipments, dragging a column from Shipments will surface only the Shipments and Orders tables for selection. (Gif 1)
2. **Revert Option to Default Date in Metric and Dashboard Filters:**\
Users can now switch back to the default date in both metric-level and dashboard-level filters.
### Enhancements:
1. **Settings Button Enhancement in Embed:**\
Added `settings-icon` prop to the `dbn-dashboard` component.
`settings-icon={JSON.stringify({name: 'random',iconSvg: 'svg'})}`
2. **PDF Table Header Wrapping:**\
Enabled text wrapping for table headers when downloading dashboards as PDFs.
3. **UI Styling Support for Pivot Table V3 Chart:**\
Added UI styling options to the Pivot Table V3 chart.
4. **Dynamic Label Positioning for Waterfall Charts:**\
Labels now dynamically adjust their position based on increases or decreases in values.
5. **Cumulative Start and End Labels for Waterfall Charts:**\
Added support for displaying cumulative start and cumulative end (running total) labels, making it easier to understand how individual increases or decreases impact the overall total. (Image 5)
6. **Font Size Customization for Tables and Underlying Data:**\
Users can now control font sizes via Chart Settings for UI-styled table charts, and via Theme Settings for table charts and underlying data views (popup and fullscreen), ensuring improved readability and visual consistency. (Images 6, 7)
7. **Encryption, Headers, and Documentation:**\
Updated filter encryption to use Company ID and added `x-authorization` header support for proxy authentication keys.
### Fixes:
1. **Fullscreen and Download Metric Options in Embed:**\
Fixed an issue where Fullscreen and Download options were not visible in embedded dashboards containing merged metrics.
**Image Version:** 1.2.0\
**Plugin Version:** 0.16.18
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Create Datamart API – Hide Table:** Added support for `tableList.isHide` to hide entire tables from the Datamart interface. Refer to the [Create Datamart API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datamart#:~:text=tableList.isHide,the%20datamart%20interface) documentation for details.
2. **Create Datamart API – Hide Table Column List:** Added support for `tableList.columns.isHide` to hide specific columns from the Datamart interface. Learn more in the [Create Datamart API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datamart#:~:text=tableList.isHide,the%20datamart%20interface) documentation.
3. **CRUD APIs for Datasource:** Introduced full CRUD API support for managing datasources. See the [Datasource API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datasource) documentation.
4. **Pie Chart – Measure Breakdown:** Added measure-based breakdown for Pie Charts, where wedges are generated based on the number of measures.
5. **Waterfall Chart V2:** Introduced Waterfall Chart V2 with cumulative value support.
6. **Multiple Scheduled Reports:** Enabled end users to create and manage multiple scheduled reports.
7. **API for Listing User-Created Reports:** Added API support to list user-created scheduled reports by embed. Refer to the [List Schedule Reports API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-schedule-reports-by-embed) documentation.
8. **Embed Renaming API:** Added API support to assign and update embed names. See the [Rename Embed API](https://docs.usedatabrain.com/developer-docs/helpers/api-reference/rename-embed) documentation.
### Enhancements:
1. **Dashboard Embed Metadata API:** Added new parameters to fetch additional embed metadata, including `createdAt`, `updatedAt`, `externalMetricId`, `dataAppId`, `embedId`, and `name`. Learn more in the List Embed API documentation.
2. **Whitelist Domain Support:** Added wildcard support and improved Top-Level Domain handling for whitelisted domains.
### Fixes:
1. **Whitelist Domain Validation:** Fixed issues related to incorrect Top-Level Domain handling in whitelisted domains.
**Image Version:** 1.1.140\
**Plugin Version:** 0.16.16
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Service Tokens and API Key Rotation:** You can now create and manage service tokens within the app for improved security and API lifecycle management. This enables API key rotation directly through the Data App for safer long-term usage.
2. **Dashboard Deletion via Embed Config:** Added support for dashboard deletion using the URL parameter:`"isDeleteDashboard": true`
### Enhancements:
1. **CSV and XLSX Support in Scheduled Reports:** Users can now schedule reports in CSV and Excel (.xlsx) formats, expanding export flexibility in automated schedules.
### Fixes:
1. **Resolved Metric Loading Issue:** Fixed an issue where loading a metric caused the entire dashboard to load instead of only the selected metric.
2. **Dashboard Filters on Empty Dashboards:** Filters are now supported even on dashboards with no visualizations.
3. **Schedule Report in Embed:** Scheduling reports through embedded dashboards now works contextually based on the selected dashboard and client.
**Image Version:** 1.1.139\
**Plugin Version:** 0.16.14
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Auto Joins in End-User Metric:** You can now set up auto joins in the Semantic layer. End users can drag and drop to create metrics from different tables seamlessly.
2. **Publish Metric API:** Added support to publish all metrics via API using the property `isPublished: true`.
3. **Update Datamart API:** Added support to update datamarts via API.
4. **Workspace APIs:** Added APIs for Create Workspace, Update Workspace, and List Workspaces.
### Enhancements:
1. **LLM Model Selection in Settings:** You can now choose and configure your preferred LLM model (e.g., `gemini-2.5-flash`, `gemini-2.5-pro-preview`, etc.) directly in the LLM settings.
2. **Custom Field Support in End-User Metric Creation:** Added support for custom fields during end-user metric creation.
3. **Embed Axis Color Properties:** Chart axis colors can now be customized using:
```json theme={"dark"}
{
"chartAppearance": {
"horizontalAxis": { "color": "#cd00e0ff", "axisColor": "#0009b6ff" },
"verticalAxis": { "color": "#b6a700ff", "axisColor": "#b60000ff" }
}
}
```
### Fixes:
1. **Filter Dropdown in Metric Creation Page:** Resolved issues with simple filter dropdown values.
2. **Bar Length:** Fixed an issue where bar lengths were not consistent.
3. **Optimized Embedded Dashboards for Mobile/Tablet:** Improved layout consistency for smaller screens, including better handling of Dashboard Filters, Filter Popups, and View Boards.
4. **Encryption in End-User Metric Creation:** Enabled encryption during end-user metric creation.
5. **Filter Value in MSSQL:** Resolved the “Metric already exists” error during end-user metric creation.
**Image Version:** 1.1.137\
**Plugin Version:** 0.16.12
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Gemini LLM:** Added a new connector for LLMs — Gemini.
2. **User Defined Fields (UDF):** Easily customize dashboards with your own data fields — no schema changes needed. DataBrain now auto-detects and supports both common and client-specific fields as dynamic filters and chart axes for flexible, personalized insights.
### Enhancements:
1. **Filter Elements for Fetch Metrics API:** Added a new parameter `isMetric=true` in the API to filter metric-level responses.
2. **Prop for Download Dashboard as PDF:** Added a new embed prop `enable-download-all-pdf={true}` to allow exporting dashboards as PDF files.
3. **Naming Conventions & Methods in End User APIs:** Updated HTTP methods to include `POST`, `GET`, `PUT`, and `DELETE`.
### Fixes:
1. **Trino:** Resolved a server error when creating a metric due to “Zero-length delimited identifier not allowed”.
2. **Logs in Playground:** Implemented a logging mechanism in the playground environment.
3. **Chat Mode:** Fixed query-related and limit issues in chat mode.
4. **Metric Cards:** Removed extra spacing in Metric Cards and Full-Screen View.
5. **Invite User Settings:** Added validation for user invites.
6. **Alias Modification:** Fixed issues related to alias name updates.
**Image Version:** 1.1.136\
**Plugin Version:** 0.16.8
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API Endpoint for End User Dashboard Creation**: End users can now create dashboards directly through the API.
2. **New Data Source – Trino**: Added support for a new data source — Trino.
3. **Single-Click Download for Metrics Data in Embed**: End users can now download the underlying data for all metrics with one click by adding the prop:\
`enable-download-csv="true"`
4. **Fullscreen Metrics in Embed**: Metrics can now fit fullscreen in embeds using the prop:\
`shouldFitFullScreen="true"`
5. **Private & Publish End User Metric in Embed Dashboard**: You can now use `userIdentifier` inside the params object to uniquely identify end users in embedded dashboards.
### Enhancements:
1. **Customizable Fonts for Table Chart**: Added options to configure font family, font color, and font weight in table charts.
2. **UI Theming for Underlying Data**: Introduced settings to customize header text, background color, content text, spacing, and font weight for underlying data.
3. **Support for Label and Hide Options in Datamart & Create Metric**: You can now add labels to columns and hide columns on the create metric page by configuring them in the Datamart layer.
4. **Enhance Gantt Chart**: You can now add additional dimensions to the tooltip of Gantt charts.
5. **Variable Value Support for Next Preset Date Filter**: Added variable value support for the “Next” preset date option in metric and dashboard filters.
### Fixes:
1. **Percentile Continuous and Percentile Discrete**: Resolved issues with the `Partition By` and `Value` fields in the Percentile function.
2. **End User Metric Creation**: Fixed the loader issue in chart view and problems related to the distinct option in dimensions.
3. **Unpublished Metrics**: Resolved issues affecting metric listing and deletion.
**Image Version** : 1.1.134\
**Plugin Version** : 0.16.2
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Boards**: Users can now create multiple views of a dashboard based on applied dashboard filters and easily switch between them.
### Enhancements:
1. **Set Default Client Per Dashboard**: Users can set a default client for each dashboard.
2. **Edit Metric**: Users can edit a metric by clicking the edit icon next to the metric name.
3. **Lifetime Option in Single Value Card**: A new option, *Lifetime*, has been added to Single Value Cards to perform aggregate calculations without comparisons.
4. **Customize Dashboard Layout in UI Theming**: Users can now configure vertical and horizontal gaps for dashboard layouts in the UI Theming page.
5. **Height-Based Auto Pagination in Table Charts**: Table charts now support automatic pagination based on height, adjusting the number of rows dynamically.
6. **Prop for Breadcrumb (Drill Down) Color and Font Family**: Users can now add color and font family to breadcrumbs when drill down is enabled in embed.
7. **Prop to Change Badge Color of Multi-Select Filter**: Introduced a property for pill color in the multi-select badges in embed.
### Fixes:
1. **Updated Results Table for No Data**: The image displayed when a query returns no results in the Query Builder has been updated.
2. **Drill-Down Issue with Unselected Dimensions**: Fixed an issue where an unselected dimension appeared in the drill-down hierarchy.
3. **Date Filter Font Consistency**: Fixed font inconsistencies in date-based metric filters.
**Image Version** : 1.1.131\
\*\*Plugin Version \*\*: 0.15.150
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **'percentile\_cont' and 'percentile\_disc' Functions for Measures**: You can now calculate continuous and discrete percentiles using these new functions.
2. **Download Dashboard as PDF**: Users can now download dashboards in PDF format.
3. **Dropdown Multi-select Filter for String Columns in Table Chart**: A dropdown multi-select filter can now be added to any string column in a table chart.
4. **Trendline Support**: We have introduced trendline functionality in table charts using custom SQL.
***
### Fixes:
1. **Default option for LLMs**: You can now set any LLM as the default option.
2. **Metric Filter Styling Issue**: Fixed font and font size inconsistencies in date-type metric filters.
3. **Underlying Data Download in OpenSearch**: Resolved issues related to downloading underlying data in OpenSearch.
\*\*Image Version \*\*: 1.1.129\
\*\*Plugin Version \*\*: 0.15.143
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **API Endpoint for Datamart**: Users can now perform CRUD operations on datamarts using the API endpoint.
2. **Hybrid (Stacked + Bar) Chart**: A new chart type, *Hybrid Bar*, has been introduced.
***
### Enhancements:
1. **Metric Filter Interaction**: Improved workflow for switching between 'Apply On' and 'Filter Options' in Metric Filters for smoother navigation.
2. **Gantt Chart Styling**: Added bar styling options for Gantt Chart, including Bar Height, Top Radius, and Bottom Radius.
***
### Fixes:
1. **Scheduled Report Issues**: Resolved the "No Data Found" and layout issues in scheduled reports.
2. **Gantt Chart**: Fixed date format issues in the Gantt chart.
3. **Hide App Filter in Filter Box**: The App Filter is now hidden in the dashboard switch select filter to enhance security and ensure proper functionality.
**Image Version**\
: 1.1.122\
, **Plugin Version**\
: 0.15.136
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Gantt Chart**: Introducing the Gantt Chart for enhanced timeline-based visualization of tasks and projects.
2. **Y Axis - Log Scale**: Added the ability to convert the Y-axis to a logarithmic scale for improved visualization of wide-ranging values.
3. **Click Action on Single Value Card**: Enable interactive experiences by configuring click actions on Single Value Cards.
4. **New Data Source - OpenSearch**: Now supporting OpenSearch as a data source, expanding your integration options.
5. **Optional Variable Filters**: Variable filters can now be made optional using square brackets in code blocks for greater flexibility.
### Enhancements:
1. **Underlying Data Download**: Added support to download filtered underlying data for deeper offline analysis.
2. **Badge Color in Table Chart**: Introduced the ability to set badge colors in table chart conditional formatting.
### Fixes:
1. **Switch Select Default Value**: Resolved inconsistencies in Switch Select options by setting a default value.
2. **Dynamic Properties in Descriptive Elements**: Fixed loading issues in dynamic properties across footnote, title, description, and long description.
3. **Athena Load Time Disparity**: Addressed inconsistencies in load time between Query Editor and Chart Builder for Athena data source.
**Image Version**\
: 1.1.119\
, **Plugin Version**\
: 0.15.130
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Drill Down Revamp**: We've updated the UI of Drill Down Feature to ensure better clarity and visibility.
2. **Custom SQL Revamp**: We've enhanced the Custom SQL interface to offer a cleaner editing experience and improved validation feedback for better query building. Users can write custom SQL queries and save them as Table Chart, Table Chart with Dynamic Table, New Chart or Custom Dataset.
3. **Single Value Card**: We've added alignment and font options, along with dynamic property support for sub-header text in the Single Value Card. String-based conditional formatting support has also been introduced.
4. **Metric Border Color**: Users can now specify the metric border color globally from the UI Theming page.
### Fixes:
1. **Filter Disappearance on Sync in Metric Page**: Resolved an issue with the variable metric filter for the Redshift data source.
2. **Custom Columns in Simple Filter**: Fixed an issue where custom columns were not appearing in the simple filter.
**Image Version**\
: 1.1.116\
, **Plugin Version**\
: 0.15.127
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Background Color Option for Metric Summary**: You can now set a background color for the metric summary card.
2. **Delete Option for Custom Roles**: A delete option is now available for custom roles.
3. **Chart settings for chart title, axis labels, axis values, and legend** have been added globally under the 'UI Theming' section on the Embed Settings page.
### Fixes:
1. **Download data issue in Athena data source**: Resolved an issue with downloading data in metrics and when limit is applied.
2. **Logo in Scheduled Reports**: Resolved an issue with the logo in scheduled reports.
3. **Switch Y Axis Enablement with Individual Number Formatting**: When the "Switch Y-Axis" option is enabled, each measure now correctly applies its own number formatting settings.
**Image Version**\
: 1.1.108\
, **Plugin Version**\
: 0.15.122
**DataBrain Updates: Enhancements, Fixes**
### Enhancements:
1. **Date Restriction Feature in Preset Date Dashboard Filters**: We have added an "Enable Restrictions" toggle to the Preset Date Dashboard filter, similar to the Metric Filter.
2. **OIDC Identity Provider (IDP) Support**: Users can now create an OIDC-based IDP for Single Sign-On (SSO) under MFA & SSO Settings
### Fixes:
1. **Dashboard UI Fix**: Resolved an issue where the 'Reset' button overlapped with other UI elements on the dashboard page.
2. **Report Scheduling**: Added user prompts for improved clarity and guidance during report scheduling.
**Image Version**\
: 1.1.106\
, **Plugin Version**\
: 0.15.120
**DataBrain Updates: Features, Enhancements, Fixes**
### Features:
1. **Add Alignment Option for Single-Value Card**: You can now align the value in Single-Value Cards.\
Navigate to Settings > Appearance > Customizations > Alignment for more control over layout.
2. **New Data Source – Athena**: We've added support for a new data source: Athena
3. **Horizontal Combo Chart**: A new chart type has been introduced, similar to the combo multi-scale chart but arranged horizontally.
4. **Bubble Chart V2**: The updated version of the Bubble Chart now allows users to specify bubble size. You can now set a measure for bubble size and drag & drop measures into dimensions.
### Enhancements:
1. **Date Range Mapping for Single Value Card Comparison**: Single value cards now automatically reflect the selected dashboard date filter range. If "Lifetime" is chosen, the card uses the comparison value set in its settings.
2. **Grid Dividers in Merge Metric**: Users can now add grid dividers between different metrics and enhance them with background colors.
### Fixes:
1. **Download Array Datatype Column Values**: Fixed an issue where array-type column values were not downloaded correctly.
2. **Single Value Card Resizing**: Resolved inconsistencies in resizing behavior for Single-Value Cards.
3. **Progress V2 Number Formatting**: Addressed incorrect number formatting on upper limit when using dynamic properties.
4. **Combo Chart Duplicate Axis**: Fixed an issue where duplicate axes appeared in Combo Charts.
5. **Resolved an issue with the preset date dashboard filter in Firebolt.**
**Image Version**\
: 1.1.102\
, **Plugin Version**\
: 0.15.116
**DataBrain Update: Enhancements**
### Enhancements
1. **Complex Sort in Metrics**: Added a feature to generate SQL for custom sorting beyond the default lexicographical ASC and DESC provided by SQL.
2. **Role Permissions for Metric Elements**: Introduced an option to manage role-based permissions for metric elements.
3. **"All Clients" Option**: Added an "All Clients" selection on the metric creation page.
4. **Transpose Data in Table Charts**: Introduced a toggle to switch rows and columns in table charts.
**Image Version**\
: 1.1.101\
, **Plugin Version**\
: 0.15.113
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Metric Expression Support in Elements**: We have introduced metric expression support in elements, allowing users to compute values using metric ID.
2. **Added Variable Filter for Preset Date Filter**: Implemented a variable filter in the preset date option for dashboards.
### Fixes
1. **Improved Pagination on the Explore Data Page**: Fixed an issue where pagination did not display correctly, ensuring a smoother navigation experience.
2. **UI Update**: Resolved an issue with tooltips for better usability.
**Image Version**\
: 1.1.100\
, **Plugin Version**\
: 0.15.111
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Font Style Options in Axis Charts**: Added Font Family, Font Size, and Font Weight options for horizontal and vertical axis names
2. **Font Styling for Metric AI Summary**: Users can now customize font styles in the Metric AI Summary
3. **Text Wrap in Combo Multi-Scales Chart**: Users can now define a value to break text in the Y-axis name of the combo multi-scales chart
4. **Customize Date Format**: Users can now set their preferred date format for the date filter in the "UI Theming" page
### Fixes
1. **Explore Data**: Fixed a download issue in the Explore Data feature
**Image Version**\
: 1.1.99 , **Plugin Version**\
: 0.15.107
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Sorting and Number Formatting for Pivot Table V2**: Added options for sorting and number formatting in Pivot Table V2
2. **Custom Value Redirection in Table Chart**: Users can now click on a specific value in the Table Chart to be redirected to a designated link
### Fixes
1. **UI Update**: Chart Tooltip settings will remain hidden until the "Label Tooltip" toggle is enabled
2. **Metric Alignment Fix**: Resolved an issue where metric alignment changed after exporting and importing a dashboard.
**Image Version**\
: 1.1.98, **Plugin Version**\
: 0.15.104
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Editability of Created Views in Custom Datasets**: Exploring the feasibility of enabling editing and deleting capabilities for previously created views within custom datasets.
2. **Enhanced Pivot Table V3**.
3. **Improved UI for Table Chart Pagination.**
4. **Metric Background Color in Single Value Card**: Users can now add a background color to Single Value Cards.
5. **Set Config**: User can now set Data Config Options in Embedded Dashboards.
### Fixes
1. Fixed flickering issue in bar charts.
2. **BigQuery Data Source Fixes**: Resolved issues with GROUP BY, single quotes in filters, and AI-powered query formatting.
**Image Version**\
: 1.1.96\
, **Plugin Version**\
: 0.15.102
**DataBrain Update: Features, Enhancements & Fixes**
### Features
1. **Auto Format Custom SQL with AI**: Introduced an AI-powered feature for automatically converting custom SQL queries into DataBrain's preferred format, ensuring consistency and improved query management.
### Enhancements
1. **Multiple Dependencies in Metric Filters**: Users can now add multiple dependencies between metric filters for greater flexibility.
2. **Conditional Band Formatting for Horizontal Bar Chart**: Allows users to apply custom band colors based on defined ranges, enhancing visual clarity.
3. **Font Weight Dropdown**: Added a dropdown to select font weights for text values, enhancing readability and customization.
4. **Improved User Experience in "Manual" Dashboard and Metric Filter**: The mandatory fields ‘Option Value’ and ‘Option Label’ now appear by default, eliminating the need to manually click ‘+ Add Option.’
5. **Added Range Option Type in Metric Filter**: Enables users to specify a range of values for improved filtering flexibility.
6. **Text Wrapping in Table Chart Columns**: Introduced text wrapping for better readability in table charts.
7. **Column Resizing in Table Chart Without Table Header**: Users can now resize columns, regardless of whether the table header is hidden.
### Fixes
1. **Escape Filter Values with Single Quotes**: Metric filters now properly accept values containing single quotes.
**Image Version:** 1.1.94\
**Plugin Version:** 0.15.99
**DataBrain Update: Enhancement**
### Enhancement
1. **Added options in preview link**: Users can now control the side panel and dashboard name in the preview link generation.
**Image Version**\
: 1.1.93\
, **Plugin Version**\
: 0.15.98
**DataBrain Update: Features, Enhancements & Fixes**
### Feature
1. **Datasource Sync API**: Exposed an API for syncing the datasource
### Enhancements
1. **Dashboard Date Filter & Time-Series Chart Integration**: We have added support for mapping dashboard date filter options with time-series charts for improved synchronization
2. **Bar Styling for Combo Multi-Scales Chart**: Added a "Bar Styling" option to the combo multi-scales chart for better customization. This feature allows users to fine-tune the appearance of bars for improved visualization and readability with key Customization Options:
* Bar Width – Adjust the width of bars to control spacing and visual clarity
* Bar Top Radius – Round the top edges of bars for a softer, modern look
* Bar Bottom Radius – Customize the bottom edge roundness for a polished appearance
### Fixes
1. **Bubble Chart in Firebolt**: Resolved an issue affecting the Bubble chart when using the Firebolt datasource
2. **UI Update (Fullscreen Dropdown Component)**: Fixed an inconsistency in dropdown behavior when in fullscreen mode
**Image Version**\
: 1.1.92\
, **Plugin Version**\
: 0.15.96
**DataBrain Update: Enhancements & Fixes**
### Enhancements
1. **Horizontal Chart**: Added Switch X-Axis and Switch Y-Axis features for improved flexibility
2. **Sankey Chart**: Introduced Switch Measure functionality for better customization
### Fixes
1. Resolved an issue where the Switch X-Axis Dropdowns displayed removed dimension values
2. Fixed duplicate values appearing in the Filter Panel dropdown in Custom Query Mode
**Image Version**\
: 1.1.91\
, **Plug In version**\
: 0.15.94
**DataBrain Updates: Features, Enhancements, Fixes**
### Features
1. **Rearrange Metric Filters**: You can now rearrange metric filters on the update/create metric page using drag-and-drop, making customization easier and more intuitive.
2. **Save a Custom Dataset (View) to Multi-Selected Datasource**: You can now save a custom dataset across multiple selected data sources, enabling seamless data management and greater flexibility. Refer to the document below:\
[Creating a custom dataset view](https://docs.usedatabrain.com/guides/datasources/creating-a-custom-dataset-view-in-a-multi-datasource-environment)
3. **Support Fiscal Year in Date Filter**: You can now set up a custom fiscal year filter in DataBrain to filter data based on the Indian Financial Year. Refer to the documentation below:\
[Custom Fiscal Year Filter Setup](https://docs.usedatabrain.com/developer-docs/helpers/options/custom-fiscal-year-filter-setup-in-databrain)
4. **Easier Access to Frequently Used Tables**: Frequently used tables now appear at the top of the schema sidebar on the metric creation page, improving accessibility and efficiency.
### Enhancements
1. **Adaptive formatting for Indian decimals**: The Indian Number System now considers values up to two decimal places.
2. **Enhanced Chart Controls for End Users**: End users can now access additional chart options, including Enable Cumulative Behavior, Dynamic Behavior, and Chart Zoom, for improved data visualization and interaction.
### Fixes
1. **UI update**: We have enhanced the user experience by eliminating flickering when switching between the Charts Panel and Settings Panel, ensuring a smoother and more seamless transition.
2. **Improved Reset Password Flow**: Expired Reset Password links now immediately display a “Reset Password Link Expired” message, preventing unnecessary input.
3. **Date filter**: The Date Filter now accepts only four-digit years, preventing incorrect inputs.
**Image Version**: 1.1.89\
**Plug In version**: 0.15.87
**DataBrain Updates: Features, Enhancements, Fixes**
### Features
1. **Drill Down for Tree Map**: Introducing drill-down functionality in Tree Map charts! Click on a section to explore deeper levels of data effortlessly.
2. **Chart Click Action with Metric**: Now, clicking on a metric within a chart allows seamless navigation to another related metric for enhanced data exploration.
3. **Add View Button in Table Chart**: Added a "View" button in table charts, enabling users to expand selected columns within a row for better data visibility.
4. **Add RHS Custom SQL Support**: Added the ability to control how selected options from a dashboard dropdown are applied on the RHS of the `WHERE` clause. Use the `{{global_selected_values}}` variable to modify selected values dynamically (e.g., applying transformations like `CONCAT`).
5. **End users can now archive metrics**
### Enhancements
1. **Adaptive Formatting – Indian Number System**: Added support for number formatting in the Indian system (e.g., lakh, crore) for improved readability.
2. **Copy Generated SQL with One Click**: A new "Copy" button allows you to easily copy the generated SQL query.
3. **Customizable Color Palettes**: Modify colors in existing palettes anytime to match your theme by clicking on the edit icon.
### Fixes
1. **Side Panel UI**: Addressed display inconsistencies in the join panel, resolving issues with overflowing fields for a cleaner user experience.
2. **Time-Series Chart**: Resolved an issue where the chart headers were not displaying correctly in metric full-screen mode.
3. **Workspace Panel**: Fixed scrolling issues for a smoother and more seamless user experience.
4. **Combo Option in Time-Series Chart**: Resolved an error that occurred when using the combo option in the time-series chart.
**Image Version**: 1.1.86\
**Plugin Version**: 0.15.82
**Features, Enhancements, Fixes:**
### Features:
1. **Footnote as a Rich Text Box**: Footnotes are now powered by a React text box, allowing you to add links, change colors, and apply formatting like bold and italics for better customization.
2. **Hide Dashboard Filter in Embed Code**: You can now control the visibility of dashboard filters in embedded dashboards. This is useful for cases where different user groups need different filter options. For example, US customers can see the US fiscal year, while Indian customers see the Indian fiscal year—without displaying unnecessary filters. Please refer the below link:
Options\
The extra options/parameters that you can pass for your Web Component.
3. **Cumulative Option for Line and Area Charts**: A new "Cumulative" option has been added to Line and Area charts, accessible under Chart Settings > Appearance > Features > Cumulative for better trend analysis.
4. **SDK Overrides**: Now you can override card titles, descriptions, footnotes, column names (for tables), and label/legend names (for charts) directly in the SDK for enhanced customization. Please refer the below link:
Options\
The extra options/parameters that you can pass for your Web Component.
5. **New Progress Bar Chart and Geo Region Map**: Added two new charts, Improved Progress Bar and Geo Region Map for Indian States.
6. **Merge Layouts**: Easily merge multiple metrics and rearrange them with the same flexibility as the dashboard's custom layout.
7. **Preview Link Management**: Track all preview links generated for dashboards and delete those no longer needed for better link management.
### Enhancements:
1. **UI Theming Update**: You now have the option to remove the stroke around metric cards for a cleaner visual experience.
2. **Revamped Chart Panel in Create Metric Page**: Charts are now grouped under categories, making it easier to find and search for the desired visualizations.
3. **Dynamic Property Support**: Added support for dynamic property implementation in the lower and upper limit setup.
4. **Clear All Option**: Easily clear all columns added in measures or dimensions with a single click using the "Clear All" functionality.
**Image Version**: 1.1.77\
**Plugin Version**: 0.15.65
**Features, Enhancements, Fixes:**
### Enhancements:
1. **Donut Chart**: Added the ability to switch X and Y axes for enhanced customization.
2. **Dynamic Property Support**: Metrics created using Python now support dynamic properties for greater flexibility.
3. **Box Plot**: Enhanced Box Plot to support multiple experiments, enabling richer comparative analysis.
### Fixes:
1. **Radial Charts**: Fixed the legend scrolling issue for a smoother user experience.
**DataBrain Update: Features, Enhancements & Fixes**
### Features
1. **Auto Format Custom SQL with AI**: Introduced an AI-powered feature for automatically converting custom SQL queries into DataBrain's preferred format, ensuring consistency and improved query management.
### Enhancements
1. **Multiple Dependencies in Metric Filters**: Users can now add multiple dependencies between metric filters for greater flexibility.
2. **Conditional Band Formatting for Horizontal Bar Chart**: Allows users to apply custom band colors based on defined ranges, enhancing visual clarity.
3. **Font Weight Dropdown**: Added a dropdown to select font weights for text values, enhancing readability and customization.
4. **Improved User Experience in "Manual" Dashboard and Metric Filter**: The mandatory fields ‘Option Value’ and ‘Option Label’ now appear by default, eliminating the need to manually click ‘+ Add Option.’
5. **Added Range Option Type in Metric Filter**: Enables users to specify a range of values for improved filtering flexibility.
6. **Text Wrapping in Table Chart Columns**: Introduced text wrapping for better readability in table charts.
7. **Column Resizing in Table Chart Without Table Header**: Users can now resize columns, regardless of whether the table header is hidden.
### Fixes
1. **Escape Filter Values with Single Quotes**: Metric filters now properly accept values containing single quotes.
**DataBrain Update: Enhancement**
### Enhancement
1. Added options in preview link: Users can now control the side panel and dashboard name in the preview link generation
# Getting Started
Source: https://docs.usedatabrain.com/developer-docs
How to Seamlessly Embed a DataBrain Dashboard
To embed a DataBrain dashboard into your application, we offer a straightforward approach using the DataBrain *npm* package. Simply install this package, and then bring it into your application to access a range of components. These components enable you to display full dashboards or specific metrics as needed.
**Prefer using an AI assistant?** The Databrain MCP server lets you set up embeds, query data, and customize dashboards through natural language — in Cursor, Claude, Windsurf, or any MCP-compatible client. [Get started in 2 minutes →](/developer-docs/mcp-server/quickstart)
## Multi-Tenancy Support
DataBrain supports embedding for different levels of tenancy based on how your client data is organized. Whether you separate data at the **table level** (rows identified by a client ID), **schema level**, **database level**, or across multiple datasources, DataBrain can handle your tenancy model.
Common tenancy models include:
* **Single Table Tenancy**: All client data in one table, separated by a `client_id` column
* **Multi-Level Tenancy**: Combining multiple layers (e.g., schema + table, database + schema)
Choose the right tenancy model based on your data architecture. Learn more about [choosing the right tenancy model](https://docs.usedatabrain.com/guides/onboarding-and-configuration/choosing-the-right-tenancy-model-for-your-data) and how to [configure tenants](https://docs.usedatabrain.com/guides/datasources/configure-tenants).
***
We've got you covered with a step-by-step guide here to help you integrate DataBrain dashboards into your user interface seamlessly.
## Step-by-Step Guide to Embed DataBrain Dashboard
```bash theme={"dark"}
npm install @databrainhq/plugin
```
```js theme={"dark"}
import '@databrainhq/plugin/web';
```
For embedding a Dashboard
```html theme={"dark"}
```
or
For embedding a Metric Card
```html theme={"dark"}
```
**Finding Your IDs**
* **Dashboard ID**: In your Data App, navigate to **Embed Info** > **Add New Embed**. Select **workspace name**, choose embed type as **dashboard**, and select the dashboard. The **Embed ID** displayed is your dashboard ID. [See detailed guide here](https://docs.usedatabrain.com/developer-docs/helpers/dashboard-id).
* **Metric ID**: In your Data App, go to **Embed Info** > **Add New Embed**. Provide the **workspace name**, select embed type as **metric**, choose the **dashboard** containing your metric, then select the metric. The **Embed ID** shown is your metric ID. [See detailed guide here](https://docs.usedatabrain.com/developer-docs/helpers/metric-id).
**Token**
The [`token`](https://docs.usedatabrain.com/developer-docs/token) should be a **guest token** generated from your backend using DataBrain's REST API. Each guest token is unique and ensures secure access control.
**Generating a Guest Token:**
Make a POST request from your backend to generate the guest token:
**Cloud DataBrain:**
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
**Self-hosted DataBrain:**
```http theme={"dark"}
POST /api/v2/guest-token/create
```
**Request Headers:**
```json theme={"dark"}
{
"Authorization": "Bearer [API_TOKEN]"
}
```
**Minimum Request Body:**
```json theme={"dark"}
{
"clientId": "id", // Use "None" if no tenancy selected
"dataAppName": "dataappname"
}
```
The API will return a token that you pass to your frontend. The token can include additional parameters like `appFilters`, `dashboardAppFilters`, and `permissions` for fine-grained control. If `expiryTime` is not specified, the token won't expire.
Learn more about [token generation and advanced options here](https://docs.usedatabrain.com/developer-docs/token).
**Example for Embedding Dashboard:**
Here is an example with a sample token and dashboardId that you can use in your frontend app to get started without a backend:
```html theme={"dark"}
```
## Additional Resources and Customization
* **Customizing the Look and Feel**:
* For further customizations related to the appearance of the embedded elements, [***refer here.***](https://docs.usedatabrain.com/developer-docs/helpers/options)
* **Understanding the Overall Architecture**:
* For a comprehensive understanding of the overarching architecture and how embedding fits into it, [***refer here.***](https://docs.usedatabrain.com/developer-docs/embedding-setup/architecture-deep-dive)
With these steps, embedding DataBrain dashboards or metrics into your application can be done efficiently, offering a dynamic and insightful data visualization component to your users.
# Token API v1 → v2 Migration
Source: https://docs.usedatabrain.com/developer-docs/api-migration-guide
Guide for migrating existing integrations for generating token from API v1 to v2, covering differences, deprecations, and implementation steps.
**Note**: v2 is mostly compatible with v1, with only slight differences in endpoint paths and some parameter naming/placement.
### Endpoint URL Changes
* v1
```
POST https://api.usedatabrain.com/api/v1/guest-token/create
```
* v2
```
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
**Note** : The url remains same except in place of v1 it will be v2.
### Parameter Adjustments
In API v1, tokens were generated using the `clientId` along with `workspaceName` and `datasourceName`.
In API v2, this has been simplified by introducing a `dataApp`, so you only need to pass the `clientId` and `dataAppName`. The main change is that v2 replaces the separate workspace and datasource parameters with a single dataApp reference.
* v1 example request body:
```
{
"clientId": "your-client-id",
"workspaceName": "your_workspace",
"datasourceName": "your_datasource",
}
```
* v2 example request body:
```
{
"clientId": "your-client-id",
"dataAppName": "your_data_app",
}
```
**Note**: In both v1 and v2, the authorization parameter works the same way. The only difference is that in v1 you used the API token from global settings, while in v2 you must use the API token generated within the dataApp. This ensures that authorization is scoped specifically to the dataApp.
### Permissions
* In v1, we used to set permissions in the workspace settings for creating metric, updating metric, deleting metric etc.
* In v2, all these permission needs to be enabled in the specific dataApp itself.
### Create Metric
* In v1, we used to just enable the create metric option in workspace settings and chose the power mode option.
* In v2, you first create a \*\*datamart \*\*from the same datasource you previously used in **v1**. Then, when enabling permissions like *create metric*, you reference that datamart within the dataApp settings.
### Migration & Token Compatibility
* Both v1 and v2 tokens will continue to work with the same dashboard ID.
* However, note that settings applied using v1 tokens will not apply when using v2 tokens, and vice versa.
* Each version’s settings are independent, even though the tokens can coexist.
# Step 1: Create Datamart and Workspace
Source: https://docs.usedatabrain.com/developer-docs/chat-mode/step-1-create-datamart-and-workspace
To utilize chat mode in your embed, you need to first create a datamart assuming you already created a data source.
Navigate to the **"Data"** section in app. Look for the **"Datamarts"** option and click on it. Click on **"Create New Datamart"** which will open a modal.
Provide a name for your datamart and the datasource. Check the box if multi-tenancy is required to enable database tenancy. Click **"Next"** to proceed.
On the next screen, you'll see a list of available tables. Review the list and select the tables you want to include in your datamart.
Click **"Next"** to move to the column configuration. For each selected table, you'll see a list of available columns. Choose the specific columns you want to include in your datamart. You may have options to rename columns or set data types if needed. Once you've configured all desired columns, click "Next" to continue.
On the **tenancy configuration** screen, you'll set up how data is separated for different tenants.
Configure all tenancy-related settings. Review your tenancy configuration to ensure it meets your requirements. Click **"Complete"** to complete the datamart setup.
Now, go to home page and click on + icon near **workspaces**.
Enter the name for the workspace, select data connection as Data Mart and chose the datamart in the select datamart dropdown that you created and provide description if you want.
Click on **"Save"** to create the workspace.
**Programmatic setup:** You can also configure the semantic layer for your datamart via the [Semantic Layer API](/developer-docs/helpers/api-reference/semantic-layer-api) — useful for automating datamart enrichment in CI/CD pipelines or managing semantic metadata across environments.
# Step 2: Create Data App and Embed ID
Source: https://docs.usedatabrain.com/developer-docs/chat-mode/step-2-create-data-app-and-embed-id
Configure a data app with AI Chat Mode by enabling access control, setting up semantic layer integration, and generating embed credentials for chat-enabled analytics.
* Navigate to the "Data" section in your app.
* Look for the "Data Apps" option and select it.
* Click on **"New Data App"** button. Provide the required information including naming it and configuring basic settings.
Access Control is crucial for managing what users can do within your Data App. Navigate to the "Access Control" tab within your created Data App.
* Look for options related to "Metric Creation" and "Chat Mode".
* Enable the setting that allows users to create metrics and select chat mode.
* Select the Data Mart and provide the client column for each table.
* Click on "Save" to save the settings.
Once access control settings are configured, click on **"Embed Info"** tab in the sidebar.
Refer to "Dashboard ID" for generating embed ID and refer "API TOKEN" for generating API token that will be used to generate **"guest token"** later.
Once API Token is generated, create "guest token" with **"client ID"**.
* Guest tokens are used for allowing temporary, limited access to your Data App.
* Go to postman or any other API platform.
* Set the URL as [Guest Token API Endpoint](https://api.usedatabrain.com/api/v2/guest-token/create).
* In the Authorization tab, select type as **"Bearer Token"** and in token field add the "API token" that you created in your data app.
* You'll need to specify a **Client ID** , which is a unique identifier for the client or user you're creating the token for and the **data app name** that you created above in the body.
* Click on **"Send"** . The generated guest token will be associated with the provided Client ID and data app.
Use the guest token and the embed ID to test your embed.
Click on **"Chat Data"** button and start analyzing your data.
To verify your response, got to **"Data"** tab in your app, select **"Semantic Layer"** in the side bar, and click on the **"Lab"** button next to the datamart that you chose to create your data app.
Inside the semantic layer for you datamart, click on **"Logs"** tab. There you will see your response.
# Self-Hosted Deployment Verification
Source: https://docs.usedatabrain.com/developer-docs/deployment-verification
Use this Docker image to verify your self-hosted application. It runs a comprehensive verification script to ensure your deployment is successful.
Authenticate your Docker CLI to AWS ECR before pulling the image.
```bash theme={"dark"}
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/databrain
```
Go to public ECR: DataBrain Test Container on AWS ECR Gallery
```bash theme={"dark"}
docker pull public.ecr.aws/databrain/dbn-test:1.1.9 // use newest tag
```
The container expects some environment variables to be passed for the test to work.
```yaml theme={"dark"}
version: '3.8'
services:
test-runner:
image: public.ecr.aws/databrain/dbn-test:1.1.9 // use newest tag
environment:
TEST_HOST: https://your-selfhosted-url.com
TEST_DEMO_HOST: https://your-selfhosted-url.com/demo
TEST_DEMO_TOKEN: 537ks6v3-8614-c535-4870-d47730bd0c70&dashboardId=selfhosted-dashboard
TEST_USER_EMAIL: selfhosted@company.com
TEST_USER_NAME: CompanyName
TEST_DELETE_USER_AUTH_TOKEN_SELFHOSTED: delete_token_9so$sm
TEST_USER_PASSWORD: Company@123
TEST_NEW_USER_COMPANY: newCompanyName
TEST_NEW_USER_EMAIL: newselfhosted@company.com
TEST_NEW_USER_NAME: newSelfhosted
TEST_NEW_USER_PASSWORD: newSelfhosted@123
TEST_NEW_USER_RESET_PASSWORD: resetSelfhosted@123
TEST_ROLE_USER_EMAIL: newUser@company.com
restart: "no"
```
Run the following GitHub Action step to execute application tests via Docker:
```yaml theme={"dark"}
- name: Run Application Tests via Docker
run: |
docker run --rm \
-e TEST_HOST=${{ secrets.TEST_HOST }} \
-e TEST_DEMO_HOST=${{ secrets.TEST_DEMO_HOST }} \
-e TEST_DEMO_TOKEN=${{ secrets.TEST_DEMO_TOKEN }} \
-e TEST_USER_EMAIL=${{ secrets.TEST_USER_EMAIL }} \
-e TEST_USER_NAME=${{ secrets.TEST_USER_NAME }} \
-e TEST_DELETE_USER_AUTH_TOKEN_SELFHOSTED=${{ secrets.TEST_DELETE_USER_AUTH_TOKEN_SELFHOSTED }}
-e TEST_USER_PASSWORD=${{ secrets.TEST_USER_PASSWORD }} \
-e TEST_NEW_USER_COMPANY=${{ secrets.TEST_NEW_USER_COMPANY }} \
-e TEST_NEW_USER_EMAIL=${{ secrets.TEST_NEW_USER_EMAIL }} \
-e TEST_NEW_USER_NAME=${{ secrets.TEST_NEW_USER_NAME }} \
-e TEST_NEW_USER_PASSWORD=${{ secrets.TEST_NEW_USER_PASSWORD }} \
-e TEST_NEW_USER_RESET_PASSWORD=${{ secrets.TEST_NEW_USER_RESET_PASSWORD }} \
-e TEST_ROLE_USER_EMAIL=${{ secrets.TEST_ROLE_USER_EMAIL }} \
public.ecr.aws/databrain/dbn-test:1.1.9
```
# Embed using iFrame (Not Recommended approach)
Source: https://docs.usedatabrain.com/developer-docs/embed-using-iframe-not-recommended-approach
You can embed the dashboard or metric using iFrame in your app.
## Embed using iFrame (Not Recommended approach)
### Usage
#### Quick Usage
```html theme={"dark"}
Document
```
You would require to generate the demo URL first. For eg:
```bash theme={"dark"}
https://demo.usedatabrain.com/?token="your guest token"&dashboardId="dashboard id"&embed=true
```
For generating the required params see:
Make sure to add `embed=true` at the end of the URL, to embed the dashboard or metric in iFrame.
# Architecture Deep Dive
Source: https://docs.usedatabrain.com/developer-docs/embedding-setup/architecture-deep-dive
Technical deep-dive into DataBrain's embedding architecture, authentication, performance, and deployment patterns
**For Technical Teams:** This guide provides detailed technical documentation of DataBrain's embedding architecture, including authentication flows, query execution paths, performance optimizations, and advanced deployment patterns.
**Prerequisites:**
* Familiarity with REST APIs and authentication concepts
* Understanding of database query execution
* Basic knowledge of cloud infrastructure (for deployment sections)
**Looking for conceptual overview?**
See [Embedding Architecture Concepts](/getting-started/core-concepts/embedding-architecture) for high-level understanding.
***
## Authentication & Security Flow
### Token Generation Process
The authentication flow ensures secure, multi-tenant access through stateless guest tokens:
**Step 1: Your backend authenticates with DataBrain**
```javascript theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DATABRAIN_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
clientId: user.tenantId,
dataAppName: 'customer-portal',
expiryTime: 3600000, // 1 hour
params: {
rlsSettings: [
{ metricId: 'metric_123', values: { customer_id: user.customerId } }
]
}
})
});
const { token } = await response.json();
```
Your API key should only be used server-side. Never expose it to the frontend.
**Step 2: DataBrain validates every request**
When the web component makes requests, DataBrain performs multiple security checks:
1. **Token lookup**: The token (an opaque UUID issued server-side) must exist in the deployment — fails with `INVALID_TOKEN` otherwise
2. **Expiration check**: Ensures token hasn't expired (`TOKEN_EXPIRED`)
3. **Origin validation**: Verifies request comes from whitelisted domain (`UNAUTHORIZED_ORIGIN`)
4. **Permission check**: Validates access to requested dashboard/metric (`UNAUTHORIZED` / `INVALID_ID`)
5. **RLS application**: Applies row-level security rules
If any validation fails, the request is rejected with an appropriate error code.
**Step 3: Configure allowed domains**
In DataBrain dashboard, whitelist scheme-less `host[:port]` entries that can embed your analytics:
* `app.yourcompany.com`
* `dashboard.yourcompany.com`
* `localhost:3000` (for development)
Requests from non-whitelisted domains are automatically blocked, even with valid tokens.
**Step 4: Row-level security enforcement**
The `rlsSettings` you define in the guest token are enforced server-side per metric — the values are fixed at mint time and cannot be changed by the end user.
```json theme={"dark"}
// Defined in the guest token
"params": {
"rlsSettings": [
{ "metricId": "metric_123", "values": { "tenant_id": "customer-123" } }
]
}
```
RLS and token filters are **not** a substitute for the Datamart's tenant filter, and tenant scoping is not applied uniformly to every query. Builder (visual/dataset) metrics get the tenant filter injected automatically when the Datamart's Client ID mapping is set — but **custom SQL metrics do not**: their authors must reference the tenant variable explicitly (`WHERE client_column = 'client_id_variable'`), or the metric runs unscoped. See the [Tenancy Model](/developer-docs/tenancy-model) for the full rules.
### Security Best Practices
* Store API keys in environment variables
* Never expose API keys in frontend code
* Rotate API keys periodically
* Use separate keys for dev/staging/production
* Set reasonable expiration times (1-24 hours)
* Refresh tokens before expiration
* Generate new tokens on user session refresh
* Shorter expiry = better security
* Whitelist only necessary domains
* Remove development domains in production
* Use HTTPS in production (required)
* Review whitelist regularly
* Define RLS rules for all tables
* Test RLS rules thoroughly
* Use parameterized queries
* Avoid SQL injection vulnerabilities
***
## Data Flow Architecture
### Query Execution Path
Understanding how queries flow through the system:
End user interacts with embedded dashboard:
* Applies filters
* Changes date ranges
* Drills down into data
* Refreshes metrics
Web component constructs authenticated API request with the guest token and sends it to DataBrain to fetch metric data with any applied filters.
DataBrain processing pipeline:
1. **Validate token**: Look up the token server-side; check expiration, permissions
2. **Retrieve metric**: Load metric configuration from metadata
3. **Apply filters**: Merge user filters with app filters
4. **Generate SQL**: Create optimized query
5. **Apply RLS**: Wrap query with row-level security
6. **Check cache**: Look for cached results (optional)
Query executes against your database:
```sql theme={"dark"}
-- Example generated query
WITH rls_orders AS (
SELECT * FROM orders
WHERE customer_id = 'customer-123'
AND created_at >= CURRENT_DATE - INTERVAL '30 days'
)
SELECT
DATE_TRUNC('day', created_at) as date,
SUM(amount) as revenue
FROM rls_orders
GROUP BY date
ORDER BY date;
```
DataBrain generates optimized SQL with proper indexing hints and query planning.
DataBrain processes query results:
* Format data for visualization
* Apply number formatting
* Calculate aggregations
* Handle null values
* Apply currency conversions (if configured)
Results streamed to frontend:
```json theme={"dark"}
{
"data": [
{ "date": "2024-01-01", "revenue": 125000 },
{ "date": "2024-01-02", "revenue": 132000 }
],
"metadata": {
"executionTime": 245,
"cached": false
}
}
```
Component renders interactive chart with your theme.
### Performance Optimizations
**Reduce database load with intelligent caching:**
* **Time-based caching**: Cache results for configurable TTL (default: 24 hours)
* **Per-tenant caching**: Cache keys include query hash, datasource ID, filters, and workspace ID — ensuring tenant isolation
* **Two caching modes**: Use DataBrain's managed Redis or bring your own Redis/Elasticache
* **Graceful degradation**: Cache failures never block queries — DataBrain falls back to direct database execution
Configure caching in **Workspace Settings → Cache Settings**. Each workspace can independently choose its caching mode and TTL.
Complete guide to configuring query caching
**Efficient database connection management:**
* Connection pool per datasource
* Automatic connection recycling
* Configurable pool size
* Connection health checks
* Query timeout management
Recommended pool configuration:
| Workload | Min Connections | Max Connections |
| -------- | --------------- | --------------- |
| Light | 2 | 10 |
| Medium | 5 | 25 |
| Heavy | 10 | 50 |
**Automatic query optimization:**
✅ Push-down filters to database\
✅ Minimize data transfer\
✅ Use appropriate indexes\
✅ Parallel query execution\
✅ Result streaming for large datasets\
✅ Automatic query planning
**Fast-loading embedded components:**
* Lazy loading of visualizations
* Progressive rendering
* Debounced filter updates
* Virtual scrolling for tables
* Compressed data transfer
* CDN delivery of assets
***
## Advanced Architecture Patterns
### Proxy Mode Architecture
For enhanced security, route all requests through your own proxy server:
**Benefits of proxy mode:**
* Guest tokens never exposed to frontend
* Additional authentication layer
* Request/response modification
* Custom logging and monitoring
* API rate limiting
* Request validation
Complete guide to implementing proxy authentication
### Multi-Datasource Architecture
Support customers with data in different databases:
```json theme={"dark"}
{
"clientId": "enterprise-customer",
"datasourceName": "customer-dedicated-db",
"dataAppName": "analytics"
}
```
**Use cases:**
* Dedicated database per enterprise customer
* Multi-region data residency
* Database sharding strategies
* Read replica routing
Configure multi-datasource workspaces
### High-Availability Architecture
Deploy DataBrain with redundancy and failover:
**Horizontal scaling with load balancers:**
```
[Load Balancer]
|
┌────┼────┬────┐
│ │ │ │
App App App App
│ │ │ │
└────┴────┴────┘
|
[Database Pool]
```
* Multiple application servers
* Session affinity (sticky sessions)
* Health check endpoints
* Automatic failover
**High availability for databases:**
* Primary-replica setup
* Read replicas for analytics
* Automatic failover
* Cross-region replication
* Point-in-time recovery
**Redis for query result caching:**
* Use DataBrain's managed Redis or bring your own (BYOC)
* Per-workspace cache configuration
* Configurable TTL per workspace
* Graceful degradation on cache failures
Configure caching for your workspace
***
## Deployment Considerations
### Cloud vs Self-Hosted Comparison
**Best for:**
* Fast time-to-market
* Minimal DevOps resources
* Automatic updates and maintenance
* Built-in scalability
* Lower initial investment
**Considerations:**
* Data passes through DataBrain infrastructure
* Requires internet connectivity
* Less customization options
* Monthly/annual subscription pricing
**Best for:**
* Strict data sovereignty requirements
* Air-gapped environments
* Complete infrastructure control
* Custom compliance needs
* High-volume workloads
**Considerations:**
* Requires infrastructure management
* DevOps/IT resources needed
* Responsible for updates and scaling
* Higher initial setup cost
* One-time license + infrastructure costs
### Self-Hosted Deployment
**Required components:**
* DataBrain Application Server (Node.js)
* PostgreSQL Database (metadata storage)
* Redis Cache (session & query caching)
* Web UI (admin interface)
Deployment instructions and installation packages are provided in your self-hosted license package.
**Connect to your databases:**
* Private network connections within VPC
* Connection pooling configuration
* SSL/TLS certificate setup
* Read replica configuration (optional)
**Configure required environment variables:**
```bash theme={"dark"}
# Database
DB_HOST=your-postgres-host
DB_PORT=5432
DB_NAME=databrain
DB_USER=databrain_user
DB_PASSWORD=secure_password
# Redis (query result caching)
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password
# Application
NODE_ENV=production
PORT=3000
API_BASE_URL=https://your-databrain.company.com
```
**Set up HTTPS for production:**
* Obtain SSL certificates
* Configure reverse proxy (nginx/Apache)
* Enable HTTPS enforcement
* Set up certificate auto-renewal
**Launch DataBrain platform:**
Refer to your self-hosted package for specific deployment commands based on your infrastructure (Docker, Kubernetes, VMs).
### Infrastructure Sizing Guide
**Estimate your resource requirements:**
| Users (Concurrent) | CPU | Memory | Storage | Bandwidth |
| ------------------ | -------------------------------------- | ------ | ------- | --------- |
| 1-50 | 2 vCPU | 4 GB | 20 GB | 100 Mbps |
| 50-200 | 4 vCPU | 8 GB | 50 GB | 500 Mbps |
| 200-500 | 8 vCPU | 16 GB | 100 GB | 1 Gbps |
| 500-1000 | 16 vCPU | 32 GB | 200 GB | 2 Gbps |
| 1000+ | Contact us for enterprise architecture | | | |
**Sizing factors to consider:**
* Dashboard complexity (number of metrics)
* Query complexity and execution time
* Cache hit rate
* Number of dashboards per user
* Refresh rate requirements
***
## Monitoring & Observability
### Key Metrics to Monitor
* Request rate and latency
* Error rates and types
* Token validation success rate
* API endpoint performance
* Query execution time
* Connection pool utilization
* Cache hit/miss ratio
* Failed query rate
* Concurrent users
* Dashboard load times
* User session duration
* Feature usage patterns
* CPU and memory utilization
* Network throughput
* Disk I/O and space
* Container/pod health
### Health Check Endpoints
DataBrain provides health check endpoints for liveness and readiness (including Hasura, Keycloak, and Postgres). See [Health Check APIs](/developer-docs/helpers/api-reference/health-check) for full details.
```bash theme={"dark"}
# Liveness (process is up)
GET /health/live
Response: { "status": "live" }
# Readiness (backend + Hasura, Keycloak, Postgres)
GET /health/ready
Response: { "status": "ready"|"not_ready", "checks": { "hasura", "keycloak?", "postgres" } }
```
### Recommended Monitoring Stack
**Tools:**
* **DataDog / New Relic**: Full-stack APM
* **Prometheus + Grafana**: Open-source metrics
* **CloudWatch**: AWS native monitoring
**Key dashboards:**
* API response times
* Error rate tracking
* Token generation rate
* Active sessions
**Tools:**
* **pgAdmin / DBeaver**: PostgreSQL monitoring
* **Redis Commander**: Redis monitoring
* **Database-specific tools**: CloudSQL, RDS monitoring
**Key metrics:**
* Query performance
* Connection counts
* Cache efficiency
* Slow query log
**Tools:**
* **Kubernetes Dashboard**: K8s clusters
* **AWS CloudWatch**: AWS infrastructure
* **Grafana**: Cross-platform visualization
**Key alerts:**
* High CPU/memory usage
* Disk space warnings
* Network anomalies
* Container restarts
**Tools:**
* **ELK Stack**: Elasticsearch, Logstash, Kibana
* **Splunk**: Enterprise log management
* **CloudWatch Logs**: AWS logging
**Log categories:**
* Application logs
* Access logs
* Error logs
* Audit logs
***
## Troubleshooting & Debugging
### Common Issues
**Symptoms:**
* "UNAUTHORIZED" errors
* "TOKEN\_EXPIRED" messages
* "UNAUTHORIZED\_ORIGIN" errors
**Solutions:**
* Verify API key is correct and active
* Check token expiration time
* Ensure domain is whitelisted
* Verify token is being sent correctly
* Check for clock skew between systems
**Symptoms:**
* Dashboards loading slowly
* Timeouts on complex queries
* High database load
**Solutions:**
* Enable query caching
* Add database indexes
* Optimize RLS rules
* Increase connection pool size
* Use read replicas for analytics
* Review query execution plans
**Symptoms:**
* "Too many connections" errors
* Intermittent connection failures
* Slow response times
**Solutions:**
* Increase max connections in pool config
* Reduce connection idle timeout
* Scale application horizontally
* Optimize query execution time
* Check for connection leaks
**Symptoms:**
* Stale data displayed
* Inconsistent results
* Memory warnings
**Solutions:**
* Reduce cache TTL
* Clear cache manually if needed
* Increase Redis memory
* Review cache invalidation logic
* Check cache hit rate
### Debug Mode
Enable debug logging for troubleshooting:
```javascript theme={"dark"}
// Frontend debugging
window.dbn = {
debug: true,
logLevel: 'verbose'
};
```
This will log:
* Component lifecycle events
* API requests and responses
* Token validation steps
* Error details
***
## Next Steps
Complete step-by-step production deployment guide
Comprehensive security and compliance documentation
Implement row-level security for multi-tenant apps
Complete API documentation for token generation
Advanced proxy mode implementation
Self-hosted deployment configuration
***
## Additional Resources
**Q: How are queries optimized?**\
A: DataBrain applies push-down filters, uses connection pooling, generates indexed queries, and caches results based on your configuration.
**Q: What database permissions are required?**\
A: DataBrain only needs SELECT permissions on the tables you want to query. No write access is required.
**Q: How is high availability achieved?**\
A: Cloud deployments have built-in HA. Self-hosted can deploy with load balancers, multiple app servers, and database replicas.
**Q: Can I customize query generation?**\
A: While DataBrain optimizes queries automatically, you can control them through metric definitions and filter configurations.
**Q: What's the token refresh strategy?**\
A: Generate new tokens before expiration (e.g., when token has 10% life remaining). Your backend should handle this automatically.
**Application Level:**
* Enable query caching with appropriate TTL
* Use connection pooling (adjust based on load)
* Implement CDN for static assets
* Enable compression for API responses
**Database Level:**
* Create indexes on filtered columns
* Use read replicas for analytics workload
* Optimize RLS queries for performance
* Monitor slow query log
**Infrastructure Level:**
* Scale horizontally with load balancing
* Use Redis cluster for caching layer
* Deploy close to your database (reduce latency)
* Implement proper monitoring and alerting
DataBrain maintains industry-leading security certifications:
* **SOC 2 Type II**: Annual audits of security controls
* **ISO 27001**: Information security management
* **GDPR**: European data protection compliance
* **HIPAA**: Healthcare data protection (self-hosted)
* **PCI DSS**: Payment card data security
[View Security Page →](https://www.usedatabrain.com/security)
**Need technical support?**
* 📚 Documentation: [docs.usedatabrain.com](https://docs.usedatabrain.com)
* 💬 Contact support through your DataBrain dashboard
**Enterprise customers:** Contact your dedicated solutions architect for architecture reviews and optimization guidance.
# Production-Ready Embedding Guide
Source: https://docs.usedatabrain.com/developer-docs/embedding-setup/step-by-step-guide
Complete step-by-step guide to embedding DataBrain dashboards in production
This guide walks you through everything you need to embed DataBrain dashboards in a production environment with proper authentication, security, and customization.
## What You'll Build
By the end of this guide, you'll have:
* ✅ A secure backend endpoint that generates guest tokens
* ✅ A frontend application with embedded DataBrain dashboards
* ✅ Row-level security for multi-tenant access control (optional)
* ✅ Customized dashboard appearance matching your brand
* ✅ Production-ready authentication flow
**Requirements:** Basic knowledge of REST APIs, frontend frameworks, and environment variables
## Quick Navigation
Jump to any section:
* [Prerequisites](#prerequisites)
* [Architecture Overview](#architecture-overview)
* [Step 1: Create Workspace & Dashboard](#step-1-create-workspace--dashboard)
* [Step 2: Create Data App](#step-2-create-data-app)
* [Step 3: Backend Integration](#step-3-backend-integration)
* [Step 4: Frontend Integration](#step-4-frontend-integration)
* [Step 5: Testing & Deployment](#step-5-testing--deployment)
* [Next Steps](#next-steps)
## Prerequisites
Ensure you have the following before starting:
| Requirement | Description | Link |
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| **DataBrain Account** | Sign up for a free account | [app.usedatabrain.com](https://app.usedatabrain.com/users/sign-up) |
| **Data Source** | Connected database or data warehouse | [Data Sources Guide](/guides/onboarding-and-configuration/add-a-data-source) |
| **Backend Server** | For secure token generation (Node.js, Python, Go, .NET, etc.) | - |
| **Frontend App** | React, Vue, Angular, or vanilla JS application | - |
## Architecture Overview
**Flow Diagram:**
Understanding the Architecture (Optional Reading)
Here's how the embedding architecture works:
End user logs into your application
Your frontend requests a guest token from your backend
Your backend calls DataBrain API to generate a guest token
```bash theme={"dark"}
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
DataBrain API returns guest token to your backend, which passes it to frontend
Frontend passes token to the dbn-dashboard web component
```html theme={"dark"}
```
Component fetches dashboard data from DataBrain using the guest token
Dashboard renders with user-specific data and permissions
## Step 1: Create Workspace & Dashboard
### 1.1 Create a Workspace
Go to the DataBrain platform and click "Create Workspace"
* Enter workspace name
* Select workspace type (standard or private)
* Configure initial settings
Detailed workspace creation guide
### 1.2 Connect Data Source
Click "Add Data Source" in your workspace
Choose from 18+ supported databases
Provide connection details (host, port, credentials)
Verify the connection works
Set up multi-tenancy if needed
Connect your database
### 1.3 Create Dashboard
Click "New Dashboard" in your workspace
Create charts, tables, and KPIs using the visual builder
Configure dashboard-level filters for interactivity
Arrange metrics and adjust sizing
Save and note your dashboard ID
Build your first dashboard
**Step 1 Complete!**
Before moving to Step 2, verify you have:
* Created a workspace in DataBrain
* Successfully connected at least one data source
* Built and saved a dashboard with metrics
* Noted your dashboard ID for later use
## Step 2: Create Data App
A Data App packages your dashboards for embedding with security and configuration.
### 2.1 Navigate to Data Apps
Go to **Data → Data Apps** in your workspace
### 2.2 Create New Data App
Start creating a new Data App
```json theme={"dark"}
{
"name": "customer-analytics-app",
"description": "Analytics for customer portal",
"workspace": "your-workspace-name"
}
```
* Choose the dashboards you want to expose through the Data App for embedding.
* Browse and select one or more dashboards from your workspace.
* Only selected dashboards can be accessed via guest tokens.
* Save the Data App to generate and use their embed IDs in embedding.
* **Tip:** Add only relevant dashboards to keep access secure and organized.
* Set default permissions
* Configure multi-tenancy
* Set token expiry defaults
Copy your API token - you'll need this for generating guest tokens
**Store your API token securely!** Never commit it to version control or expose it in frontend code. Use environment variables.
### 2.3 Find Your Dashboard ID
Navigate to your Data App
Look for the dashboards list
Each dashboard has a unique ID (e.g., `sales-dashboard-2024`)
Detailed guide on locating IDs
**Step 2 Complete!**
Before moving to Step 3, verify you have:
* Created a Data App in your workspace
* Added your dashboard(s) to the Data App
* Copied and securely stored your API token
* Have your Data App name ready (e.g., `customer-analytics-app`)
## Step 3: Backend Integration
Set up your backend to generate guest tokens securely.
### 3.1 Store API Token
Add your DataBrain API token to environment variables:
```bash .env theme={"dark"}
DATABRAIN_API_TOKEN=dbn_live_abc123...
DATABRAIN_API_URL=https://api.usedatabrain.com
DATA_APP_NAME=customer-analytics-app
```
```yaml docker-compose.yml theme={"dark"}
environment:
- DATABRAIN_API_TOKEN=dbn_live_abc123...
- DATA_APP_NAME=customer-analytics-app
```
```json Kubernetes ConfigMap theme={"dark"}
apiVersion: v1
kind: Secret
metadata:
name: databrain-secrets
type: Opaque
stringData:
api-token: "dbn_live_abc123..."
data-app-name: "customer-analytics-app"
```
### 3.2 Implement Token Generation
Create an API endpoint to generate guest tokens:
```javascript Node.js/Express theme={"dark"}
// routes/databrain.js
const express = require('express');
const router = express.Router();
router.post('/guest-token', async (req, res) => {
try {
const { userId } = req.user; // From your auth middleware
const response = await fetch(
`${process.env.DATABRAIN_API_URL}/api/v2/guest-token/create`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DATABRAIN_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
clientId: userId,
dataAppName: process.env.DATA_APP_NAME,
expiryTime: 3600000 // 1 hour
})
}
);
const data = await response.json();
if (!response.ok) {
throw new Error(data.error?.message || 'Failed to generate token');
}
res.json({ token: data.token });
} catch (error) {
console.error('Token generation error:', error);
res.status(500).json({ error: 'Failed to generate token' });
}
});
module.exports = router;
```
```python Python/FastAPI theme={"dark"}
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
import httpx
import os
router = APIRouter()
class TokenResponse(BaseModel):
token: str
@router.post("/guest-token", response_model=TokenResponse)
async def get_guest_token(current_user: User = Depends(get_current_user)):
try:
async with httpx.AsyncClient() as client:
response = await client.post(
f"{os.getenv('DATABRAIN_API_URL')}/api/v2/guest-token/create",
headers={
"Authorization": f"Bearer {os.getenv('DATABRAIN_API_TOKEN')}",
"Content-Type": "application/json"
},
json={
"clientId": str(current_user.id),
"dataAppName": os.getenv('DATA_APP_NAME'),
"expiryTime": 3600000 # 1 hour
}
)
if response.status_code != 200:
raise HTTPException(status_code=500, detail="Token generation failed")
data = response.json()
return TokenResponse(token=data["token"])
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
```
```go Go/Gin theme={"dark"}
package handlers
import (
"bytes"
"encoding/json"
"net/http"
"os"
"github.com/gin-gonic/gin"
)
type TokenRequest struct {
ClientID string `json:"clientId"`
DataAppName string `json:"dataAppName"`
ExpiryTime int `json:"expiryTime"`
}
type TokenResponse struct {
Token string `json:"token"`
}
func GetGuestToken(c *gin.Context) {
userID := c.GetString("userID") // From auth middleware
reqBody := TokenRequest{
ClientID: userID,
DataAppName: os.Getenv("DATA_APP_NAME"),
ExpiryTime: 3600000, // 1 hour
}
jsonData, _ := json.Marshal(reqBody)
req, _ := http.NewRequest(
"POST",
os.Getenv("DATABRAIN_API_URL")+"/api/v2/guest-token/create",
bytes.NewBuffer(jsonData),
)
req.Header.Set("Authorization", "Bearer "+os.Getenv("DATABRAIN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
c.JSON(500, gin.H{"error": "Token generation failed"})
return
}
defer resp.Body.Close()
var tokenResp TokenResponse
json.NewDecoder(resp.Body).Decode(&tokenResp)
c.JSON(200, tokenResp)
}
```
```csharp C#/.NET theme={"dark"}
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Text;
using System.Text.Json;
[ApiController]
[Route("api/[controller]")]
public class DataBrainController : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
public DataBrainController(
IHttpClientFactory httpClientFactory,
IConfiguration configuration)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
}
[HttpPost("guest-token")]
public async Task GetGuestToken()
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
var requestBody = new
{
clientId = userId,
dataAppName = _configuration["DataBrain:AppName"],
expiryTime = 3600000
};
var client = _httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Post,
$"{_configuration["DataBrain:ApiUrl"]}/api/v2/guest-token/create");
request.Headers.Add("Authorization",
$"Bearer {_configuration["DataBrain:ApiToken"]}");
request.Content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json");
var response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
return StatusCode(500, "Token generation failed");
}
var result = await response.Content.ReadAsStringAsync();
var tokenData = JsonSerializer.Deserialize(result);
return Ok(tokenData);
}
}
```
#### Verify Token Generation
Test your endpoint to ensure tokens are being generated correctly:
```bash cURL theme={"dark"}
curl -X POST http://localhost:3000/api/databrain/guest-token \
-H "Authorization: Bearer your-app-auth-token" \
-H "Content-Type: application/json"
# Expected Response:
# {
# "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# }
```
```javascript Postman/JavaScript theme={"dark"}
// Test in your browser console or Postman
fetch('http://localhost:3000/api/databrain/guest-token', {
method: 'POST',
credentials: 'include'
})
.then(res => res.json())
.then(data => console.log('Token:', data.token))
.catch(err => console.error('Error:', err));
```
Advanced: Add Row-Level Security (Multi-Tenant Apps)
### 3.3 Advanced Token Configuration
Add Row-Level Security (RLS) and filters:
```javascript theme={"dark"}
// With RLS and app filters
const tokenRequest = {
clientId: userId,
dataAppName: process.env.DATA_APP_NAME,
params: {
// Row-level security
rlsSettings: [{
metricId: 'sales-metric',
values: {
customer_id: userCustomerId,
region: userRegion
}
}],
// Dashboard app filters
dashboardAppFilters: [{
dashboardId: 'sales-dashboard',
values: {
date_range: {
startDate: '2024-01-01',
endDate: '2024-12-31'
},
region: userRegion
},
isShowOnUrl: false
}]
},
// Permissions
permissions: {
isEnableDownloadMetrics: true,
isEnableUnderlyingData: false,
isEnableManageMetrics: false
},
expiryTime: 3600000
};
```
Complete token configuration options
**Step 3 Complete!**
Before moving to Step 4, verify you have:
* Environment variables configured with API token
* Backend endpoint created for token generation
* Successfully tested token generation (returns valid JWT)
* Tokens are secured server-side (never exposed to frontend)
## Step 4: Frontend Integration
### 4.1 Install Package
```bash theme={"dark"}
npm install @databrainhq/plugin
```
### 4.2 Create Dashboard Component
Framework-Specific Integration Guides
```javascript React theme={"dark"}
import { useEffect, useState } from 'react';
import '@databrainhq/plugin/web';
function AnalyticsDashboard() {
const [token, setToken] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchToken() {
try {
const response = await fetch('/api/databrain/guest-token', {
method: 'POST',
credentials: 'include' // Include auth cookies
});
if (!response.ok) {
throw new Error('Failed to fetch token');
}
const data = await response.json();
setToken(data.token);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchToken();
}, []);
if (loading) {
return
;
return (
);
};
export default Analytics;
```
**Basic Implementation (All Frameworks):**
```html theme={"dark"}
```
Optional: Customize Dashboard Appearance
### 4.3 Add Customization
```javascript theme={"dark"}
```
All customization options
**Step 4 Complete!**
Before moving to Step 5, verify you have:
* Installed `@databrainhq/plugin` package
* Created a dashboard component in your frontend
* Dashboard successfully fetches token from your backend
* Dashboard renders with data from DataBrain
## Step 5: Testing & Deployment
### 5.1 Test Locally
Ensure your backend token endpoint is running
Run your frontend development server
Check that the dashboard renders correctly
* Click on charts
* Apply filters
* Download CSV
* Test responsive behavior
### 5.2 Environment Variables
Set up environment variables for each environment:
```bash Development theme={"dark"}
DATABRAIN_API_TOKEN=dbn_test_...
DATABRAIN_API_URL=https://api.usedatabrain.com
DATA_APP_NAME=my-app-dev
```
```bash Production theme={"dark"}
DATABRAIN_API_TOKEN=dbn_live_...
DATABRAIN_API_URL=https://api.usedatabrain.com
DATA_APP_NAME=my-app-prod
```
**🎉 Congratulations! You're Production-Ready**
Your embedded analytics are now live! You've successfully:
* Created DataBrain workspace and dashboards
* Set up secure backend token generation
* Integrated dashboard into your frontend
* Deployed to production
**What's next?** Explore multi-tenancy, SSO, and advanced customization below.
## Next Steps
Implement row-level security
Set up single sign-on
Deep dive into options
Common implementation patterns
# Introduction
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide
This article will guide you integrate databrain plugin in your respective UI framework/libraries.
# Angular
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/angular
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
View the complete Angular integration example on GitHub
## Usage
Add support for custom elements/web components in `app.module.ts`
```ts theme={"dark"}
// app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
// server event
(window as any).databrainServerEvent = (error: any) => {
console.log(error);
};
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
```
### Import in `app.component.ts`
```ts theme={"dark"}
import '@databrainhq/plugin/web';
```
### Then use it anywhere in your app
#### Integrating Dashboard
```html theme={"dark"}
```
#### Integrating Metric
```html theme={"dark"}
```
customMessages - In your parent component, assign the `customMessages` prop like this:
```ts theme={"dark"}
this.customMessages = {
tokenExpiry: "Some custom message you want to show here."
};
```
metricFilterOptions - In your parent component, assign the `metricFilterOptions` prop like this:
```ts theme={"dark"}
this.metricFilterOptions = { // note that invalid options will be filtered out
"Filter name for a string datatype": {
options: ['hello', 'hi'], // should have unique elements
defaultOption: 'hello', // name of the option
},
"Filter name for a number datatype": {
options: [9, 19, 23], // should have unique elements
defaultOption: 19, // name of the option
},
"Filter name for a date datatype": {
options: [{
range: 'Last|This|Custom', // one of the three option
time: 'Day|Week|Month|Quarter|Year', // one of the five option ignored for range = "Custom"
name: 'Last 10 Years', // will be shown in the list
count: 10, // required for range = "Last" else ignored
fromDate: new Date(), // optional if you don't want date picker for custom range else ignored
toDate: new Date(), // optional if you don't want date picker for custom range else ignored
minDate: new Date(), // optional for custom range else ignored
maxDate: new Date(), // optional for custom range else ignored
},{
range: 'Last|This|Custom', // one of the three option
time: 'Day|Week|Month|Quarter|Year', // one of the five option for range "Custom" nit required
name: 'This Year', // will be shown in the list
count: 0, // required for range "Last" else not required
minDate: new Date(), // optional for custom range
maxDate: new Date(), // optional for custom range
}],
defaultOption: 'Last 10 Years', // name of the option
},
}
```
appearanceOptions - In your parent component, assign the `appearanceOptions` prop like this:
```ts theme={"dark"}
this.appearanceOptions = {
appearanceOptionsPosition: 'top-left|top-right|bottom-left|bottom-right', // one of the four options, by default it is bottom-right
cumulativeBar: {
isEnabled: true|false, // can be used with bar and time series charts (if series type is bar)
label: 'Cumulative' // change the label for the property
},
stackedBars: {
isEnabled: true|false, // can be used with stack chart only
label: '100% stacked bars', // change the label for the property
},
dynamicBehaviour: {
isEnabled: true|false, // can be used with bar, line, area, stacked area and time series charts
label: 'Dynamic' //change the label for the property
},
}
```
# Nextjs
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/nextjs
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
View the complete Next.js integration example on GitHub
## Usage
### Quick usage:
```tsx theme={"dark"}
"use client";
import '@databrainhq/plugin/web';
export default function Home() {
const url = new URL(location.href);
const token = url.searchParams.get("token");
const dashboardId = url.searchParams.get("dashboardId");
return (
);
}
declare global {
namespace JSX {
interface IntrinsicElements {
"dbn-dashboard": any;
"dbn-metric": any;
}
}
}
```
For embedding a Metric Card you can use the `dbn-metric` webcomponent:
```html theme={"dark"}
```
* To find dashboardId please see here.
* To find metricId please see here.
## Token
The [`token`](https://docs.usedatabrain.com/developer-docs/token) should be a guest token, fetched from your backend based on the current user's login information. You can see more [about it here](https://docs.usedatabrain.com/developer-docs/token).
Here is an example with sample token and dashboardId that you can use in your frontend app to get started without a backend.
```html theme={"dark"}
```
### **Breakdown:**
Import the library main or index or App or layout file
```js theme={"dark"}
import '@databrainhq/plugin/web';
```
Once the library is imported, the web-components `dbn-dashboard`, `dbn-metrics` are available to use anywhere inside your app. And you can use it anywhere in your app like:
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
## Integrating metric
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
To see the full list of options please check the [options list](https://docs.usedatabrain.com/developer-docs/helpers/options).
# Reactjs
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/reactjs
## @databrainhq/plugin
> Databrain app UI web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
To see the full list of options please check the [options list](https://docs.usedatabrain.com/developer-docs/helpers/options).
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
View the complete React integration example on GitHub
## Usage
**Quick usage:**
```tsx showLineNumbers title="App.tsx" theme={"dark"}
// React + Databrain plugin example
import React, { useState, useEffect } from 'react';
import '@databrainhq/plugin/web';
import './App.css';
declare global {
namespace JSX {
interface IntrinsicElements {
'dbn-dashboard': any;
'dbn-metric': any;
}
}
}
function App() {
const [token, setToken] = useState(null);
const dashboardId = 'your-dashboard-id'; // Replace with your actual dashboard ID
useEffect(() => {
const fetchToken = async () => {
try {
const response = await fetch('/fetch-guest-token');
if (!response.ok) {
throw new Error('Failed to fetch token');
}
const data = await response.json();
setToken(data.token); // Assuming the API returns the token in a 'token' field
} catch (error) {
console.error('Error fetching token:', error);
}
};
fetchToken();
}, []);
if (!token) {
return
Loading...
;
}
return (
);
}
export default App;
```
For embedding a Metric Card you can use the `dbn-metric` webcomponent:
```html theme={"dark"}
```
### Token
The [`token`](https://docs.usedatabrain.com/developer-docs/helpers/token-body) should be a guest token, fetched from your backend based on the current user's login information. You can follow the document below for guest token generation.
Here is an example with sample token and dashboardId that you can use in your frontend app to get started without a backend.
```html theme={"dark"}
```
#### Breakdown:
Import the library main or index or App or layout file
```ts theme={"dark"}
import '@databrainhq/plugin/web';
```
Once the library is imported, the web-components `dbn-dashboard`, `dbn-metrics` are available to use anywhere inside your app. And you can use it anywhere in your app like:
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
## Intgerating Metric
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
# Solid
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/solid
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
View the complete Solid.js integration example on GitHub
## Usage
Import in main/index/App
```ts theme={"dark"}
import '@databrainhq/plugin/web';
```
Then use it anywhere in your app
## Integrating Dashboard:
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
## Integrating Metric
```tsx theme={"dark"}
const Example = () => {
return (
);
};
```
# Svelte
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/svelte
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
View the complete Svelte integration example on GitHub
## Usage
Import in main/index/App
```svelte theme={"dark"}
```
### Integrating Dashboard
```svelte theme={"dark"}
```
### Integrating Metric
```svelte theme={"dark"}
```
# Vanilla JS
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/vanillajs
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Github Repo Link
[https://github.com/databrainhq/dbn-demos-updated/tree/main/dbn-demo-vanilla](https://github.com/databrainhq/dbn-demos-updated/tree/main/dbn-demo-vanilla)
## Usage
In your index.html file, add the following script
```html theme={"dark"}
```
**Note:** If you want to use a specific version, add the version in place of latest. For example
```html theme={"dark"}
```
**If you get process error in your console, add the below script above your cdn script**
```html theme={"dark"}
```
Use global document object to create components. Add the below script in your script file like main.js or inside script tags.
### Integrating Dashboard:
```js theme={"dark"}
function initDashboard() {
const url = new URL(location.href);
const token = url.searchParams.get("token") || "";
const dashboardId = url.searchParams.get("dashboardId") || "";
// Create the dashboard element
const dashboardElement = document.createElement('dbn-dashboard');
// Set attributes
if (token) {
dashboardElement.setAttribute('token', token);
}
if (dashboardId) {
dashboardElement.setAttribute('dashboard-id', dashboardId);
}
// Append the dashboard to the body
document.body.appendChild(dashboardElement);
}
// Initialize the dashboard when the DOM is fully loaded
document.addEventListener('DOMContentLoaded', initDashboard);
```
### Integrating Metric
```js theme={"dark"}
function initMetric() {
const url = new URL(location.href);
const token = url.searchParams.get("token") || "";
const dashboardId = url.searchParams.get("metricId") || "";
// Create the metric element
const metricElement = document.createElement('dbn-metric');
// Set attributes
if (token) {
metricElement.setAttribute('token', token);
}
if (dashboardId) {
metricElement.setAttribute('metric-id', dashboardId);
}
// Append the metric to the body
document.body.appendChild(metricElement);
}
// Initialize the metric when the DOM is fully loaded
document.addEventListener('DOMContentLoaded', initMetric);
```
**Note:** If you don't want to use cdn link, you can install the below npm package.
```bash theme={"dark"}
npm i @databrainhq/plugin
```
Add import statement like below in your main.js file.
```js theme={"dark"}
import "@databrainhq/plugin/web";
```
# Vuejs
Source: https://docs.usedatabrain.com/developer-docs/framework-specific-guide/vuejs
## @databrainhq/plugin
> Databrain app ui web component plugin.
v0.15.135-uat
Enforced using StandardJS styleguide.
## Install
```bash theme={"dark"}
npm install @databrainhq/plugin
```
## Github Repo Link
[https://github.com/databrainhq/dbn-demos-updated/tree/main/dbn-demo-vue](https://github.com/databrainhq/dbn-demos-updated/tree/main/dbn-demo-vue)
## Usage
Import in `App/main/index.(vue/ts/js)`:
```ts theme={"dark"}
import '@databrainhq/plugin/web';
```
### Integrating Dashboard
```html theme={"dark"}
```
### Integrating metric
```html theme={"dark"}
```
# Admin Authentication Flow
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/admin-authentication-flow
Understand the complete flow for setting up and managing admin authentication on self-hosted Databrain instances.
This guide walks you through the complete authentication flow for self-hosted Databrain instances. Follow these steps in order to set up your admin account and service tokens.
**Self-Hosted Only:** All endpoints described in this flow are available only on **self-hosted** Databrain instances. They will return errors on cloud (SaaS) deployments.
## Step-by-Step Process
If this is your first time setting up your self-hosted instance, create the initial admin account using the [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account) endpoint.
**What you need:**
* Admin first name
* Admin email address
* Secure password (meets complexity requirements)
* Company name
**What you get:**
* An `accessToken` (JWT) that you can use for subsequent admin operations
This step is only needed once. If an admin account already exists, proceed to step 2.
For existing admin accounts, sign in using the [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) endpoint to receive an access token.
**What you need:**
* Admin email address
* Admin password
**What you get:**
* An `accessToken` (JWT) for authenticated admin operations
Use this token in the `Authorization: Bearer ` header for admin-only endpoints.
Once you have an admin access token, create a service token using the [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) endpoint.
**What you need:**
* Admin `accessToken` from step 1 or 2 (in Authorization header)
* A UUID value for the service token
**What you get:**
* A `serviceToken` (UUID) that can be used for organization-level operations such as:
* Creating Data App API tokens
* Managing Data Apps
* Export/import operations
Generate a UUID using your preferred method (e.g., `uuidv4()` in Node.js, `uuid.uuid4()` in Python). Store this token securely as it provides elevated permissions.
Periodically rotate your service token for enhanced security using the [Rotate Service Token](/developer-docs/helpers/api-reference/rotate-service-token) endpoint.
**What you need:**
* Admin `accessToken` (in Authorization header)
* Current service token UUID
* Expiration grace period (in seconds)
**What you get:**
* A new `serviceToken` UUID
* The old token expires after the grace period
Use a grace period (e.g., 3600 seconds = 1 hour) to allow time for updating clients before the old token stops working.
Change your admin password using the [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password) endpoint.
**What you need:**
* Admin `accessToken` (in Authorization header)
* Current password
* New password (meets complexity requirements)
**What you get:**
* Confirmation that the password was changed successfully
After resetting your password, you'll need to sign in again using Create Admin JWT to get a new access token.
## Common Scenarios
**Complete flow for new installations:**
1. Create Admin Account → Get `accessToken`
2. Create Service Token → Get `serviceToken`
3. Use `serviceToken` for organization operations
This is a one-time setup process.
**For existing admin accounts:**
1. Create Admin JWT → Get `accessToken`
2. Use `accessToken` for admin operations
3. Create or rotate service tokens as needed
Repeat this whenever you need to perform admin operations.
**For security best practices:**
1. Create Admin JWT → Get `accessToken`
2. Rotate Service Token → Get new `serviceToken`
3. Update all clients with new `serviceToken`
4. Old token expires after grace period
Rotate tokens periodically (recommended: every 6 months).
**When you need to change your password:**
1. Create Admin JWT → Get `accessToken`
2. Reset Admin Password → Confirm change
3. Create Admin JWT again → Get new `accessToken`
After password reset, your old access tokens may become invalid.
## Security Best Practices
* Never commit tokens to version control
* Use environment variables or secrets managers
* Rotate tokens regularly
* Minimum 8 characters
* Mix of uppercase, lowercase, digits, and special characters
* No spaces
* Rotate service tokens every 6 months
* Use grace periods during rotation
* Update all clients before expiration
* Track token usage
* Revoke compromised tokens immediately
* Use separate tokens for different environments
## Related Documentation
* [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account) – Create the first admin account
* [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) – Sign in and get access token
* [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) – Create organization service token
* [Rotate Service Token](/developer-docs/helpers/api-reference/rotate-service-token) – Rotate service token securely
* [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password) – Change admin password
# Fetch Dashboards by Workspace
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/cloud-databrain-endpoint
POST https://api.usedatabrain.com/api/v2/workspace/dashboards
Retrieve a list of dashboards available in a workspace with optional pagination support.
Retrieve a list of dashboards available in a workspace. Use this endpoint to discover dashboards for provisioning and embedding in your application.
This endpoint operates at the workspace level using a service token. Use the workspace name to scope which dashboards are returned. Supports pagination for workspaces with many dashboards.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the workspace to fetch dashboards from. Must match an existing workspace in your organization.
* Use the [List Workspaces](/developer-docs/helpers/api-reference/list-workspaces) endpoint to see all available workspaces
* Names are case-sensitive
* Must be an exact match
Enable pagination to retrieve dashboards in batches of 10.
* `true`: Enable pagination with page-based retrieval (10 items per page)
* `false` (default): Return all dashboards in a single response
- Use pagination when you have more than 20 dashboards in a workspace
- Improves response times for large datasets
- Each page returns up to 10 dashboards
The page number to retrieve when pagination is enabled. Pages are 1-indexed.
**Note:** This parameter is only used when `isPagination` is set to `true`.
## Response
Array of dashboard objects. Returns empty array if no dashboards exist or page number exceeds available pages.
Display name of the dashboard.
Unique identifier for the dashboard.
Error object if the request failed, otherwise `null` for successful requests.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - All Dashboards theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "my-workspace"
}'
```
```bash cURL - With Pagination theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "my-workspace",
"isPagination": true,
"pageNumber": 1
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace/dashboards', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
workspaceName: 'my-workspace',
isPagination: true,
pageNumber: 1
})
});
const result = await response.json();
console.log('Dashboards:', result.data);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/workspace/dashboards',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'workspaceName': 'my-workspace',
'isPagination': True,
'pageNumber': 1
}
)
result = response.json()
print(f"Dashboards: {result['data']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/workspace/dashboards')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
workspaceName: 'my-workspace',
isPagination: true,
pageNumber: 1
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Dashboards: #{result['data']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class FetchDashboards {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"workspaceName": "my-workspace",
"isPagination": true,
"pageNumber": 1
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/workspace/dashboards"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type DashboardRequest struct {
WorkspaceName string `json:"workspaceName"`
IsPagination bool `json:"isPagination,omitempty"`
PageNumber int `json:"pageNumber,omitempty"`
}
func main() {
reqData := DashboardRequest{
WorkspaceName: "my-workspace",
IsPagination: true,
PageNumber: 1,
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/workspace/dashboards",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'my-workspace',
'isPagination' => true,
'pageNumber' => 1
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
print_r($result['data']);
?>
```
```json 200 - Success theme={"dark"}
{
"data": [
{
"name": "Sales Dashboard",
"externalDashboardId": "sales_dash_123"
},
{
"name": "Marketing Analytics",
"externalDashboardId": "marketing_dash_456"
}
],
"error": null
}
```
```json 200 - Empty Results theme={"dark"}
{
"data": [],
"error": null
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"workspaceName\" is required"
}
}
```
```json 400 - Workspace Not Found theme={"dark"}
{
"error": {
"code": "WORKSPACE_ID_ERROR",
"message": "The workspace name provided does not exist"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "API Key is not provided or Invalid!"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Dashboards retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------ |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid request body parameters |
| `WORKSPACE_ID_ERROR` | 400 | Workspace name does not exist |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid or expired API key |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Next Steps
Retrieve metrics from a workspace
List all workspaces in your organization
Create a new workspace for your analytics environment
Generate secure tokens for embedded access
# Create Admin Account (Self-Hosted)
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-admin-account
POST https://api.usedatabrain.com/api/v2/admin-account
Create the first admin account for your self-hosted Databrain instance. Returns an access token for the new admin. Self-hosted only.
Create the initial admin user and company for a self-hosted deployment. On success, the API returns an access token that can be used for subsequent admin operations (e.g. creating a service token, managing Data Apps). Only one company can exist on a self-hosted instance; if an account already exists, sign in via [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) instead.
**Self-Hosted Only:** This endpoint is available only on **self-hosted** Databrain instances. Calling it on cloud will return an error.
## Headers
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
Admin user's first name. Must be between **3 and 30 characters**.
Admin user's email address. Must be a valid email with at least two domain segments (e.g. `user@example.com`). Some common consumer email domains may be blocked (e.g. gmail, yahoo, outlook).
Password for the admin account. Must meet:
* Minimum **8 characters**
* At least **1 uppercase** letter
* At least **1 lowercase** letter
* At least **1 digit**
* At least **1 special character**
* **No spaces**
Name of the company/organization to create for this admin.
## Response
On success, the API returns **200** with a JSON object:
Wrapper object for the response payload.
JWT access token for the newly created admin. Use this in the `Authorization: Bearer ` header for admin APIs (e.g. [Create Service Token](/developer-docs/helpers/api-reference/create-service-token), [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password)).
On error, the API returns a JSON object with `error.code` and `error.message` and an appropriate HTTP status (400 or 500).
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/admin-account \
--header 'Content-Type: application/json' \
--data '{
"firstName": "Admin",
"email": "admin@company.com",
"password": "SecureP@ss1",
"companyName": "My Company"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/admin-account', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
firstName: 'Admin',
email: 'admin@company.com',
password: 'SecureP@ss1',
companyName: 'My Company'
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
const accessToken = data.data.accessToken;
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/admin-account"
headers = {"Content-Type": "application/json"}
payload = {
"firstName": "Admin",
"email": "admin@company.com",
"password": "SecureP@ss1",
"companyName": "My Company"
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if data.get("error"):
raise Exception(data["error"].get("message", "Request failed"))
access_token = data["data"]["accessToken"]
```
```json Success (200) theme={"dark"}
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
```
```json Error (400) - Validation (Joi) theme={"dark"}
{
"error": {
"code": "INVALID REQUEST BODY",
"message": "\"firstName\" is required"
}
}
```
```json Error (400) - Company already exists (self-hosted) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST",
"message": "Your company account is already created, please sign in"
}
}
```
```json Error (500) theme={"dark"}
{
"error": {
"code": "SELFHOSTED_APP_ERROR",
"message": "This feature is only available for self-hosted instances"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ----------------------------------------------------------------------------------------------------------- |
| `200` | **OK** – Admin account created; `data.accessToken` returned |
| `400` | **Bad Request** – Validation error (invalid email, weak password, missing fields) or company already exists |
| `500` | **Internal Server Error** – Server error or self-hosted-only error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------- | ----------- |
| `INVALID REQUEST BODY` | Joi validation message (e.g. `"firstName" is required`, `"password" should contain at least 1 uppercase character`) | 400 |
| `INVALID_REQUEST` | Your company account is already created, please sign in | 400 |
| `SELFHOSTED_APP_ERROR` | This feature is only available for self-hosted instances | 500 |
| `INTERNAL_SERVER_ERROR` | INTERNAL\_SERVER\_ERROR | 500 |
## Related
* [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) – Sign in and get an access token for an existing admin
* [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) – Create a service token using the admin access token
* [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password) – Change password for the authenticated admin
# Create Admin JWT (Self-Hosted)
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-admin-jwt
POST https://api.usedatabrain.com/api/v2/admin-account/jwt
Sign in as an admin and receive a JWT access token for self-hosted Databrain. Use this token for service token and admin APIs. Self-hosted only.
Sign in with an existing admin email and password to receive a JWT access token. Use this token in the `Authorization` header when calling admin-only endpoints such as [Create Service Token](/developer-docs/helpers/api-reference/create-service-token), [Rotate Service Token](/developer-docs/helpers/api-reference/rotate-service-token), and [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password).
**Self-Hosted Only:** This endpoint is available only on **self-hosted** Databrain instances.
## Headers
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
Admin user's email address. Must be a valid email with at least two domain segments.
Admin user's password.
## Response
On success, the API returns **200** with a JSON object:
Wrapper object for the response payload.
JWT access token. Use as `Authorization: Bearer ` for admin and service-token APIs.
On error, the API returns a JSON object with `error.code` and `error.message` and an appropriate HTTP status (400 or 500).
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/admin-account/jwt \
--header 'Content-Type: application/json' \
--data '{"email":"admin@company.com","password":"SecureP@ss1"}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/admin-account/jwt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'admin@company.com',
password: 'SecureP@ss1'
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
const accessToken = data.data.accessToken;
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/admin-account/jwt"
headers = {"Content-Type": "application/json"}
payload = {
"email": "admin@company.com",
"password": "SecureP@ss1"
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if data.get("error"):
raise Exception(data["error"].get("message", "Request failed"))
access_token = data["data"]["accessToken"]
```
```json Success (200) theme={"dark"}
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
```
```json Error (400) - Wrong password theme={"dark"}
{
"error": {
"code": "Invalid credentials",
"message": "Invalid credentials"
}
}
```
```json Error (400) - User not found theme={"dark"}
{
"error": {
"code": "USER_NOT_FOUND",
"message": "No User found with the given email"
}
}
```
```json Error (500) theme={"dark"}
{
"error": {
"code": "SELFHOSTED_APP_ERROR",
"message": "This feature is only available for self-hosted instances"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------ |
| `200` | **OK** – Access token returned in `data.accessToken` |
| `400` | **Bad Request** – Invalid credentials or validation error |
| `500` | **Internal Server Error** – Server error or self-hosted-only error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | --------------------------------------------------------------- | ----------- |
| `USER_NOT_FOUND` | No User found with the given email | 400 |
| `Invalid credentials` | Invalid credentials (when password is incorrect or login fails) | 400 |
| `SELFHOSTED_APP_ERROR` | This feature is only available for self-hosted instances | 500 |
| `INTERNAL SERVER ERROR` | Connection Failure | 500 |
## Related
* [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account) – Create the first admin account
* [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) – Create a service token (requires this JWT)
* [Reset Admin Password](/developer-docs/helpers/api-reference/reset-admin-password) – Change admin password (requires this JWT)
# Create API Token for Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-api-token
POST https://api.usedatabrain.com/api/v2/data-app/api-tokens
Generate a new API token for a specific Data App to enable embed operations.
Create a new API token for a Data App. API tokens are used to authenticate requests for embed operations such as creating embeds, generating guest tokens, and querying metrics.
Each Data App can have multiple API tokens. This is useful for:
* Separating tokens by environment (development, staging, production)
* Rotating tokens without service interruption
* Tracking API usage by token
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage API tokens across your organization.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app/api-tokens
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/api-tokens
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The name of the Data App to create the API token for. This must exactly match an existing Data App name.
* Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to get all Data App names
* Check your Databrain dashboard for Data App configurations
* The name is case-sensitive
A descriptive name/label for the API token. This helps identify the token's purpose.
* Use descriptive names like "Production Token", "Development Token", "Partner API Key"
* Include environment or purpose information
* Keep names unique within each Data App for easy identification
## Response
The newly generated API token (UUID format). Store this securely as it will be used for all embed operations.
**Important:** The API key is only shown once. Store it securely immediately after creation.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/api-tokens \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{
"dataAppName": "Customer Portal Analytics",
"name": "Production API Key"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/api-tokens', {
method: 'POST',
headers: {
'Authorization': 'Bearer service_token_xyz...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dataAppName: 'Customer Portal Analytics',
name: 'Production API Key'
})
});
const data = await response.json();
console.log('New API Key:', data.key);
// Store this key securely!
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/api-tokens"
headers = {
"Authorization": "Bearer service_token_xyz...",
"Content-Type": "application/json"
}
payload = {
"dataAppName": "Customer Portal Analytics",
"name": "Production API Key"
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
print(f"New API Key: {data['key']}")
# Store this key securely!
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateApiToken {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"dataAppName": "Customer Portal Analytics",
"name": "Production API Key"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/api-tokens"))
.header("Authorization", "Bearer service_token_xyz...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
// Store the key securely!
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type CreateApiTokenRequest struct {
DataAppName string `json:"dataAppName"`
Name string `json:"name"`
}
type CreateApiTokenResponse struct {
Key string `json:"key"`
Error interface{} `json:"error"`
}
func main() {
requestBody := CreateApiTokenRequest{
DataAppName: "Customer Portal Analytics",
Name: "Production API Key",
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/data-app/api-tokens", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer service_token_xyz...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result CreateApiTokenResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("New API Key: %s\n", result.Key)
// Store this key securely!
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Customer Portal Analytics',
'name' => 'Production API Key'
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/data-app/api-tokens',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer service_token_xyz...',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo 'New API Key: ' . $result['key'];
// Store this key securely!
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/api-tokens')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
request['Content-Type'] = 'application/json'
request.body = {
dataAppName: 'Customer Portal Analytics',
name: 'Production API Key'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "New API Key: #{result['key']}"
# Store this key securely!
```
```json 200 - Success theme={"dark"}
{
"key": "550e8400-e29b-41d4-a716-446655440000"
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"dataAppName\" is required"
}
}
```
```json 400 - Data App Not Found theme={"dark"}
{
"error": {
"code": "DATA_APP_NOT_FOUND",
"message": "Data app not found"
}
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - API token created successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | -------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid dataAppName or name |
| `DATA_APP_NOT_FOUND` | 400 | Data App with given name not found |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## API Token Scope
When an API token is created, it is automatically assigned the following scope:
* **Access Metrics** - Query and retrieve metric data
* **Access Dashboards** - Access and embed dashboards
## Quick Start Guide
In **Settings** page, navigate to the **Service Tokens** section. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to confirm the Data App exists:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
Create a new API token for your Data App:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/api-tokens \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{"dataAppName": "My Data App", "name": "Production Token"}'
```
The response contains the API key. Store it securely as it won't be shown again:
```javascript theme={"dark"}
// Store in environment variables
process.env.DATABRAIN_API_KEY = response.key;
// Or in a secrets manager
await secretsManager.setSecret('databrain-api-key', response.key);
```
Use the new API key to create embeds and generate guest tokens:
```bash theme={"dark"}
curl --request POST \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds' \
--header 'Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{...}'
```
## Best Practices
Never commit API keys to version control. Use environment variables or secrets managers.
Name tokens clearly (e.g., "Production API Key", "Dev Environment Token")
Rotate API keys periodically for enhanced security using the [Rotate API Key](/developer-docs/helpers/api-reference/rotate-api-key) endpoint.
Create separate tokens for development, staging, and production environments.
## Next Steps
View all API tokens for a Data App
Rotate API keys for enhanced security
Use your API token to create embed configurations
Generate guest tokens for your end users
# Create an Empty Dashboard Embed
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-dashboard-embed
POST https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds
Create a new empty dashboard for multi-tenant scenarios where each client gets their own blank canvas.
Create a **new empty dashboard** in your data app. This endpoint is designed for multi-tenant scenarios where each client needs their own dashboard instance to build upon. Use `templateDashboardId` to clone filters and settings from an existing dashboard.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/dashboard-embeds`. The old endpoint `/api/v2/dataApp/dashboard-embeds` will be deprecated soon. Please update your integrations to use the new endpoint format.
This endpoint creates a **new empty dashboard**. To embed an **existing pre-built dashboard** from your workspace, use the [Embed a Pre-built Dashboard/Metric](/developer-docs/helpers/api-reference/create-embed) endpoint instead.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/dashboard-embeds
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Supported values:
* `application/json` for pure JSON payloads
* `multipart/form-data` when uploading a dashboard export JSON file via `importDashboardDataFile`
```
Content-Type: application/json
```
When using `multipart/form-data`, object/boolean/array fields (for example `accessSettings`, `metadata`, `importDashboardData`, `isImportMetrics`, `isRenameDashboard`, `schemaPairs`) can be sent as JSON strings. Databrain parses these before validation.
`importDashboardDataFile` is a multipart file field (not a JSON body field). The uploaded file must be sent with MIME type `application/json` and contain a top-level `data` object.
## Request Body
Unique identifier for the new dashboard. Must be unique within the data app.
The name of the workspace where the dashboard will be created.
Client ID for the dashboard owner. Used for multi-tenant isolation and row-level security.
Dashboard ID to clone filters, grid margins, and layout settings from (optional).
Custom metadata for the dashboard (optional).
Allow users to create private metrics visible only to them (optional).
Human-readable name for the embed configuration (optional). If not provided, the dashboard ID is used as the name. When `isRenameDashboard` is `true`, this value is also used as the underlying dashboard's display name.
Description for the embed configuration (optional).
When `true` and `templateDashboardId` is provided, metrics from the template dashboard are imported into the new dashboard (optional).
Full dashboard configuration to import into the newly created client dashboard (optional). This should be the `data` object from a dashboard export payload (for example, from the [Export Dashboard](/developer-docs/helpers/api-reference/export-dashboard) API or the **Export Embed Dashboard** API). When `importDashboardData` is provided, Databrain skips `templateDashboardId`-based metric import and directly hydrates the new dashboard from this configuration.
Optional JSON file upload alternative to `importDashboardData`. Upload a dashboard export JSON file (the payload that contains a top-level `data` object). When provided, Databrain reads `data` from the file and uses it as `importDashboardData`.
If both `importDashboardData` and `importDashboardDataFile` are provided, `importDashboardDataFile` takes precedence.
When `true` and `name` is provided, the created dashboard's display name is set to `name`. When `false` or omitted, the dashboard name is set to `{dashboardId}_{clientId}` (optional). Defaults to `false` if omitted.
When `isImportMetrics` is `true` and `templateDashboardId` is provided, controls how metrics are imported: `GALLERY` or `METRIC` (optional).
Optional. Same shape as **[Import Dashboard](/developer-docs/helpers/api-reference/import-dashboard)** **`schemaPairs`**: an array of objects; each object requires **`replaceSchema`** (string) and **`targetSchema`** (string). Use this when imported SQL references a schema name that should map to the target datamart schema.
Typically used with **`importDashboardData`** or **`importDashboardDataFile`**. With **`multipart/form-data`**, send **`schemaPairs`** as a JSON-encoded string (see note above); the server parses it before Joi validation.
Access control settings for the dashboard.
The datamart name used in the embedded environment.
Allow AI Pilot features (optional).
Allow sending email reports.
Allow managing metrics.
Allow metric creation.
Allow metric deletion.
Allow layout changes to metrics.
Allow updating metrics.
Allow viewing of underlying data.
Allow creating dashboard views.
Optional. Enables end-user dashboard filter interactions in embedded mode.
Optional allowlist for dashboard filterable columns. Each item must include `tableName` and `columns`.
Fully qualified table name used in dashboard filters.
Column names allowed for dashboard filter evaluation for the specified table.
Optional. Enables end-user metric filter interactions in embedded mode.
Optional allowlist for columns that end users can use in metric filters. Each item must include `tableName` and `columns`.
Fully qualified table name used in metric filters.
Column names allowed for metric filter evaluation for the specified table.
Recommended join strategy for table relationships.
* `single`: single worksheet mode (tables are pre-joined into one worksheet)
* `multi`: multi-sheet mode (joins are resolved dynamically based on fields used in each chart)
Legacy join strategy flag. Prefer using `accessSettings.joinModel` instead.
Mode of metric creation (drag and drop or chat).
List of allowed tables and client columns for table tenancy (optional). When provided, each item must include `name` and `clientColumn`.
Table name. Required when the parent `tableTenancySettings` array is provided.
Client-level column for table tenancy. Required when the parent `tableTenancySettings` array is provided.
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"dashboardId": "client-acme-dashboard",
"workspaceName": "analytics-workspace",
"clientId": "acme-corp-123",
"templateDashboardId": "template-dashboard-001",
"metadata": {
"clientName": "Acme Corporation",
"region": "North America"
},
"isAllowPrivateMetricsByDefault": false,
"name": "ACME Analytics Dashboard",
"embedDescription": "Analytics dashboard for ACME Corp",
"isImportMetrics": true,
"isRenameDashboard": true,
"metricImportMode": "GALLERY",
"importDashboardData": {
"...": "dashboard configuration exported from the Export Dashboard or Export Embed Dashboard API"
},
"accessSettings": {
"datamartName": "customer-analytics",
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"isAllowCreateDashboardView": true,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"name": "sales_data",
"clientColumn": "customer_id"
}
]
}
}'
```
```bash cURL (Multipart File Upload) theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--form 'dashboardId=client-acme-dashboard' \
--form 'workspaceName=analytics-workspace' \
--form 'clientId=acme-corp-123' \
--form 'name=ACME Analytics Dashboard' \
--form 'isRenameDashboard=true' \
--form 'accessSettings={"datamartName":"customer-analytics","isAllowEmailReports":false,"isAllowManageMetrics":true,"isAllowEndUserMetricFilter":true,"metricFilterColumns":[{"tableName":"public.sales_data","columns":["region","order_date"]}],"isAllowMetricCreation":true,"isAllowMetricDeletion":false,"isAllowMetricLayoutChange":true,"isAllowMetricUpdate":true,"isAllowUnderlyingData":false,"isAllowCreateDashboardView":true,"joinModel":"multi","metricCreationMode":"DRAG_DROP"}' \
--form 'importDashboardDataFile=@./dashboard-export.json;type=application/json'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dashboardId: `client-${clientId}-dashboard`,
workspaceName: 'analytics-workspace',
clientId: clientId,
templateDashboardId: 'template-dashboard-001',
metadata: {
clientName: 'Acme Corporation',
createdAt: new Date().toISOString()
},
isAllowPrivateMetricsByDefault: false,
name: 'ACME Analytics Dashboard',
embedDescription: 'Analytics dashboard for ACME Corp',
isImportMetrics: true,
isRenameDashboard: true,
metricImportMode: 'GALLERY',
importDashboardData: exportedDashboard.data, // from Export Dashboard or Export Embed Dashboard API
accessSettings: {
datamartName: 'customer-analytics',
isAllowAiPilot: true,
isAllowEmailReports: false,
isAllowManageMetrics: true,
isAllowEndUserDashboardFilter: true,
dashboardFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['customer_id', 'region', 'order_date']
}
],
isAllowEndUserMetricFilter: true,
metricFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['region', 'order_date']
}
],
isAllowMetricCreation: true,
isAllowMetricDeletion: false,
isAllowMetricLayoutChange: true,
isAllowMetricUpdate: true,
isAllowUnderlyingData: false,
isAllowCreateDashboardView: true,
joinModel: 'multi',
metricCreationMode: 'DRAG_DROP',
tableTenancySettings: [
{
name: 'sales_data',
clientColumn: 'customer_id'
}
]
}
})
});
const data = await response.json();
console.log('New dashboard ID:', data.id, 'Name:', data.name);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
import json
url = "https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
payload = {
"dashboardId": f"client-{client_id}-dashboard",
"workspaceName": "analytics-workspace",
"clientId": client_id,
"templateDashboardId": "template-dashboard-001",
"metadata": {
"clientName": "Acme Corporation",
"region": "North America"
},
"isAllowPrivateMetricsByDefault": False,
"name": "ACME Analytics Dashboard",
"embedDescription": "Analytics dashboard for ACME Corp",
"isImportMetrics": True,
"isRenameDashboard": True,
"metricImportMode": "GALLERY",
"importDashboardData": exported_dashboard["data"], # from Export Dashboard or Export Embed Dashboard API
"accessSettings": {
"datamartName": "customer-analytics",
"isAllowEmailReports": False,
"isAllowManageMetrics": True,
"isAllowEndUserDashboardFilter": True,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": True,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"isAllowMetricCreation": True,
"isAllowMetricDeletion": False,
"isAllowMetricLayoutChange": True,
"isAllowMetricUpdate": True,
"isAllowUnderlyingData": False,
"isAllowCreateDashboardView": True,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"name": "sales_data",
"clientColumn": "customer_id"
}
]
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
data = response.json()
print(f"New dashboard ID: {data['id']}, Name: {data.get('name')}")
```
```json Success Response theme={"dark"}
{
"id": "client-acme-dashboard",
"error": null,
"name": "ACME Analytics Dashboard"
}
```
```json Error Response (400 - validation) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"accessSettings\" is required",
"status": 400
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DASHBOARD_ID",
"message": "Dashboard already exists",
"status": 400
}
}
```
```json Error Response (401) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Invalid Data App API key",
"status": 401
}
}
```
## Response
The ID of the created dashboard embed configuration.
Error object if the request failed, otherwise `null`.
The name of the embed configuration. Matches the request body `name` if provided, otherwise the `dashboardId`. Returned by the new endpoint (`/api/v2/data-app/dashboard-embeds`); the legacy endpoint returns only `id` and `error`.
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Dashboard created successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Code | Message | HTTP Status |
| -------------------------- | --------------------------------- | ----------- |
| `INVALID_REQUEST_BODY` | Request body validation failed | 400 |
| `WORKSPACE_ID_ERROR` | Invalid workspace name | 400 |
| `INVALID_DATA_APP_API_KEY` | Invalid Data App API key | 401 |
| `CLIENT_ID_ERROR` | Invalid client id | 400 |
| `INVALID_DASHBOARD_ID` | Dashboard already exists | 400 |
| `TEMPLATE_DASHBOARD_ERROR` | Invalid template dashboard id | 400 |
| `INVALID_DASHBOARD_DATA` | Uploaded JSON missing `data` | 400 |
| `DASHBOARD_CREATE_ERROR` | Failed to create client dashboard | 400 or 500 |
| `INTERNAL_SERVER_ERROR` | Internal server error | 500 |
## Quick Start Guide
For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
Make a POST request with the required parameters:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"dashboardId": "client-acme-analytics",
"clientId": "acme-corp-123",
"workspaceName": "my-workspace",
"accessSettings": {
"datamartName": "my-datamart",
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowCreateDashboardView": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP"
}
}'
```
To clone settings from an existing dashboard, add `templateDashboardId`. To also import metrics from the template, set `isImportMetrics: true` and optionally `metricImportMode` to `"GALLERY"` or `"METRIC"`. To use a custom display name for the dashboard (instead of `{dashboardId}_{clientId}`), set `name` and `isRenameDashboard: true`:
```json theme={"dark"}
{
"dashboardId": "client-acme-analytics",
"clientId": "acme-corp-123",
"templateDashboardId": "template-dashboard-001",
"name": "ACME Analytics Dashboard",
"isRenameDashboard": true,
"isImportMetrics": true,
"metricImportMode": "GALLERY",
"accessSettings": { ... }
}
```
Use the created dashboard ID to generate a guest token for your end users. See the [Guest Token API](/developer-docs/helpers/api-reference/token) for details.
Use the dashboard ID and guest token in your web component:
```javascript theme={"dark"}
```
## Use Cases
Create isolated dashboards for each customer in your SaaS application.
Use `templateDashboardId` to clone filters and settings from a master template.
Set `isRenameDashboard: true` with `name` to give each client dashboard a human-readable display name instead of `{dashboardId}_{clientId}`.
Automatically create dashboards during customer onboarding or upgrades.
Ensure data isolation with `clientId` and row-level security settings.
## Next Steps
Create secure tokens to access your new dashboard
Embed existing dashboards that were built in the databrain platform
Integrate dashboards into your application
Set up row-level security for your dashboards
# Create Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-data-app
POST https://api.usedatabrain.com/api/v2/data-app
Create a new Data App to organize and manage your embedded analytics.
Create a new Data App in your organization. Data Apps serve as containers for organizing embed configurations, API tokens, and access controls for your embedded analytics.
Data Apps are the top-level organizational unit for embedded analytics. Each Data App can contain multiple embed configurations and has its own set of API tokens for authentication.
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage Data Apps across your organization.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The unique name for the Data App. This name must be unique within your organization.
* Names must be unique within your organization
* Use descriptive names that indicate the purpose (e.g., "Customer Portal Analytics", "Partner Dashboard")
* Avoid special characters that might cause URL encoding issues
## Response
The name of the newly created Data App.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Customer Portal Analytics"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app', {
method: 'POST',
headers: {
'Authorization': 'Bearer service_token_xyz...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Customer Portal Analytics'
})
});
const data = await response.json();
console.log('Created Data App:', data.name);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app"
headers = {
"Authorization": "Bearer service_token_xyz...",
"Content-Type": "application/json"
}
payload = {
"name": "Customer Portal Analytics"
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
print(f"Created Data App: {data['name']}")
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateDataApp {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"name": "Customer Portal Analytics"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app"))
.header("Authorization", "Bearer service_token_xyz...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type CreateDataAppRequest struct {
Name string `json:"name"`
}
type CreateDataAppResponse struct {
Name string `json:"name"`
Error interface{} `json:"error"`
}
func main() {
requestBody := CreateDataAppRequest{
Name: "Customer Portal Analytics",
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/data-app", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer service_token_xyz...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result CreateDataAppResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Created Data App: %s\n", result.Name)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Customer Portal Analytics'
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/data-app',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer service_token_xyz...',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo 'Created Data App: ' . $result['name'];
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
request['Content-Type'] = 'application/json'
request.body = {
name: 'Customer Portal Analytics'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created Data App: #{result['name']}"
```
```json 200 - Success theme={"dark"}
{
"name": "Customer Portal Analytics"
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"name\" is required"
}
}
```
```json 400 - Data App Already Exists theme={"dark"}
{
"error": {
"code": "DATA_APP_ALREADY_EXISTS",
"message": "Data app with the same name already exists"
}
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Data App created successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ------------------------- | ----------- | -------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid name parameter |
| `DATA_APP_ALREADY_EXISTS` | 400 | Data App with same name already exists |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
In **Settings** page, navigate to the **Service Tokens** section. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Make a POST request with a unique name for your Data App:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{"name": "My Analytics App"}'
```
After creating the Data App, create an API token to use for embed operations. See the [Create API Token](/developer-docs/helpers/api-reference/create-api-token) endpoint.
Use the API token to create embed configurations for your dashboards and metrics.
## Next Steps
View all Data Apps in your organization
Generate API tokens for your Data App
Create embed configurations for dashboards
Remove Data Apps you no longer need
# Create Datamart
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datamart
POST https://api.usedatabrain.com/api/v2/data-app/datamarts
Create a new datamart to organize and manage your data sources with custom table and column configurations.
Create datamarts to organize your data sources into logical business units. Datamarts provide structured access to your datasource tables and columns with optional schema support.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/datamarts`. The old endpoint `/api/v2/dataApp/datamarts` will be deprecated soon. Please update your integrations to use the new endpoint format.
Datamarts help organize data sources by defining which tables and columns are accessible. Tenancy settings are optional and can be omitted if multi-tenant data isolation is handled at the application level. Ensure your datasource exists before creating a datamart.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app/datamarts
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/data-app/datamarts
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
```bash Authentication theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json' \
--data '{
"name": "demo-sales-default-1",
"datasourceName": "Bigquery",
"tableList": [
{
"schemaName": "databrain_dev2",
"name": "demo_sales",
"label": "Demo Sales",
"clientColumn": "client id",
"isHide": false,
"columns": [
{
"name": "client id",
"alias": "client_id",
"label": "Client ID",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT",
"defaultSort": "ASC"
},
{
"name": "store id",
"alias": "store_id",
"label": "Store ID",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT",
"defaultSort": "ASC"
},
{
"name": "quantity sold",
"alias": "quantity_sold",
"label": "Quantity Sold",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "SUM",
"defaultSort": "DESC"
}
]
}
]
}'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the datamart to create. Must be unique within your organization — the API will reject the request with an error if a datamart with the same name already exists.
* Use descriptive names (e.g., "sales-analytics", "customer-data")
* Alphanumeric characters and hyphens recommended
* Must be unique within your organization (enforced server-side)
* Cannot be changed after creation
The datasource to which this datamart belongs. Must match an existing datasource in your organization.
* Check your datasources list in the DataBrain dashboard
* Use the exact name as it appears in your datasource configuration
* Names are case-sensitive
Array of tables with columns to include in the datamart. Must be non-empty.
Table name from your datasource.
Optional schema name (required only for schema-based datasources like PostgreSQL, SQL Server).
Optional column name in this table that identifies the client/tenant. This column is used for multi-tenant data isolation at the table level. Must exist in the table schema.
* Used for table-level tenancy when `tenancyLevel` is `TABLE`
* The column should contain client/tenant identifiers
Optional flag to hide the table from the datamart interface.
Optional label for the table to provide a human-readable display name. When provided, this label can be used in the UI instead of the technical table name for better readability.
* Provides a user-friendly display name for the table
* Useful when table names are cryptic or technical
* Does not affect the actual table reference in queries
Optional wildcard index pattern for OpenSearch tables. When set, this value is used as the table name in queries, enabling you to query multiple OpenSearch indices that match a pattern.
* Only applicable to **OpenSearch** datasources
* Accepts a valid OpenSearch index wildcard pattern (e.g., `logs-*`, `events-2024-*`)
* When set, the wildcard value is used instead of the exact `name` when constructing the FROM clause
* Allows a single datamart table to cover multiple time-partitioned or sharded OpenSearch indices
List of column objects for this table. Must be non-empty.
Column name from the table.
Optional alias for the column to display a different name.
Optional label for the column for better readability.
Optional flag to hide the column from the datamart interface.
Optional flag to mark this as a custom/calculated column. When `true`, the `sql` field is required to define the column's SQL expression.
* Custom columns allow you to define calculated fields using SQL expressions
* The `name` field should reference an existing column from the datasource schema
* Use the `alias` field to give the calculated column a custom display name
* The SQL expression can reference other columns from the same table
* Useful for derived metrics, concatenations, or transformations
SQL expression that defines the calculated value for a custom column. **Required when** `isCustomColumn` is `true`. The expression can reference other columns from the same table.
* Simple calculation: `quantity * unit_price`
* Date extraction: `EXTRACT(YEAR FROM order_date)`
* String concatenation: `CONCAT(first_name, ' ', last_name)`
* Case statement: `CASE WHEN status = 'active' THEN 1 ELSE 0 END`
Optional flag to indicate if this column should be treated as an aggregate column. When `true`, the column is marked as `AGGREGATE` drop type for metric calculations.
* Aggregate columns are used for pre-aggregated metrics
* Affects how the column behaves in metric calculations and drag-drop operations
* Common for SUM, COUNT, AVG type pre-calculated values
Optional flag to enable default aggregation for the column. When `true`, Databrain uses the value set in `defaultAggregation` when the column is added as a measure.
Optional field to define the default aggregation applied to the column when used as a measure.
```json theme={"dark"}
{
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT"
}
```
Optional flag to enable timezone conversion for this column. When `true`, the column's datetime values are converted using the timezone passed as `params.timezone` in the guest token at query execution time.
This field has no effect unless `params.timezone` is set in the guest token. See [Timezone Handling in Guest Token](/developer-docs/solutions-alchemy/guest-token-timezone) for the full setup guide.
* Apply to datetime or timestamp columns that store values in UTC or a fixed timezone
* The timezone is sourced from `params.timezone` in the guest token — not a user or workspace setting
* Supported datasources: Postgres, CockroachDB, Trino, Athena, BigQuery, MSSQL, OpenSearch, Databricks, Clickhouse, Redshift, Snowflake
* Has no effect on non-datetime column types
Optional default sort direction for the column. Supported values are `ASC` and `DESC`. The value is propagated to data-app embed access settings and used as the initial sort direction when this column is selected during metric creation.
Pass an empty string (`""`) or `null`, or omit this field, to leave the column without a default sort. Values are case-sensitive; lowercase values such as `"asc"` fail validation.
Multi-tenant configuration for the datamart. Defines how data is isolated between different tenants/clients. Optional - if not provided, the datamart will be created without explicit tenancy settings.
* **TABLE level**: Uses a dedicated table to map client identifiers
* **DATABASE level**: Each client has a separate database
* **MULTI\_DATABASE level**: Supports multi-database tenancy with an optional primary database
* Optional - can be omitted if tenancy is handled at the application level
The level at which tenant isolation occurs. Must be one of: `TABLE`, `DATABASE`, or `MULTI_DATABASE`.
* `TABLE`: Client mapping is stored in a specific table (most common)
* `DATABASE`: Each client has a separate database instance
* `MULTI_DATABASE`: Tenancy spans multiple databases with optional default routing via `primaryDatabase`
**Required when** `tenancySettings` is provided. If `tenancySettings` is omitted, this field is not needed.
Data type of the client identifier column. Must be either `NUMBER` or `STRING`.
**Required when** `tenancyLevel` is `TABLE`.
Optional primary database name used for `DATABASE` and `MULTI_DATABASE` tenancy levels. Set to `null` when you do not want a default database.
**Note:** The API accepts this field for all tenancy levels. It is primarily used by `DATABASE` and `MULTI_DATABASE`.
Schema name where the client mapping table is located.
**Required when** `tenancyLevel` is `TABLE`.
Name of the table that contains client mapping information.
**Required when** `tenancyLevel` is `TABLE`.
Column name in the mapping table that stores the client identifier.
**Required when** `tenancyLevel` is `TABLE`.
Primary key column of the client mapping table.
**Required when** `tenancyLevel` is `TABLE`.
Optional array of table relationships to define how tables in the datamart are connected. Relationships enable joins between tables for more complex queries.
* Define how tables relate to each other (e.g., orders.customer\_id → customers.id)
* Supports different join types and cardinalities
* Useful for creating metrics that span multiple tables
* Optional - datamarts can work without relationships for single-table queries
Name of the parent table in the relationship.
Column name in the parent table that participates in the relationship.
Name of the child table in the relationship.
Column name in the child table that participates in the relationship.
A descriptive name for the relationship (e.g., "orders\_to\_customers").
The cardinality of the relationship. Must be one of: `ManyToMany`, `ManyToOne`, `OneToMany`, `OneToOne`.
**Optional:** Can be omitted or set to `null` if not specified.
The type of SQL join to use. Must be one of: `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`.
**Optional:** Can be omitted or set to `null` if not specified.
## Response
The name of the created datamart (same as the input name).
Error object if the request failed, otherwise `null` for successful requests.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "demo-sales-default-1",
"datasourceName": "Bigquery",
"tableList": [
{
"schemaName": "databrain_dev2",
"name": "demo_sales",
"label": "Demo Sales",
"clientColumn": "client id",
"isHide": false,
"columns": [
{
"name": "client id",
"alias": "client_id",
"label": "Client ID",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT",
"defaultSort": "ASC"
},
{
"name": "store id",
"alias": "store_id",
"label": "Store ID",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT",
"defaultSort": "ASC"
},
{
"name": "quantity sold",
"alias": "quantity_sold",
"label": "Quantity Sold",
"isHide": false,
"allowAggregate": true,
"defaultAggregation": "SUM",
"defaultSort": "DESC"
}
]
}
]
}'
```
```bash cURL - Without Tenancy Settings theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "analytics-datamart",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Sales Orders",
"clientColumn": "tenant_id",
"columns": [
{
"name": "order_id",
"alias": "id",
"label": "Order ID"
},
{
"name": "order_date",
"alias": "date",
"label": "Order Date"
}
]
}
]
}'
```
```bash cURL - Multi-Database Tenancy theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "regional-sales-multi-db",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"columns": [
{ "name": "order_id" },
{ "name": "region" }
]
}
],
"tenancySettings": {
"tenancyLevel": "MULTI_DATABASE",
"primaryDatabase": "core_analytics"
}
}'
```
```bash cURL - With Custom Columns theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "sales-with-calculations",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Customer Orders",
"columns": [
{
"name": "order_id",
"alias": "id",
"label": "Order ID"
},
{
"name": "quantity",
"label": "Quantity"
},
{
"name": "unit_price",
"alias": "total_revenue",
"label": "Total Revenue",
"isCustomColumn": true,
"sql": "quantity * unit_price"
},
{
"name": "order_date",
"alias": "order_year",
"label": "Order Year",
"isCustomColumn": true,
"sql": "EXTRACT(YEAR FROM order_date)"
},
{
"name": "created_at",
"label": "Created At",
"isApplyTimezone": true
}
]
}
]
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'sales-analytics',
datasourceName: 'postgres-main',
tableList: [
{
schemaName: 'public',
name: 'orders',
label: 'Customer Orders',
clientColumn: 'tenant_id',
isHide: false,
columns: [
{
name: 'order_id',
alias: 'id',
label: 'Order ID',
isHide: false
},
{
name: 'customer_id',
label: 'Customer',
isHide: false
},
{
name: 'order_date',
alias: 'date',
label: 'Order Date',
isHide: false
}
]
}
],
tenancySettings: {
tenancyLevel: 'TABLE',
clientColumnType: 'STRING',
schemaName: 'public',
tableName: 'client_mapping',
tableClientNameColumn: 'client_id',
tablePrimaryKeyColumn: 'id'
},
relationships: [
{
parentTableName: 'orders',
parentColumnName: 'customer_id',
childTableName: 'customers',
childColumnName: 'id',
relationshipName: 'orders_to_customers',
cardinality: 'ManyToOne',
join: 'LEFT JOIN'
}
]
})
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'name': 'sales-analytics',
'datasourceName': 'postgres-main',
'tableList': [
{
'schemaName': 'public',
'name': 'orders',
'columns': [
{
'name': 'order_id',
'alias': 'id',
'label': 'Order ID'
},
{
'name': 'customer_id',
'label': 'Customer'
},
{
'name': 'order_date',
'alias': 'date',
'label': 'Order Date'
}
]
}
],
'tenancySettings': {
'tenancyLevel': 'TABLE',
'clientColumnType': 'STRING',
'schemaName': 'public',
'tableName': 'client_mapping',
'tableClientNameColumn': 'client_id',
'tablePrimaryKeyColumn': 'id'
},
'relationships': [
{
'parentTableName': 'orders',
'parentColumnName': 'customer_id',
'childTableName': 'customers',
'childColumnName': 'id',
'relationshipName': 'orders_to_customers',
'cardinality': 'ManyToOne',
'join': 'LEFT JOIN'
}
]
}
)
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
name: 'sales-analytics',
datasourceName: 'postgres-main',
tableList: [
{
schemaName: 'public',
name: 'orders',
label: 'Customer Orders',
columns: [
{
name: 'order_id',
alias: 'id',
label: 'Order ID'
},
{
name: 'customer_id',
label: 'Customer'
},
{
name: 'order_date',
alias: 'date',
label: 'Order Date'
}
]
}
],
tenancySettings: {
tenancyLevel: 'TABLE',
clientColumnType: 'STRING',
schemaName: 'public',
tableName: 'client_mapping',
tableClientNameColumn: 'client_id',
tablePrimaryKeyColumn: 'id'
},
relationships: [
{
parentTableName: 'orders',
parentColumnName: 'customer_id',
childTableName: 'customers',
childColumnName: 'id',
relationshipName: 'orders_to_customers',
cardinality: 'ManyToOne',
join: 'LEFT JOIN'
}
]
}.to_json
response = http.request(request)
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainDatamartAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """{
"name": "sales-analytics",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Customer Orders",
"columns": [
{
"name": "order_id",
"alias": "id",
"label": "Order ID"
},
{
"name": "customer_id",
"label": "Customer"
},
{
"name": "order_date",
"alias": "date",
"label": "Order Date"
}
]
}
],
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "client_mapping",
"tableClientNameColumn": "client_id",
"tablePrimaryKeyColumn": "id"
},
"relationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type DatamartRequest struct {
Name string `json:"name"`
DatasourceName string `json:"datasourceName"`
TableList []TableInfo `json:"tableList"`
TenancySettings TenancySettings `json:"tenancySettings"`
}
type TableInfo struct {
SchemaName string `json:"schemaName"`
Name string `json:"name"`
Label string `json:"label,omitempty"`
Columns []ColumnInfo `json:"columns"`
}
type ColumnInfo struct {
Name string `json:"name"`
Alias string `json:"alias,omitempty"`
Label string `json:"label,omitempty"`
}
type TenancySettings struct {
TenancyLevel string `json:"tenancyLevel"`
ClientColumnType string `json:"clientColumnType"`
SchemaName string `json:"schemaName"`
TableName string `json:"tableName"`
TableClientNameColumn string `json:"tableClientNameColumn"`
TablePrimaryKeyColumn string `json:"tablePrimaryKeyColumn"`
}
func main() {
reqData := DatamartRequest{
Name: "sales-analytics",
DatasourceName: "postgres-main",
TableList: []TableInfo{
{
SchemaName: "public",
Name: "orders",
Columns: []ColumnInfo{
{Name: "order_id", Alias: "id", Label: "Order ID"},
{Name: "customer_id", Label: "Customer"},
{Name: "order_date", Alias: "date", Label: "Order Date"},
},
},
},
TenancySettings: TenancySettings{
TenancyLevel: "TABLE",
ClientColumnType: "STRING",
SchemaName: "public",
TableName: "client_mapping",
TableClientNameColumn: "client_id",
TablePrimaryKeyColumn: "id",
},
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/data-app/datamarts", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Datamart created successfully")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics',
'datasourceName' => 'postgres-main',
'tableList' => [
[
'schemaName' => 'public',
'name' => 'orders',
'label' => 'Customer Orders',
'columns' => [
[
'name' => 'order_id',
'alias' => 'id',
'label' => 'Order ID'
],
[
'name' => 'customer_id',
'label' => 'Customer'
],
[
'name' => 'order_date',
'alias' => 'date',
'label' => 'Order Date'
]
]
]
],
'tenancySettings' => [
'tenancyLevel' => 'TABLE',
'clientColumnType' => 'STRING',
'schemaName' => 'public',
'tableName' => 'client_mapping',
'tableClientNameColumn' => 'client_id',
'tablePrimaryKeyColumn' => 'id'
],
'relationships' => [
[
'parentTableName' => 'orders',
'parentColumnName' => 'customer_id',
'childTableName' => 'customers',
'childColumnName' => 'id',
'relationshipName' => 'orders_to_customers',
'cardinality' => 'ManyToOne',
'join' => 'LEFT JOIN'
]
]
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Datamart ID: " . $result['id'];
?>
```
```json 200 - Success theme={"dark"}
{
"id": "sales-analytics",
"error": null
}
```
```json 400 - Bad Request theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Table list cannot be empty"
}
}
```
```json 400 - Duplicate Datamart Name theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Datamart name already exists"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid or missing API key"
}
}
```
## Errors
| HTTP Status | Error Code | Description |
| ----------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` | - | **Success** - Datamart created successfully |
| `200` | - | **Success** - Datamart created successfully |
| `400` | `INVALID_REQUEST_BODY` | Invalid request parameters. Common causes: missing required fields, empty table list, invalid table/column structure, invalid schema/table names, invalid column names, validation errors from Joi schema, or **duplicate datamart name** (`"Datamart name already exists"`). |
| `400` | `AUTH_ERROR` | Invalid or expired service token |
| `400` | `DATASOURCE_NAME_ERROR` | The specified datasource doesn't exist or you don't have access to it |
| `500` | `INTERNAL_SERVER_ERROR` | Server error occurred. Contact support if error persists |
## Quick Start Guide
Ensure your datasource exists and is properly configured. You'll need the exact datasource name as it appears in your DataBrain workspace.
Identify the tables and columns you want to include in your datamart:
```json theme={"dark"}
{
"name": "sales-analytics",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Customer Orders",
"clientColumn": "tenant_id",
"isHide": false,
"columns": [
{"name": "order_id", "alias": "id", "label": "Order ID", "isHide": false},
{"name": "customer_id", "label": "Customer", "isHide": false},
{"name": "order_date", "alias": "date", "label": "Order Date", "isHide": false}
]
}
],
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "client_mapping",
"tableClientNameColumn": "client_id",
"tablePrimaryKeyColumn": "id"
},
"relationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}
```
Make the API call to create your datamart:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "sales-analytics",
"datasourceName": "postgres-main",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"clientColumn": "tenant_id",
"isHide": false,
"columns": [
{"name": "order_id", "alias": "id", "label": "Order ID", "isHide": false},
{"name": "customer_id", "label": "Customer", "isHide": false}
]
}
],
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "client_mapping",
"tableClientNameColumn": "client_id",
"tablePrimaryKeyColumn": "id"
},
"relationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}'
```
Reference your new datamart in embed configurations:
```javascript theme={"dark"}
const embedConfig = await createEmbedConfiguration({
dashboardId: 'your-dashboard-id',
embedType: 'dashboard',
workspaceName: 'your-workspace',
accessSettings: {
datamartName: 'sales-analytics', // Your new datamart
// ... other settings
}
});
```
## Next Steps
View all datamarts in your organization
Remove datamarts you no longer need
Use your datamart in embed configurations
Learn how to get started with DataBrain embedding
# Create Datasource
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-datasource
POST https://api.usedatabrain.com/api/v2/datasource
Create a new datasource connection to your data infrastructure. Supports multiple database types and cloud services.
Create a new datasource connection to integrate your database or data warehouse with DataBrain. The API validates credentials, tests the connection, and automatically caches the schema for immediate use.
Before creating a datasource, ensure you have valid credentials for your database or data warehouse. The API will test the connection before creating the datasource. Supported datasource types include Snowflake, PostgreSQL, MySQL, BigQuery, Databricks, and many more.
## Endpoint
```
POST https://api.usedatabrain.com/api/v2/datasource
```
## Self-hosted Databrain Endpoint
```
POST /api/v2/datasource
```
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
```bash Authentication theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The type of datasource to create. Must be one of the supported datasource types.
**Supported types:**
* `snowflake` - Snowflake data warehouse
* `postgres` - PostgreSQL database
* `redshift` - Amazon Redshift
* `cockroachdb` - CockroachDB
* `mysql` - MySQL database
* `mongodb` - MongoDB database
* `clickhouse` - ClickHouse database
* `singlestore` - SingleStore database
* `bigquery` - Google BigQuery
* `databricks` - Databricks
* `elasticsearch` - Elasticsearch
* `opensearch` - OpenSearch
* `mssql` - Microsoft SQL Server
* `awss3` - Amazon S3
* `csv` - CSV files
* `firebolt` - Firebolt
* `athena` - Amazon Athena
* `trino` - Trino
The datasource type determines which credential fields are required. Each datasource type has specific connection requirements documented in the credentials section.
Connection credentials for the datasource. The structure varies by datasource type, but all types require a `name` field.
All datasource types require:
* `name` (string, required) - Unique name for the datasource within your organization
Unique name for the datasource. This name will be used to reference the datasource in other APIs and configurations.
* Use descriptive names (e.g., "production-postgres", "analytics-snowflake")
* Must be unique within your organization
* Alphanumeric characters, hyphens, and underscores recommended
* Case-sensitive
Multi-tenant configuration for the datasource. Defines how data is isolated between different tenants/clients. Optional - if not provided, the datasource will be created without explicit tenancy settings.
* **TABLE level**: Uses a dedicated table to map client identifiers
* **DATABASE level**: Each client has a separate database
* Optional - can be omitted if tenancy is handled at the application level
The level at which tenant isolation occurs. Must be one of: `TABLE` or `DATABASE`.
* `TABLE`: Client mapping is stored in a specific table (most common)
* `DATABASE`: Each client has a separate database instance
**Required when** `tenancySettings` is provided. If `tenancySettings` is omitted, this field is not needed.
Data type of the client identifier column. Must be either `NUMBER` or `STRING`.
**Required when** `tenancyLevel` is `TABLE`.
Schema name where the client mapping table is located.
**Required when** `tenancyLevel` is `TABLE`.
Name of the table that contains client mapping information.
**Required when** `tenancyLevel` is `TABLE`.
Column name in the mapping table that stores the client identifier.
**Required when** `tenancyLevel` is `TABLE`.
Primary key column of the client mapping table.
**Required when** `tenancyLevel` is `TABLE`.
### Datasource-Specific Credentials
The credentials object structure depends on the `datasourceType`. Below are examples for common datasource types:
Datasource-specific credential fields. The required fields depend on the `datasourceType`.
Snowflake account hostname (e.g., `your-account.snowflakecomputing.com`)
Snowflake username
Snowflake role to use
Snowflake warehouse name
Snowflake database name
Snowflake schema name
Authentication method: `"username/password"` or `"Key-pair authentication"`
Password (required if credentials is `"username/password"`)
Private key (required if credentials is `"Key-pair authentication"`)
Passphrase for the private key (optional)
Database hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Schema name
Enable SSL mode (optional)
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH server hostname (required if sshTunnel is `"enable"`)
SSH server port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
CockroachDB hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Schema name
Enable SSL mode (optional)
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH server hostname (required if sshTunnel is `"enable"`)
SSH server port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
JSON string containing Google Cloud service account credentials
Google Cloud project ID
BigQuery dataset location (e.g., `"US"`, `"EU"`)
BigQuery dataset ID (optional)
Database hostname or IP address
Database port number (1-65535)
Database username. Note: Uses `user` not `username` for these datasource types.
Database password
SQL Server hostname or IP address. Note: Uses `server` not `host` for MSSQL.
Database port number (1-65535)
Database username. Note: Uses `user` not `username` for MSSQL.
Database password
Database name (optional)
Disable database selection (optional)
Optional MSSQL read-only routing hint. When `true`, Databrain connects with read-only intent for MSSQL workloads.
Database hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Databricks server hostname
Databricks HTTP path
Databricks access token
Server type: `"elastic-cloud"`, `"open-cloud"`, or `"self-managed"`
Cloud ID (required if server\_type is `"elastic-cloud"` or `"open-cloud"`)
Server URL (required if server\_type is `"self-managed"`)
Username (required unless `disableAuth` is `true`)
Password (required unless `disableAuth` is `true`)
Disable authentication (optional, default `false`). Only valid when server\_type is `"self-managed"`.
Ignore certificate verification (optional)
Ignore SSL (optional)
Server type: `"elastic-cloud"`, `"open-cloud"`, or `"self-managed"`
Cloud ID (required if server\_type is `"elastic-cloud"` or `"open-cloud"`)
Server URL (required if server\_type is `"self-managed"`)
Username (required unless `disableAuth` is `true`)
Password (required unless `disableAuth` is `true`)
Disable authentication (optional, default `false`). Only valid when server\_type is `"self-managed"`.
Ignore certificate verification (optional)
Ignore SSL (optional)
Firebolt client ID
Firebolt client secret
Firebolt account name
Database name
Engine name
Schema name (optional)
Athena database name
S3 output bucket for query results
AWS access key ID
AWS region
AWS secret access key
Datasource ID (optional)
Trino hostname or IP address
Database port number (1-65535)
Trino catalog name
Schema name
Username
Password
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH host (required if sshTunnel is `"enable"`)
SSH port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
Name for the CSV datasource
S3 bucket name
Path within the bucket (optional, can be empty string)
AWS region (e.g., `"us-east-1"`)
Table level: `"File"` or `"Folder"` (optional)
AWS access key ID
AWS secret access key
## Response
The name of the created datasource (same as credentials.name).
Error field, null when successful. Not included in successful responses.
## Examples
```bash cURL - PostgreSQL Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "postgres",
"credentials": {
"name": "production-postgres",
"host": "db.example.com",
"port": 5432,
"username": "dbuser",
"password": "securepassword",
"database": "analytics",
"schema": "public"
}
}'
```
```bash cURL - Snowflake Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "snowflake",
"credentials": {
"name": "analytics-snowflake",
"host": "account.snowflakecomputing.com",
"username": "user@example.com",
"role": "ANALYST",
"warehouse": "COMPUTE_WH",
"database": "ANALYTICS",
"schema": "PUBLIC",
"credentials": "username/password",
"password": "securepassword"
}
}'
```
```bash cURL - MSSQL Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "mssql",
"credentials": {
"name": "production-mssql",
"server": "sqlserver.example.com",
"port": 1433,
"user": "sqluser",
"password": "securepassword",
"database": "analytics",
"readOnlyIntent": true
}
}'
```
```bash cURL - CockroachDB Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "cockroachdb",
"credentials": {
"name": "production-cockroachdb",
"host": "cockroach.example.com",
"port": 26257,
"username": "dbuser",
"password": "securepassword",
"database": "analytics",
"schema": "public"
}
}'
```
```bash cURL - OpenSearch Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "opensearch",
"credentials": {
"name": "production-opensearch",
"server_type": "self-managed",
"server_url": "https://opensearch.example.com:9200",
"username": "admin",
"password": "securepassword"
}
}'
```
```bash cURL - Elasticsearch Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "elasticsearch",
"credentials": {
"name": "production-elasticsearch",
"server_type": "elastic-cloud",
"cloud_id": "my-deployment:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyQ...",
"username": "elastic",
"password": "securepassword"
}
}'
```
```bash cURL - Trino Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "trino",
"credentials": {
"name": "production-trino",
"host": "trino.example.com",
"port": 8080,
"catalog": "hive",
"schema": "analytics",
"username": "trinouser",
"password": "securepassword"
}
}'
```
```bash cURL - With Tenancy Settings theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "postgres",
"credentials": {
"name": "multi-tenant-postgres",
"host": "db.example.com",
"port": 5432,
"username": "dbuser",
"password": "securepassword",
"database": "analytics",
"schema": "public"
},
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "clients",
"tableClientNameColumn": "client_name",
"tablePrimaryKeyColumn": "client_id"
}
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/datasource', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datasourceType: 'postgres',
credentials: {
name: 'production-postgres',
host: 'db.example.com',
port: 5432,
username: 'dbuser',
password: 'securepassword',
database: 'analytics',
schema: 'public'
}
})
});
const data = await response.json();
if (data.error) {
console.error('Error:', data.error);
} else {
console.log('Datasource created:', data.name);
}
```
```python Python theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/datasource',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datasourceType': 'postgres',
'credentials': {
'name': 'production-postgres',
'host': 'db.example.com',
'port': 5432,
'username': 'dbuser',
'password': 'securepassword',
'database': 'analytics',
'schema': 'public'
}
}
)
data = response.json()
if data.get('error'):
print('Error:', data['error'])
else:
print('Datasource created:', data['name'])
```
```json 200 - Success theme={"dark"}
{
"name": "production-postgres"
}
```
```json 400 - Bad Request theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid credentials for postgres: \"host\" is required",
"status": 400
}
}
```
```json 400 - Duplicate Name theme={"dark"}
{
"error": {
"code": "DATASOURCE_NAME_ERROR",
"message": "Datasource name already exists, please use unique name",
"status": 400
}
}
```
```json 400 - Connection Test Failed theme={"dark"}
{
"error": {
"code": "CREDENTIAL_TEST_FAILED",
"message": "Failed to connect to datasource",
"status": 400
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "AUTHENTICATION_ERROR",
"status": 401
}
}
```
## Error Codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing required fields or invalid credential structure |
| `DATASOURCE_NAME_ERROR` | 400 | Datasource name already exists |
| `CREDENTIAL_TEST_FAILED` | 400 | Connection test failed |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing service token |
| `SCHEMA_CACHE_FAILED` | 500 | Schema caching failed |
| `CREATE_DATASOURCE_FAILED` | 500 | Internal error during datasource creation |
| `INTERNAL_SERVER_ERROR` | 500 | Server error occurred |
## Next Steps
View all datasources in your organization
Update datasource credentials or configuration
Sync datasource schema after creation
Create a datamart using your new datasource
# Embed a Pre-built Dashboard/Metric
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-embed
POST https://api.usedatabrain.com/api/v2/data-app/embeds
Create an embed for an existing dashboard or metric that was built by your data analyst.
Embed **existing dashboards or metrics** from your workspace. Use this endpoint when a dashboard has already been created in the DataBrain platform and you want to make it available for embedding in your application.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/embeds`. The old endpoint `/api/v2/dataApp/embeds` will be deprecated soon. Please update your integrations to use the new endpoint format.
This endpoint embeds **existing dashboards/metrics** from your workspace. To create a **new empty dashboard** for multi-tenant scenarios, use the [Create an Empty Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed) endpoint instead.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app/embeds
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/embeds
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Existing dashboard ID to embed. This dashboard must already exist in your workspace.
Type of embed configuration: `dashboard` or `metric`.
Metric ID to embed. Required if embedType is `metric`.
The name of the workspace where the embed configuration will be created.
Optional human-readable name for the embed configuration. If not provided, the embed ID will be used as the name.
Access control settings for the embedded view. Required when `embedType` is `dashboard`. Optional when `embedType` is `metric`.
The datamart name used in the embedded environment. Required when `embedType` is `dashboard`.
Allow AI Pilot features (optional).
Allow sending email reports.
Allow managing metrics.
Allow creating dashboard views.
Optional. Enables end-user dashboard filter interactions in embedded mode.
Optional allowlist for dashboard filterable columns. Each item must include `tableName` and `columns`.
Fully qualified table name used in dashboard filters.
Column names allowed for dashboard filter evaluation for the specified table.
Optional. Enables end-user metric filter interactions in embedded mode.
Optional allowlist for columns that end users can use in metric filters. Each item must include `tableName` and `columns`.
Fully qualified table name used in metric filters.
Column names allowed for metric filter evaluation for the specified table.
Allow metric creation.
Allow metric deletion.
Allow metric layout changes.
Allow updating metrics.
Allow viewing underlying data.
Recommended join strategy for table relationships.
* `single`: single worksheet mode (tables are pre-joined into one worksheet)
* `multi`: multi-sheet mode (joins are resolved dynamically based on fields used in each chart)
Legacy join strategy flag. Prefer using `accessSettings.joinModel` instead.
Mode of metric creation (drag and drop or chat).
Multi-tenant table access configuration (optional).
Table name for tenancy configuration. Required when `tableTenancySettings` is provided.
Column name for client-level filtering. Required when `tableTenancySettings` is provided.
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"dashboardId": "dash_12345",
"embedType": "dashboard",
"workspaceName": "analytics-workspace",
"name": "Sales Dashboard Embed",
"accessSettings": {
"datamartName": "sales-data",
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowCreateDashboardView": true,
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"name": "sales_data",
"clientColumn": "customer_id"
}
]
}
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dashboardId: 'dash_12345',
embedType: 'dashboard',
workspaceName: 'analytics-workspace',
name: 'Sales Dashboard Embed',
accessSettings: {
datamartName: 'sales-data',
isAllowEmailReports: false,
isAllowManageMetrics: true,
isAllowCreateDashboardView: true,
isAllowEndUserDashboardFilter: true,
dashboardFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['customer_id', 'region', 'order_date']
}
],
isAllowEndUserMetricFilter: true,
metricFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['region', 'order_date']
}
],
isAllowMetricCreation: true,
isAllowMetricDeletion: false,
isAllowMetricLayoutChange: true,
isAllowMetricUpdate: true,
isAllowUnderlyingData: false,
joinModel: 'multi',
metricCreationMode: 'DRAG_DROP',
tableTenancySettings: [
{
name: 'sales_data',
clientColumn: 'customer_id'
}
]
}
})
});
const data = await response.json();
console.log('Embed configuration ID:', data.id);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
import json
url = "https://api.usedatabrain.com/api/v2/data-app/embeds"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
payload = {
"dashboardId": "dash_12345",
"embedType": "dashboard",
"workspaceName": "analytics-workspace",
"name": "Sales Dashboard Embed",
"accessSettings": {
"datamartName": "sales-data",
"isAllowEmailReports": False,
"isAllowManageMetrics": True,
"isAllowCreateDashboardView": True,
"isAllowEndUserDashboardFilter": True,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": True,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"isAllowMetricCreation": True,
"isAllowMetricDeletion": False,
"isAllowMetricLayoutChange": True,
"isAllowMetricUpdate": True,
"isAllowUnderlyingData": False,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"name": "sales_data",
"clientColumn": "customer_id"
}
]
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
data = response.json()
print(f"Embed configuration ID: {data['id']}")
```
```json Success Response theme={"dark"}
{
"id": "embed_abc123def456",
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_WORKSPACE_NAME",
"message": "Invalid workspace name",
"status": 400
}
}
```
```json Error Response (404) theme={"dark"}
{
"error": {
"code": "INVALID_DASHBOARD_ID",
"message": "Dashboard not found",
"status": 404
}
}
```
## Response
Unique identifier for the created embed configuration.
Error object if the request failed, otherwise `null`.
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Embed configuration created successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `404` | **Not Found** - Dashboard or metric not found |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------- |
| `INVALID_WORKSPACE_NAME` | 404 | Workspace not found |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INVALID_DASHBOARD_ID` | 404 | Dashboard not found |
| `INVALID_METRIC_ID` | 404 | Metric not found |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
First, create and configure your dashboard in the DataBrain workspace with all the metrics and visualizations you want to embed.
Make a POST request to embed your existing dashboard:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"dashboardId": "existing-dashboard-id",
"embedType": "dashboard",
"workspaceName": "my-workspace",
"accessSettings": {
"datamartName": "my-datamart",
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowCreateDashboardView": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"joinModel": "multi",
"metricCreationMode": "DRAG_DROP"
}
}'
```
To embed just one metric instead of the entire dashboard, use `embedType: "metric"`:
```json theme={"dark"}
{
"dashboardId": "existing-dashboard-id",
"embedType": "metric",
"metricId": "metric-123",
"workspaceName": "my-workspace",
// ... accessSettings
}
```
Use the embed ID to generate a guest token for your end users. See the [Guest Token API](/developer-docs/helpers/api-reference/token) for details.
Use the embed ID and guest token in your web component:
```javascript theme={"dark"}
```
## Next Steps
Create secure tokens for your embed configurations
Create new empty dashboards for multi-tenant scenarios
Modify existing embed configurations
Learn how to integrate embeds in your application
# Create Semantic Layer
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-semantic-layer
POST https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer
Create a semantic layer for a datamart by adding table descriptions, column metadata, and feedback.
Add semantic metadata to a datamart that doesn't have a semantic layer yet. This includes table and column descriptions, synonyms, column type classifications, and global feedback for AI context.
This endpoint will reject the request with `409 SEMANTIC_LAYER_ALREADY_EXISTS` if the datamart already has semantic data. Use [PUT](/developer-docs/helpers/api-reference/update-semantic-layer) to modify an existing semantic layer.
At least one of `tables` or `feedback` must be provided in the request body.
## Authentication
This endpoint requires a **service token** in the Authorization header. Data app API tokens are not permitted and will be rejected with a `403` error.
To access your service token:
1. Go to your Databrain dashboard and open **Settings**.
2. Navigate to **Settings**.
3. Find the **Service Tokens** section.
4. Click the **"Generate Token"** button to generate a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the existing datamart to create a semantic layer for. Must match exactly (case-sensitive).
* Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to get all datamart names
* Names are case-sensitive and must match exactly
* The datamart must not already have semantic data
Array of table objects with semantic metadata. Each table must reference a table that exists in the datamart.
* Table `name` must match an existing table in the datamart
* Column `name` (when provided) must match an existing column in the respective table
* Descriptions are limited to 500 characters
* Synonyms are limited to 10 per entity, 100 characters each
* Synonyms must be unique (case-insensitive)
Table name from the datamart. Must match an existing table.
Optional schema name for the table.
Human-readable description of the table. Maximum 500 characters.
Alternative names for the table. Maximum 10 synonyms, each up to 100 characters. Must be unique (case-insensitive).
Additional context for AI query generation. Maximum 1000 characters.
Array of column objects with semantic metadata.
Column name from the table. Must match an existing column.
Human-readable description of the column. Maximum 500 characters.
Alternative names for the column. Maximum 10 synonyms, each up to 100 characters. Must be unique (case-insensitive).
Additional context for AI query generation. Maximum 1000 characters.
Semantic column type classification. Must be one of: `String`, `Long String`, `String (Custom)`, `ENUM`, `Mapper`, `Range`, `Expression`, `Identifier`, `Number`, `JSON`.
The column type must be compatible with the column's underlying SQL datatype. For example, `Number` cannot be assigned to a `varchar` column.
Additional configuration for the column type. Must match the shape expected for `columnType`:
* **`String`**, **`String (Custom)`**, **`ENUM`**, **`Mapper`**: plain object mapping values to descriptions (e.g. `{ "pending": "Not shipped", "shipped": "Sent" }`)
* **`Range`**: `{ "lowerLimit": number, "upperLimit": number }` (both must be numbers)
* **`Expression`**: string template
* **`JSON`**: string (sample JSON)
* **`Identifier`**, **`Number`**, **`Long String`**: omit or use `null` (non-null config is rejected)
Invalid configs return `400 INVALID_COLUMN_TYPE_CONFIG` with a message describing the required shape.
Mark this column as an identifier (e.g., primary key, foreign key). Defaults to `false`.
Exclude this column from AI indexing. Defaults to `false`.
Global feedback text providing context to the AI about this datamart. Maximum 2000 characters.
* Helps guide AI-generated SQL queries
* Example: "All monetary amounts are in USD. The fiscal year starts in April."
* Can be used alone (without tables)
## Response
On success, the response body contains only the datamart name. There is no `error` field in the JSON body when the request succeeds.
The name of the datamart (same as the input `datamartName`) on success.
## Examples
```bash cURL - Full Example theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "status",
"description": "Current order status",
"synonyms": ["order status", "state"],
"columnType": "ENUM"
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. All amounts are in USD."
}'
```
```bash cURL - Feedback Only theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "This datamart covers e-commerce sales data. Fiscal year starts April 1."
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
synonyms: ['purchases', 'transactions'],
columns: [
{
name: 'order_id',
description: 'Unique order identifier',
columnType: 'Identifier',
isIdentifier: true
},
{
name: 'amount',
description: 'Total order amount in USD',
columnType: 'Number'
}
]
}
],
feedback: 'All amounts are in USD.'
})
});
const result = await response.json();
if (result.error) {
console.error('Create failed:', result.error.message);
} else {
console.log('Semantic layer created for:', result.id);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Customer purchase orders',
'synonyms': ['purchases', 'transactions'],
'columns': [
{
'name': 'order_id',
'description': 'Unique order identifier',
'columnType': 'Identifier',
'isIdentifier': True
},
{
'name': 'amount',
'description': 'Total order amount in USD',
'columnType': 'Number'
}
]
}
],
'feedback': 'All amounts are in USD.'
}
)
result = response.json()
if result.get('error'):
print(f"Create failed: {result['error']['message']}")
else:
print(f"Semantic layer created for: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Customer purchase orders',
columns: [
{ name: 'order_id', description: 'Unique order identifier', columnType: 'Identifier' },
{ name: 'amount', description: 'Total order amount', columnType: 'Number' }
]
}
],
feedback: 'All amounts are in USD.'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Created: #{result['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"columns": [
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number"
}
]
}
],
"feedback": "All amounts are in USD."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Customer purchase orders",
"columns": []map[string]interface{}{
{
"name": "order_id",
"description": "Unique order identifier",
"columnType": "Identifier",
"isIdentifier": true,
},
{
"name": "amount",
"description": "Total order amount in USD",
"columnType": "Number",
},
},
},
},
"feedback": "All amounts are in USD.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer created")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Customer purchase orders',
'columns' => [
[
'name' => 'order_id',
'description' => 'Unique order identifier',
'columnType' => 'Identifier',
'isIdentifier' => true
],
[
'name' => 'amount',
'description' => 'Total order amount in USD',
'columnType' => 'Number'
]
]
]
],
'feedback' => 'All amounts are in USD.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Created: " . $result['id'];
?>
```
```json 200 - Success theme={"dark"}
{
"id": "sales-analytics"
}
```
```json 400 - Missing datamartName theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
```
```json 400 - No Section Provided theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
```
```json 400 - Invalid Table theme={"dark"}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
```
```json 400 - Invalid Column theme={"dark"}
{
"error": {
"code": "INVALID_COLUMN",
"message": "Column 'nonexistent_col' not found in table 'orders'"
}
}
```
```json 400 - Incompatible Column Type theme={"dark"}
{
"error": {
"code": "INVALID_COLUMN_TYPE",
"message": "Column type 'Number' is not compatible with datatype 'varchar' for column 'status' in table 'orders'"
}
}
```
```json 400 - Duplicate Synonyms theme={"dark"}
{
"error": {
"code": "DUPLICATE_SYNONYM",
"message": "Duplicate synonyms for table 'orders': purchases"
}
}
```
```json 409 - Already Exists theme={"dark"}
{
"error": {
"code": "SEMANTIC_LAYER_ALREADY_EXISTS",
"message": "Semantic layer already exists for datamart 'sales-analytics'. Use PUT to update."
}
}
```
```json 403 - Data App Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------- |
| `200` | **OK** — Semantic layer created successfully |
| `400` | **Bad Request** — Validation failed (see error codes below) |
| `401` | **Unauthorized** — Invalid or missing API token |
| `403` | **Forbidden** — Data app token used instead of service token |
| `409` | **Conflict** — Semantic layer already exists on this datamart |
| `500` | **Internal Server Error** — Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ------------------------------- | ----------- | ------------------------------------------------------ |
| `INVALID_REQUEST_BODY` | 400 | Missing required fields or validation failure |
| `INVALID_DATAMART` | 400 | Datamart not found |
| `INVALID_TABLE` | 400 | Table name doesn't exist in the datamart |
| `INVALID_COLUMN` | 400 | Column name doesn't exist in the table |
| `INVALID_COLUMN_TYPE` | 400 | Column type incompatible with the column's datatype |
| `INVALID_COLUMN_TYPE_CONFIG` | 400 | Column type config has wrong shape for the column type |
| `DUPLICATE_SYNONYM` | 400 | Duplicate synonyms detected (case-insensitive) |
| `SEMANTIC_LAYER_ALREADY_EXISTS` | 409 | Datamart already has semantic data — use PUT to update |
| `AUTHENTICATION_ERROR` | 403 | Data app token used instead of service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to confirm the datamart exists and note its exact name.
Gather descriptions, synonyms, and column type classifications for your tables:
```json theme={"dark"}
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Customer purchase orders",
"synonyms": ["purchases"],
"columns": [
{ "name": "order_id", "description": "Unique identifier", "columnType": "Identifier" },
{ "name": "amount", "description": "Total in USD", "columnType": "Number" }
]
}
],
"feedback": "All monetary values are in USD."
}
```
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{ ... }'
```
Retrieve the semantic layer to confirm it was created and check the completion score:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
## Next Steps
Retrieve and inspect your semantic layer
Modify your semantic layer after creation
Remove semantic layer metadata
Configure the semantic layer in the Databrain UI
# Create Service Token (Self-Hosted)
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-service-token
POST https://api.usedatabrain.com/api/v2/service-token
Create or save a service token for your self-hosted Databrain instance. Available only on self-hosted deployments.
Create or register a service token for your self-hosted instance. If no service token exists, a new one is created; if one already exists, it is updated with the provided token value. Service tokens are used for organization-level operations such as managing Data Apps and API tokens.
**Self-Hosted Only:** This endpoint is available only on **self-hosted** Databrain instances. It returns an error on cloud (SaaS) deployments.
**Authentication Requirement:** This endpoint requires an authenticated admin user (Bearer token from [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt)) and a subscribed account.
## Authentication
Use a valid admin session token in the `Authorization` header. Obtain one by calling [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) first.
## Headers
Bearer token for an authenticated admin user.
```
Authorization: Bearer
```
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
The service token value. Must be a valid **UUID** (e.g. RFC 4122). The backend stores this as the service token ID for your company. Generate a UUID (e.g. via `uuidv4`) and send it here.
## Response
On success, the API returns **200** with a JSON object:
The service token (UUID). Use this value as the Bearer token for service-level API calls (e.g. creating Data App API tokens, export/import dashboard).
On error, the API returns a JSON object with `error.code` and `error.message` and an appropriate HTTP status (400 or 500).
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/service-token \
--header 'Authorization: Bearer YOUR_ADMIN_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"token":"550e8400-e29b-41d4-a716-446655440000"}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/service-token', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ADMIN_ACCESS_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: '550e8400-e29b-41d4-a716-446655440000'
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
console.log('Service token:', data.key);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/service-token"
headers = {
"Authorization": "Bearer YOUR_ADMIN_ACCESS_TOKEN",
"Content-Type": "application/json"
}
payload = {"token": "550e8400-e29b-41d4-a716-446655440000"}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if data.get("error"):
raise Exception(data["error"].get("message", "Request failed"))
print("Service token:", data["key"])
```
```json Success (200) theme={"dark"}
{
"key": "550e8400-e29b-41d4-a716-446655440000"
}
```
```json Error (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"token\" is required"
}
}
```
```json Error (400) - Invalid UUID theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"token\" must be a valid GUID"
}
}
```
```json Error (500) theme={"dark"}
{
"error": {
"code": "SELFHOSTED_APP_ERROR",
"message": "This feature is only available for self-hosted instances"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------- |
| `200` | **OK** – Service token created or updated; response contains `key` |
| `400` | **Bad Request** – Invalid or missing `token` (must be a valid UUID) |
| `500` | **Internal Server Error** – Server error or self-hosted-only error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | ----------------------------------------------------------------------------------- | ----------- |
| `INVALID_REQUEST_BODY` | Joi validation message (e.g. `"token" is required`, `"token" must be a valid GUID`) | 400 |
| `SELFHOSTED_APP_ERROR` | This feature is only available for self-hosted instances | 500 |
| `ACCOUNT_NOT_FOUND` | ACCOUNT\_NOT\_FOUND | 500 |
| `INTERNAL_SERVER_ERROR` | INTERNAL\_SERVER\_ERROR | 500 |
## Related
* [Rotate Service Token](/developer-docs/helpers/api-reference/rotate-service-token) – Rotate the service token with an expiration window
* [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account) – Create the first admin account (self-hosted)
* [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) – Get an access token for admin APIs
# Create Workspace
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/create-workspace
POST https://api.usedatabrain.com/api/v2/workspace
Create a new workspace with datasource, datamart, multi-datasource, or multi-datamart configuration to organize your analytics environment.
Create workspaces to organize your analytics environment by connecting datasources or datamarts. Workspaces serve as containers for dashboards and metrics, providing structured access to your data.
Choose a `connectionType` that matches how this workspace will use data. For `DATASOURCE` or `DATAMART`, the corresponding `datasourceName` or `datamartName` must already exist in your organization. For `MULTI_DATASOURCE` or `MULTI_DATAMART`, those name fields are not required in the request body (see `connectionType` below).
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the workspace to create. Must be unique within your organization.
* Use descriptive names (e.g., "sales-analytics", "customer-insights")
* Alphanumeric characters and spaces are supported
* Must be unique within your organization
* Cannot be changed after creation (use update API to modify connection)
Type of connection for the workspace. Must be one of: `DATASOURCE`, `DATAMART`, `MULTI_DATASOURCE`, or `MULTI_DATAMART`.
* **DATASOURCE**: Connect directly to a single datasource
* **DATAMART**: Connect to a pre-configured datamart
* **MULTI\_DATASOURCE**: Allow connections to multiple datasources within this workspace (`datasourceName` is not required for this type)
* **MULTI\_DATAMART**: Allow multiple datamarts in this workspace (`datamartName` is not required for this type; it is required only when `connectionType` is `DATAMART`)
Name of the datasource to connect to this workspace.
**Required when** `connectionType` is `DATASOURCE`.
* Check your datasources list in the DataBrain dashboard
* Use the exact name as stored in datasource credentials
* Names are case-sensitive
Name of the datamart to connect to this workspace.
**Required when** `connectionType` is `DATAMART`.
* List available datamarts using the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts)
* Use the exact name as it appears in your datamart configuration
* Names are case-sensitive
Optional primary LLM name for workspace-level AI features. Must match an existing LLM configured in your organization.
Optional list of LLM names available for AI Copilot in this workspace. Every value must match an existing organization LLM name.
Optional flag to enable AI-powered metric suggestions in this workspace. Defaults to `false` when omitted.
Optional flag to enable AI-generated metric summaries in this workspace. Defaults to `false` when omitted.
Summary mode used when metric summaries are enabled. Must be one of:
`technicalAndInsightSummary`, `forecastAndTrendAnalysis`, `comparativeAndAnomalyDetection`, `custom`.
**Required when** `isEnableMetricSummary` is `true`.
Custom summary instruction prompt for AI-generated summaries.
**Required when** `summaryType` is `custom`.
Optional workspace theme name. Must match an existing theme configured in your organization.
## Response
Contains the created workspace information on success.
The name of the successfully created workspace.
Error object if the request failed, otherwise `null` for successful requests.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Datasource Connection theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "DATASOURCE",
"datasourceName": "postgres-main"
}'
```
```bash cURL - Datamart Connection theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Customer Insights",
"connectionType": "DATAMART",
"datamartName": "customer-data-mart"
}'
```
```bash cURL - Multi-Datasource theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Cross-Platform Analytics",
"connectionType": "MULTI_DATASOURCE"
}'
```
```bash cURL - Multi-Datamart theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Multi-Datamart Analytics",
"connectionType": "MULTI_DATAMART"
}'
```
```bash cURL - Datamart with AI + Theme Settings theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Executive AI Workspace",
"connectionType": "DATAMART",
"datamartName": "finance-datamart",
"llmName": "gpt-4o",
"aiCopilotLlms": ["gpt-4o", "gpt-4.1-mini"],
"isEnableMetricSuggestions": true,
"isEnableMetricSummary": true,
"summaryType": "custom",
"customSummaryPrompt": "Summarize KPIs with variance drivers and weekly action items.",
"themeName": "Executive Theme"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Sales Analytics',
connectionType: 'DATASOURCE',
datasourceName: 'postgres-main'
})
});
const result = await response.json();
console.log(result);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/workspace',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'name': 'Sales Analytics',
'connectionType': 'DATASOURCE',
'datasourceName': 'postgres-main'
}
)
result = response.json()
print(result)
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/workspace')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
name: 'Sales Analytics',
connectionType: 'DATASOURCE',
datasourceName: 'postgres-main'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts result
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class CreateWorkspace {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"name": "Sales Analytics",
"connectionType": "DATASOURCE",
"datasourceName": "postgres-main"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/workspace"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type WorkspaceRequest struct {
Name string `json:"name"`
ConnectionType string `json:"connectionType"`
DatasourceName string `json:"datasourceName,omitempty"`
DatamartName string `json:"datamartName,omitempty"`
}
func main() {
reqData := WorkspaceRequest{
Name: "Sales Analytics",
ConnectionType: "DATASOURCE",
DatasourceName: "postgres-main",
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/workspace",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Workspace created successfully")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Sales Analytics',
'connectionType' => 'DATASOURCE',
'datasourceName' => 'postgres-main'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Workspace: " . $result['data']['name'];
?>
```
```json 200 - Success theme={"dark"}
{
"data": {
"name": "Sales Analytics"
},
"error": null
}
```
```json 400 - Workspace Already Exists theme={"dark"}
{
"error": {
"code": "WORKSPACE_NAME_ALREADY_EXISTS",
"message": "Workspace with the same name already exists"
}
}
```
```json 400 - Invalid Datasource theme={"dark"}
{
"error": {
"code": "INVALID_DATASOURCE_NAME",
"message": "Invalid datasource name provided"
}
}
```
```json 400 - Invalid Datamart theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART_NAME",
"message": "Invalid datamart name provided"
}
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"connectionType\" is required"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Workspace created successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ------------------------------- | ----------- | ----------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid parameters |
| `WORKSPACE_NAME_ALREADY_EXISTS` | 400 | Workspace name already exists |
| `INVALID_DATASOURCE_NAME` | 400 | Datasource not found |
| `INVALID_DATAMART_NAME` | 400 | Datamart not found |
| `INVALID_LLM_NAME` | 400 | Invalid LLM name provided |
| `INVALID_AI_COPILOT_LLMS` | 400 | Invalid AI Copilot LLM list |
| `INVALID_THEME_NAME` | 400 | Invalid theme name provided |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
Before creating a workspace, ensure you have:
* A valid API token from your data app
* Either a datasource or datamart already configured
* The exact name of your datasource or datamart (case-sensitive)
Decide which connection type fits your use case:
* **DATASOURCE**: For connecting to a single data source
* **DATAMART**: For connecting to a pre-configured datamart with table/column configurations
* **MULTI\_DATASOURCE**: For workspaces that need access to multiple datasources
* **MULTI\_DATAMART**: For workspaces that support multiple datamarts (same API shape as multi-datasource: only `name` and `connectionType` in the minimal body)
Start with DATASOURCE for simple use cases. Use DATAMART when you need structured access with tenancy settings. For multi-datamart setup in the product UI, see [Multi Datamart Workspace](/guides/workspace/multi-datamart-workspace).
Make the API call with your chosen configuration:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "My Analytics Workspace",
"connectionType": "DATASOURCE",
"datasourceName": "postgres-main"
}'
```
Successful response returns the workspace name. Save this for use in embed configurations.
Reference your workspace in dashboards and metrics:
```javascript theme={"dark"}
const embedConfig = {
workspaceName: 'My Analytics Workspace',
// ... other configuration
};
```
# Data App Embedding APIs
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/data-app-embedding-api
Retrieve dashboards and metrics from datapps
### Overview
The Databrain API provides endpoints for retrieving dashboards and metrics from data apps in both cloud Databrain and self-hosted Databrain environments.
# Datamart API
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/datamart-api
APIs to create, delete, and list datamart configurations associated with datasource.
## API Endpoints
### Cloud Databrain Endpoint
```bash theme={"dark"}
POST https://api.usedatabrain.com/api/v2/dataApp/datamart/{method_path}
```
### Self-hosted Databrain Endpoint
```bash theme={"dark"}
POST /api/v2/dataApp/datamart/{method_path}
```
Bearer token for API authentication. Format: `Bearer YOUR_API_TOKEN`.
# Delete Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-data-app
DELETE https://api.usedatabrain.com/api/v2/data-app?name={name}
Permanently delete a Data App and all its associated resources.
Permanently delete a Data App from your organization. This action removes the Data App along with all associated embed configurations and API tokens.
**Destructive Operation:** This action is irreversible. Deleting a Data App will:
* Remove all embed configurations associated with this Data App
* Invalidate all API tokens for this Data App
* Break any embedded dashboards using this Data App's tokens
Make sure you have updated your applications before deletion.
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage Data Apps across your organization.
## Endpoint Formats
```
DELETE https://api.usedatabrain.com/api/v2/data-app?name={name}
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
DELETE https://api.usedatabrain.com/api/v2/dataApp?name={name}
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
## Query Parameters
The name of the Data App to delete. This must exactly match the Data App name.
* Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to get all Data App names
* Check your Databrain dashboard for Data App configurations
* The name is case-sensitive
## Response
The name of the deleted Data App for confirmation.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app?name=Customer%20Portal%20Analytics' \
--header 'Authorization: Bearer service_token_xyz...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const dataAppName = 'Customer Portal Analytics';
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app?name=${encodeURIComponent(dataAppName)}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer service_token_xyz...'
}
});
const data = await response.json();
console.log('Deleted Data App:', data.name);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
from urllib.parse import quote
url = "https://api.usedatabrain.com/api/v2/data-app"
headers = {
"Authorization": "Bearer service_token_xyz..."
}
params = {
"name": "Customer Portal Analytics"
}
response = requests.delete(url, headers=headers, params=params)
data = response.json()
print(f"Deleted Data App: {data['name']}")
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DeleteDataApp {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String name = URLEncoder.encode("Customer Portal Analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app?name=%s",
name
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer service_token_xyz...")
.DELETE()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type DeleteDataAppResponse struct {
Name string `json:"name"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app"
params := url.Values{}
params.Add("name", "Customer Portal Analytics")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("DELETE", fullURL, nil)
req.Header.Set("Authorization", "Bearer service_token_xyz...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result DeleteDataAppResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Deleted Data App: %s\n", result.Name)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Customer Portal Analytics'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer service_token_xyz...',
'method' => 'DELETE'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted Data App: " . $response['name'];
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app')
params = { name: 'Customer Portal Analytics' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Deleted Data App: #{result['name']}"
```
```json 200 - Success theme={"dark"}
{
"name": "Customer Portal Analytics"
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"name\" is required"
}
}
```
```json 400 - Data App Not Found theme={"dark"}
{
"error": {
"code": "DATA_APP_NOT_FOUND",
"message": "Data app not found"
}
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Data app not found"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Data App deleted successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | ---------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid name parameter |
| `DATA_APP_NOT_FOUND` | 400 | Data App with given name not found |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
Before deleting, confirm the Data App exists using the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
Before deletion, update your applications to remove any references to this Data App's API tokens and embed configurations.
Make a DELETE request with the Data App name:
```bash theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app?name=My%20Data%20App' \
--header 'Authorization: Bearer service_token_xyz...'
```
Confirm the Data App was deleted by listing Data Apps again:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
## Best Practices
Always verify the Data App exists and check its embeds before deletion
Update your applications to remove Data App references before deletion
Implement proper error handling for failed deletions
Monitor for any broken embedded dashboards after deletion
## Next Steps
Create new Data Apps to replace deleted ones
View all remaining Data Apps
Generate API tokens for your Data Apps
View embed configurations for your Data Apps
# Delete Datamart
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-datamart
DELETE https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName={name}
Delete a datamart from your organization. This action cannot be undone.
Permanently delete a datamart from your organization. This will remove the datamart and all its associated configurations.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/datamart`. The old endpoint `/api/v2/dataApp/datamart` will be deprecated soon. Please update your integrations to use the new endpoint format.
This action is irreversible. Once a datamart is deleted, all its data configurations and associated embed configurations will be permanently removed.
## Endpoint Formats
```
DELETE https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName={name}
```
**Use this endpoint** for all new integrations. Uses REST-ful DELETE method with query parameters.
```
POST https://api.usedatabrain.com/api/v2/dataApp/datamart/delete
Content-Type: application/json
{
"datamartName": "sales-analytics"
}
```
This endpoint still works but will be deprecated. Uses POST method with JSON body.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
```bash Authentication theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The name of the datamart to delete. Must match an existing datamart name in your organization.
* Use the List Datamarts API to get all datamart names
* Check the response from datamart creation
* Available in the DataBrain dashboard when viewing datamarts
## Response
The name of the deleted datamart for confirmation.
Error field, null when successful.
## Examples
```bash cURL theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const datamartName = 'sales-analytics';
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName=${encodeURIComponent(datamartName)}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Deleted datamart:', data.id);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/datamart"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"datamartName": "sales-analytics"
}
response = requests.delete(url, headers=headers, params=params)
data = response.json()
print(f"Deleted datamart: {data['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamart')
params = { datamartName: 'sales-analytics' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Deleted datamart: #{data['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DataBrainDeleteDatamartAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String datamartName = URLEncoder.encode("sales-analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName=%s",
datamartName
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.DELETE()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type DeleteDatamartResponse struct {
Id string `json:"id"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/datamart"
params := url.Values{}
params.Add("datamartName", "sales-analytics")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("DELETE", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var datamartResp DeleteDatamartResponse
json.NewDecoder(resp.Body).Decode(&datamartResp)
fmt.Printf("Deleted datamart: %s\n", datamartResp.Id)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamart?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'DELETE'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted datamart: " . $response['id'];
?>
```
```json Success Response theme={"dark"}
{
"id": "sales-analytics",
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Datamart not found",
"status": 400
}
}
```
## Legacy Endpoint Examples
The following examples use the deprecated POST endpoint. These are provided for reference only. **Please use the DELETE endpoint examples above for all new integrations.**
```bash cURL theme={"dark"}
curl --request POST \
--url 'https://api.usedatabrain.com/api/v2/dataApp/datamart/delete' \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/dataApp/datamart/delete', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics'
})
});
const data = await response.json();
console.log('Deleted datamart:', data.id);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/dataApp/datamart/delete"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
data = {
"datamartName": "sales-analytics"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(f"Deleted datamart: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/dataApp/datamart/delete')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics'
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Deleted datamart: #{data['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainDeleteDatamartAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/dataApp/datamart/delete"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type DeleteDatamartRequest struct {
DatamartName string `json:"datamartName"`
}
type DeleteDatamartResponse struct {
Id string `json:"id"`
Error interface{} `json:"error"`
}
func main() {
reqData := DeleteDatamartRequest{
DatamartName: "sales-analytics",
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/dataApp/datamart/delete", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var datamartResp DeleteDatamartResponse
json.NewDecoder(resp.Body).Decode(&datamartResp)
fmt.Printf("Deleted datamart: %s\n", datamartResp.Id)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted datamart: " . $response['id'];
?>
```
```json Success Response theme={"dark"}
{
"id": "sales-analytics",
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Datamart not found",
"status": 400
}
}
```
## Error Codes
**Invalid request body** - Check that datamartName is provided and valid
**Unexpected failure** - Internal server error occurred
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------ |
| 200 | **OK** - Datamart deleted successfully |
| 400 | **Bad Request** - Invalid request parameters or datamart not found |
| 401 | **Unauthorized** - Invalid or expired API token |
| 500 | **Internal Server Error** - Unexpected server error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | ------------------ | ----------- |
| INVALID\_REQUEST\_BODY | Datamart not found | 400 |
| INTERNAL\_SERVER\_ERROR | Unexpected failure | 500 |
## Best Practices
Before deleting, verify no embed configurations depend on this datamart
Consider exporting important configurations before deletion
Test deletion process in a non-production environment first
Document the deletion for audit and compliance purposes
## Quick Start Guide
First, see which datamarts you have available to identify the one to delete:
```bash theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Before deleting, ensure no embed configurations are using this datamart. Use the List Embeds API to verify.
Make the deletion request with the exact datamart name as a query parameter:
```bash theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamart?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Update any embed configurations that were using this datamart to reference a different datamart:
```javascript theme={"dark"}
// Update embeds that used the deleted datamart
await updateEmbed({
embedId: 'embed_123',
accessSettings: {
datamartName: 'replacement-datamart'
}
});
```
**Critical:** This action permanently deletes the datamart and cannot be undone. Ensure all dependent configurations are updated before deletion.
## Next Steps
Create a new datamart to replace the deleted one
View all remaining datamarts in your organization
Create new embed configurations for your remaining datamarts
Generate tokens for your updated configurations
# Delete Datasource
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-datasource
DELETE https://api.usedatabrain.com/api/v2/datasource?datasourceName={name}
Delete a datasource from your organization. This action cannot be undone and will remove all associated configurations.
Permanently delete a datasource from your organization. This will remove the datasource and all its associated configurations, including cached schemas.
This action is irreversible. Once a datasource is deleted, all its configurations and cached schemas will be permanently removed. Ensure no datamarts or other resources depend on this datasource before deletion.
## Endpoint
```
DELETE https://api.usedatabrain.com/api/v2/datasource?datasourceName={name}
```
## Self-hosted Databrain Endpoint
```
DELETE /api/v2/datasource?datasourceName={name}
```
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
```bash Authentication theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/datasource?datasourceName=production-postgres' \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The name of the datasource to delete. Must match exactly as it was created.
* Use the [List Datasources API](/developer-docs/helpers/api-reference/list-datasources) to get all datasource names
* Check the response from datasource creation
* Available in the DataBrain dashboard when viewing datasources
## Response
The ID of the deleted datasource for confirmation.
Success message confirming the deletion: "Datasource deleted successfully".
Error field, null when successful. Not included in successful responses.
## Examples
```bash cURL theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/datasource?datasourceName=production-postgres' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js theme={"dark"}
const datasourceName = 'production-postgres';
const response = await fetch(
`https://api.usedatabrain.com/api/v2/datasource?datasourceName=${encodeURIComponent(datasourceName)}`,
{
method: 'DELETE',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
}
);
const data = await response.json();
if (data.error) {
console.error('Error:', data.error);
} else {
console.log('Deleted datasource:', data.id);
console.log('Message:', data.message);
}
```
```python Python theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/datasource"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"datasourceName": "production-postgres"
}
response = requests.delete(url, headers=headers, params=params)
data = response.json()
if data.get('error'):
print('Error:', data['error'])
else:
print(f"Deleted datasource: {data['id']}")
print(f"Message: {data['message']}")
```
```ruby Ruby theme={"dark"}
require 'net/http'
require 'json'
require 'uri'
uri = URI('https://api.usedatabrain.com/api/v2/datasource')
params = { datasourceName: 'production-postgres' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
if data['error']
puts "Error: #{data['error']}"
else
puts "Deleted datasource: #{data['id']}"
puts "Message: #{data['message']}"
end
```
```java Java theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DataBrainDeleteDatasourceAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String datasourceName = URLEncoder.encode("production-postgres", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/datasource?datasourceName=%s",
datasourceName
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.DELETE()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type DeleteDatasourceResponse struct {
Id string `json:"id"`
Message string `json:"message"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/datasource"
params := url.Values{}
params.Add("datasourceName", "production-postgres")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("DELETE", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var datasourceResp DeleteDatasourceResponse
json.NewDecoder(resp.Body).Decode(&datasourceResp)
if datasourceResp.Error != nil {
fmt.Printf("Error: %v\n", datasourceResp.Error)
} else {
fmt.Printf("Deleted datasource: %s\n", datasourceResp.Id)
fmt.Printf("Message: %s\n", datasourceResp.Message)
}
}
```
```php PHP theme={"dark"}
'production-postgres'
]);
$url = 'https://api.usedatabrain.com/api/v2/datasource?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'DELETE'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
if (isset($response['error'])) {
echo "Error: " . json_encode($response['error']);
} else {
echo "Deleted datasource: " . $response['id'] . "\n";
echo "Message: " . $response['message'];
}
?>
```
```json Success Response theme={"dark"}
{
"id": "uuid-of-deleted-datasource",
"message": "Datasource deleted successfully"
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid datasource name",
"status": 400
}
}
```
```json Error Response (400) - Datasource Not Found theme={"dark"}
{
"error": {
"code": "DATASOURCE_NAME_ERROR",
"message": "Invalid datasource name",
"status": 400
}
}
```
```json Error Response (400) - Datasource In Use theme={"dark"}
{
"error": {
"code": "DATASOURCE_IN_USE",
"message": "Cannot delete datasource as it is being used by other resources",
"status": 400
}
}
```
```json Error Response (401) theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "AUTHENTICATION_ERROR",
"status": 401
}
}
```
## Error Codes
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | ------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid datasourceName parameter |
| `DATASOURCE_NAME_ERROR` | 400 | Datasource not found |
| `DATASOURCE_IN_USE` | 400 | Datasource is being used by other resources |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error occurred |
## Next Steps
Create a new datasource to replace the deleted one
View all remaining datasources in your organization
Update datasource credentials instead of deleting
Create datamarts using your remaining datasources
# Delete an Embed
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-embed
DELETE https://api.usedatabrain.com/api/v2/data-app/embeds?embedId={id}
Delete an embed from your data app. This action cannot be undone.
Permanently delete an embed from your data app. This will remove the embed and invalidate any associated guest tokens.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/embeds`. The old endpoint `/api/v2/dataApp/embeds` will be deprecated soon. Please update your integrations to use the new endpoint format.
This action is irreversible. Once an embed configuration is deleted, all associated guest tokens will become invalid and embedded dashboards will stop working.
## Endpoint Formats
```
DELETE https://api.usedatabrain.com/api/v2/data-app/embeds?embedId={id}
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/data-app/embeds?embedId={id}
Content-Type: application/json
{
"embedId": "embed_abc123def456"
}
```
This endpoint still works but will be deprecated. Uses POST method with JSON body.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The unique identifier of the embed configuration to delete. Get this from the create embed response or list embeds API.
* Use the List All Embeds API to get embed IDs
* Check the response from embed creation
* Available in the DataBrain dashboard when viewing embed configurations
Optional parameter to also delete the associated dashboard along with the embed configuration. Set to `"true"` to enable dashboard deletion.
**Destructive Operation:** When set to `"true"`, this will permanently delete the dashboard associated with this embed. This action cannot be undone.
**When dashboard deletion is allowed:**
* Dashboard was created via API.
* Dashboard is only referenced by this single embed
* Embed and dashboard both belong to your organization
**Params:**
* `isDeleteDashboard=true` - Delete both embed and dashboard
* `isDeleteDashboard=false` or omitted - Delete only embed configuration
## Response
The ID of the deleted embed configuration for confirmation.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Delete Embed Only theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL - Delete Embed and Dashboard theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456&isDeleteDashboard=true' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js - Delete Embed Only icon="fa-brands fa-node-js" theme={"dark"}
const embedId = 'embed_abc123def456';
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=${encodeURIComponent(embedId)}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Deleted embed:', data.id);
```
```javascript Node.js - Delete Embed and Dashboard icon="fa-brands fa-node-js" theme={"dark"}
const embedId = 'embed_abc123def456';
const isDeleteDashboard = true;
const url = new URL('https://api.usedatabrain.com/api/v2/data-app/embeds');
url.searchParams.append('embedId', embedId);
url.searchParams.append('isDeleteDashboard', isDeleteDashboard.toString());
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Deleted embed and dashboard:', data.id);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/embeds"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"embedId": "embed_abc123def456"
}
response = requests.delete(url, headers=headers, params=params)
data = response.json()
print(f"Deleted embed: {data['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/embeds')
params = { embedId: 'embed_abc123def456' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Deleted embed: #{data['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DataBrainDeleteEmbedAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String embedId = URLEncoder.encode("embed_abc123def456", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=%s",
embedId
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.DELETE()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type DeleteEmbedResponse struct {
Id string `json:"id"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/embeds"
params := url.Values{}
params.Add("embedId", "embed_abc123def456")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("DELETE", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var embedResp DeleteEmbedResponse
json.NewDecoder(resp.Body).Decode(&embedResp)
fmt.Printf("Deleted embed: %s\n", embedResp.Id)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'embed_abc123def456'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/embeds?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'DELETE'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted embed: " . $response['id'];
?>
```
```json Success Response theme={"dark"}
{
"id": "embed_abc123def456"
}
```
```json Error - Embed Not Found theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Embed not found"
}
}
```
```json Error - Internal Dashboard Cannot Be Deleted theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Deletion blocked: internal dashboards can't be removed."
}
}
```
```json Error - Dashboard Referenced by Multiple Embeds theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Deletion blocked: this dashboard is referenced by multiple embeds."
}
}
```
```json Error - Invalid API Key theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
## Legacy Endpoint Examples
The following examples use the deprecated POST endpoint. These are provided for reference only. **Please use the DELETE endpoint examples above for all new integrations.**
```bash cURL theme={"dark"}
curl --request POST \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456' \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId: 'embed_abc123def456'
})
});
const data = await response.json();
console.log('Deleted embed:', data.id);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
data = {
"embedId": "embed_abc123def456"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(f"Deleted embed: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
embedId: 'embed_abc123def456'
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Deleted embed: #{data['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainDeleteEmbedAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"embedId": "embed_abc123def456"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type DeleteEmbedRequest struct {
EmbedId string `json:"embedId"`
}
type DeleteEmbedResponse struct {
Id string `json:"id"`
Error interface{} `json:"error"`
}
func main() {
reqData := DeleteEmbedRequest{
EmbedId: "embed_abc123def456",
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/data-app/embeds?embedId=embed_abc123def456", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var embedResp DeleteEmbedResponse
json.NewDecoder(resp.Body).Decode(&embedResp)
fmt.Printf("Deleted embed: %s\n", embedResp.Id)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'embed_abc123def456'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted embed: " . $response['id'];
?>
```
```json Success Response theme={"dark"}
{
"id": "embed_abc123def456",
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Embed not found",
"status": 400
}
}
```
## Error Codes
**Invalid request body** - Check that embedId is provided and valid
**Missing or invalid data app** - Check your API key and data app configuration
**Unexpected failure** - Internal server error occurred
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | --------------------------------------------------------------- |
| 200 | **OK** - Embed deleted successfully |
| 400 | **Bad Request** - Invalid request parameters or embed not found |
| 500 | **Internal Server Error** - Unexpected server error |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ---------------------------------------------- |
| `INVALID_REQUEST_BODY` | 500 | Embed not found |
| `INVALID_REQUEST_BODY` | 500 | Internal dashboards can't be removed |
| `INVALID_REQUEST_BODY` | 500 | Dashboard is referenced by multiple embeds |
| `INVALID_DATA_APP_API_KEY` | 400 | invalid or expired API KEY, data app not found |
## Usage Examples
### Basic Deletion
```javascript theme={"dark"}
// Delete an embed configuration
const result = await deleteEmbed({
embedId: 'embed_123'
});
console.log(`Deleted embed: ${result.id}`);
```
### Batch Deletion
```javascript theme={"dark"}
// Delete multiple embed configurations
const embedIds = ['embed_1', 'embed_2', 'embed_3'];
for (const embedId of embedIds) {
try {
const result = await deleteEmbed({ embedId });
console.log(`Deleted embed: ${result.id}`);
} catch (error) {
console.error(`Failed to delete ${embedId}:`, error.message);
}
}
```
### Safe Deletion with Verification
```javascript theme={"dark"}
// Verify embed exists before deletion
const embeds = await listEmbeds();
const embedToDelete = embeds.data.find(e => e.embedId === 'embed_123');
if (embedToDelete) {
const result = await deleteEmbed({
embedId: embedToDelete.embedId
});
console.log(`Successfully deleted: ${result.id}`);
} else {
console.log('Embed not found');
}
```
## Best Practices
Always verify the embed exists before attempting deletion
Implement proper error handling for failed deletions
Update your integration documentation after deletions
Monitor for any broken embedded dashboards after deletion
**Important:** Deleting an embed configuration will invalidate all guest tokens associated with it and break any embedded dashboards using this configuration. Ensure you have updated your application before deletion.
## Next Steps
Create new embed configurations to replace deleted ones
View all remaining embed configurations
Modify existing embed configurations instead of deleting
Generate new tokens for your updated configurations
# Delete Semantic Layer
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-semantic-layer
DELETE https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName={name}
Delete the semantic layer from a datamart, removing all descriptions, synonyms, column types, and feedback.
Permanently remove all semantic layer metadata from a datamart. This clears table descriptions, column metadata (descriptions, synonyms, column types, configs), and feedback. The underlying datamart structure (tables, columns) remains intact.
This action cannot be undone. All semantic metadata — descriptions, synonyms, column types, and feedback — will be permanently removed.
The datamart itself is not deleted. Only the semantic layer enrichments are removed. You can recreate the semantic layer using the [POST endpoint](/developer-docs/helpers/api-reference/create-semantic-layer).
## Authentication
This endpoint requires a **service token** in the Authorization header. Data app API tokens are not permitted and will be rejected with a `403` error.
To access your service token:
1. Go to your Databrain dashboard and open **Settings**.
2. Navigate to **Settings**.
3. Find the **Service Tokens** section.
4. Click the **"Generate Token"** button to generate a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The name of the datamart whose semantic layer you want to delete. Must match an existing datamart that has semantic data.
* Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to get all datamart names
* Use the [Get Semantic Layer API](/developer-docs/helpers/api-reference/get-semantic-layer) to confirm semantic data exists
## Response
On success, the response body contains only the datamart name. There is no `error` field in the JSON body when the request succeeds.
The name of the datamart whose semantic layer was deleted.
## Examples
```bash cURL theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const datamartName = 'sales-analytics';
const response = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=${encodeURIComponent(datamartName)}`,
{
method: 'DELETE',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
}
);
const result = await response.json();
if (result.error) {
console.error('Delete failed:', result.error.message);
} else {
console.log('Semantic layer deleted for:', result.id);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.delete(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...'
},
params={
'datamartName': 'sales-analytics'
}
)
result = response.json()
if result.get('error'):
print(f"Delete failed: {result['error']['message']}")
else:
print(f"Semantic layer deleted for: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
params = { datamartName: 'sales-analytics' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Deleted: #{result['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DeleteSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String datamartName = URLEncoder.encode("sales-analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=%s",
datamartName
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.DELETE()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"
params := url.Values{}
params.Add("datamartName", "sales-analytics")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("DELETE", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Deleted: %v\n", result["id"])
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'DELETE'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Deleted: " . $response['id'];
?>
```
```json 200 - Success theme={"dark"}
{
"id": "sales-analytics"
}
```
```json 400 - Missing datamartName theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "datamartName query parameter is required"
}
}
```
```json 400 - Datamart Not Found theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART",
"message": "Datamart 'nonexistent' not found"
}
}
```
```json 404 - No Semantic Layer theme={"dark"}
{
"error": {
"code": "SEMANTIC_LAYER_NOT_FOUND",
"message": "No semantic layer found for datamart 'sales-analytics'."
}
}
```
```json 403 - Data App Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------ |
| `200` | **OK** — Semantic layer deleted successfully |
| `400` | **Bad Request** — Missing datamartName or datamart not found |
| `401` | **Unauthorized** — Invalid or missing API token |
| `403` | **Forbidden** — Data app token used instead of service token |
| `404` | **Not Found** — No semantic layer exists for this datamart |
| `500` | **Internal Server Error** — Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | datamartName query parameter is missing |
| `INVALID_DATAMART` | 400 | Datamart not found |
| `SEMANTIC_LAYER_NOT_FOUND` | 404 | No semantic layer exists for this datamart |
| `AUTHENTICATION_ERROR` | 403 | Data app token used instead of service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Best Practices
Use the GET endpoint to save a copy of the semantic layer before deleting
AI chat mode relies on the semantic layer — verify impact before deleting
## Quick Start Guide
Retrieve and save the current semantic layer data:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...' \
-o semantic-layer-backup.json
```
```bash theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Retrieve the datamart again to confirm the semantic layer was cleared:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
The response should show `null` descriptions, empty synonyms, and a completion score of `0`.
## Next Steps
Recreate the semantic layer with fresh metadata
Verify the deletion
Configure the semantic layer in the Databrain UI
View your datamarts
# Delete Workspace
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/delete-workspace
DELETE https://api.usedatabrain.com/api/v2/workspace?name={name}
Permanently delete a workspace from your organization by name.
Permanently delete a workspace. The workspace is identified by the **`name`** query parameter. The payload is validated with **`name`**: required string (`Joi.string().required()`).
This action is irreversible. Ensure no dashboards, metrics, or embeds still depend on this workspace before deleting it.
## Endpoint
```
DELETE https://api.usedatabrain.com/api/v2/workspace?name={name}
```
## Self-hosted Databrain Endpoint
```
DELETE /api/v2/workspace?name={name}
```
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
```bash Authentication theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/workspace?name=sales-analytics' \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
Workspace name to delete. Must match an existing workspace in your organization (case-sensitive, same string as returned by list/create).
If `name` is omitted, validation fails with `INVALID_REQUEST_BODY` and the Joi validation message (for example `"name" is required`).
* Use the [List Workspaces API](/developer-docs/helpers/api-reference/list-workspaces) to list workspace names
* Use the same value as in [Create Workspace](/developer-docs/helpers/api-reference/create-workspace) / [Update Workspace](/developer-docs/helpers/api-reference/update-workspace)
## Response
On success, the API returns a top-level **`data`** object (same shape as other `/api/v2/workspace` handlers).
Set to the workspace **`name`** that was deleted (string echoed from the query parameter).
Success message: `Workspace deleted successfully`.
On success, `error` is omitted or null. On failure, contains `code` and `message` (see examples below).
## Examples
```bash cURL theme={"dark"}
curl --request DELETE \
--url 'https://api.usedatabrain.com/api/v2/workspace?name=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const workspaceName = 'sales-analytics';
const response = await fetch(
`https://api.usedatabrain.com/api/v2/workspace?name=${encodeURIComponent(workspaceName)}`,
{
method: 'DELETE',
headers: {
Authorization: 'Bearer dbn_live_abc123...',
},
}
);
const result = await response.json();
if (result.error) {
console.error('Error:', result.error);
} else {
console.log('Deleted workspace:', result.data);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/workspace"
headers = {"Authorization": "Bearer dbn_live_abc123..."}
params = {"name": "sales-analytics"}
response = requests.delete(url, headers=headers, params=params)
result = response.json()
if result.get("error"):
print("Error:", result["error"])
else:
print("Deleted workspace:", result.get("data"))
```
```json 200 - Success theme={"dark"}
{
"data": {
"id": "sales-analytics",
"message": "Workspace deleted successfully"
}
}
```
```json 400 - Missing or invalid API key (middleware) theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is not provided or Invalid!"
}
}
```
```json 400 - Invalid request body (Joi) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"name\" is required"
}
}
```
```json 400 - Workspace not found theme={"dark"}
{
"error": {
"code": "WORKSPACE_ID_ERROR",
"message": "invalid workspace name, workspace name not found"
}
}
```
```json 401 - Invalid or expired API key (middleware) theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is invalid or expired!"
}
}
```
```json 500 - Internal server error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ----------------------------------------------------------------------------------------------------- |
| `200` | **OK** — Workspace deleted successfully |
| `400` | **Bad Request** — Missing/invalid API key (middleware), Joi validation failed, or workspace not found |
| `401` | **Unauthorized** — Invalid/expired token or missing required scopes (middleware) |
| `500` | **Internal Server Error** — Delete mutation failed or unexpected error |
## Possible Errors
| Error code | HTTP status | When it occurs |
| ----------------------- | ----------- | ---------------------------------------------------------------- |
| `AUTHENTICATION_ERROR` | 400 | Authorization missing or malformed (`isPrivateApp` middleware) |
| `INVALID_REQUEST_BODY` | 400 | `deleteWorkspaceSchema` validation failed (e.g. missing `name`) |
| `WORKSPACE_ID_ERROR` | 400 | No workspace with that `name` for your company |
| `AUTHENTICATION_ERROR` | 401 | Service token invalid, expired, or missing required scopes |
| `INTERNAL_SERVER_ERROR` | 500 | Delete mutation returned no row, GraphQL error, or handler catch |
## Next Steps
List remaining workspaces in your organization
Create a new workspace after deletion
Update workspace settings instead of deleting
# Embed Data App API (CRUD)
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/embed-data-app-crud
APIs to create, update, delete, and list embed configurations associated with dashboards or metrics in data app
## API Endpoints
### Cloud Databrain Endpoint
```bash theme={"dark"}
POST https://api.usedatabrain.com/api/v2/dataApp/embed/{method_path}
```
### Self-hosted Databrain Endpoint
```bash theme={"dark"}
POST /api/v2/dataApp/embed/{method_path}
```
Bearer token for API authentication. Format: `Bearer YOUR_API_TOKEN`.
# Embedding APIs
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/embedding-apis
Retrieve dashboards and metrics from workspaces
### Overview
The Databrain API provides endpoints for retrieving dashboards and metrics from workspaces in both Cloud Databrain and self-hosted Databrain environments. To use the API, you need to pass a workspaceName along with other optional parameters.
**First-time flow:** Create an embed ([Create Embed](/developer-docs/helpers/api-reference/create-embed) or [Create Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed)), list embeds ([List Embeds](/developer-docs/helpers/api-reference/list-embed)) to verify metadata configurations and identify the created embed, then call [Update Workspace Dashboards](/developer-docs/helpers/api-reference/update-workspace-dashboards) to apply filter mapping changes using the embed id listed in metadata.
# Export Dashboard
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/export-dashboard
POST https://api.usedatabrain.com/api/v2/data-app/export-dashboard
Export a dashboard from a workspace as a JSON file for backup, migration, or import into another workspace.
Export a dashboard and its configuration (layout, metrics, filters) from a workspace. The response is a JSON file download that can be used with the [Import Dashboard API](/developer-docs/helpers/api-reference/import-dashboard) or the UI import flow.
**Authentication Requirement:** This endpoint requires a **service token** (company-level), not a data app API key. Service tokens have elevated permissions. Use the token that has access to the workspace and dashboard.
## Authentication
Use your service token in the `Authorization` header. See [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) for how to obtain a service token.
```bash Authentication theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/export-dashboard \
--header 'Authorization: Bearer YOUR_SERVICE_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"dashboardId":"your-dashboard-id","workspaceName":"Your Workspace"}'
```
## Headers
Bearer token for API authentication. Use your **service token** (company-level).
```
Authorization: Bearer dbn_live_...
```
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
The dashboard ID to export. This is the external dashboard ID (e.g. from [Fetch Dashboards by Data App](/developer-docs/helpers/api-reference/fetch-dashboards-by-datapp) or the dashboard list in the UI).
The name of the workspace that contains the dashboard. Must match the workspace name exactly.
## Response
On success, the API returns **200** with:
* **Content-Type:** `application/json`
* **Content-Disposition:** `attachment; filename="dashboard-{dashboardId}.json"`
The response body is a JSON object with this structure:
Metadata about the export.
ISO 8601 timestamp when the export was performed.
The workspace name the dashboard was exported from.
The dashboard ID that was exported.
The dashboard configuration and content (layout, metrics, filters, etc.). Structure matches what the import API expects as `importDashboardData`.
On error, the API returns a JSON error object (e.g. 400 or 500) with `error.code` and `error.message`.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url 'https://api.usedatabrain.com/api/v2/data-app/export-dashboard' \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json' \
--data '{"dashboardId":"sales-dashboard-1","workspaceName":"Sales Workspace"}' \
--output dashboard-sales-dashboard-1.json
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/export-dashboard', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
dashboardId: 'sales-dashboard-1',
workspaceName: 'Sales Workspace'
})
});
if (!response.ok) {
const err = await response.json();
throw new Error(err.error?.message || 'Export failed');
}
const blob = await response.blob();
// Save or process the JSON file
const text = await blob.text();
const exported = JSON.parse(text);
console.log('Exported at:', exported._meta?.exportedAt);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/export-dashboard"
headers = {
"Authorization": "Bearer dbn_live_...",
"Content-Type": "application/json"
}
payload = {
"dashboardId": "sales-dashboard-1",
"workspaceName": "Sales Workspace"
}
response = requests.post(url, headers=headers, json=payload)
if not response.ok:
raise Exception(response.json().get("error", {}).get("message", "Export failed"))
with open("dashboard-sales-dashboard-1.json", "w") as f:
f.write(response.text)
```
```json Success (response body is the downloaded JSON) theme={"dark"}
{
"_meta": {
"exportedAt": "2025-02-13T10:00:00.000Z",
"workspaceName": "Sales Workspace",
"dashboardId": "sales-dashboard-1"
},
"data": {
"layout": [...],
"filters": [...],
...
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"dashboardId\" is required"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "AUTH_ERROR",
"message": "Invalid Service Token"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "DATA_APP_NOT_FOUND",
"message": "Data app not found"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------------------ |
| `200` | **OK** – Dashboard exported successfully; response is a JSON file (attachment) |
| `400` | **Bad Request** – Invalid or missing parameters, invalid token, or dashboard/workspace not found |
| `500` | **Internal Server Error** – Server error during export |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | --------------------------------------------------------- | ----------- |
| `INVALID_REQUEST_BODY` | Joi validation message (e.g. `"dashboardId" is required`) | 400 |
| `AUTH_ERROR` | Invalid Service Token | 400 |
| `DATA_APP_NOT_FOUND` | Data app not found | 400 |
| `INTERNAL_SERVER_ERROR` | Server error message | 500 |
## Related
* [Import Dashboard](/developer-docs/helpers/api-reference/import-dashboard) – Import a previously exported dashboard into a workspace
* [Fetch Dashboards by Data App](/developer-docs/helpers/api-reference/fetch-dashboards-by-datapp) – List dashboards to get `dashboardId` values
* [Import/Export Dashboard (UI)](/guides/dashboards/import-export-dashboard) – UI guide for import/export
# Export Embedded Dashboard
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/export-embed
GET https://api.usedatabrain.com/api/v2/data-app/embeds/export?embedId={embed_abc123}
Export the dashboard and configuration behind a data app embed using a data app API token.
Export the dashboard and its configuration (layout, metrics, filters) associated with a specific embed configuration. This endpoint is useful when you want to:
* Clone an embedded dashboard into another workspace or client
* Back up the configuration behind an embed
* Feed the exported configuration into the **Create Empty Dashboard Embed** API via `importDashboardData`
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/embeds/export`. The old endpoint `/api/v2/dataApp/embeds/export` will be deprecated soon. Please update your integrations to use the new endpoint format.
## Authentication
All API requests must include your **data app API token** in the `Authorization` header. This is the same token you use for other data app embedding APIs.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request GET \
--url "https://api.usedatabrain.com/api/v2/data-app/embeds/export?embedId=embed_abc123" \
--header 'Authorization: Bearer dbn_live_abc123...'
```
## Headers
Bearer token for API authentication. Use your **data app API token**.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The embed configuration ID to export. This identifies which embedded dashboard's configuration should be exported.
* Created when you configure an embed via the [Create Embed API](/developer-docs/helpers/api-reference/create-embed) or [Create Empty Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed)
* Retrieved via the [List Embeds API](/developer-docs/helpers/api-reference/list-embed)
* Available in your DataBrain dashboard embed settings
## Response
On success, the API returns **200** with:
* **Content-Type:** `application/json`
* **Content-Disposition:** `attachment; filename="dashboard-{embedId}.json"`
The response body is a JSON object with this structure:
Metadata about the export and the embed configuration.
ISO 8601 timestamp when the export was performed.
The embed ID that was exported.
Human-readable name of the embed configuration.
Type of embed configuration: typically `"dashboard"` or `"metric"`.
External dashboard ID associated with this embed. This is the dashboard that the export is based on.
Access settings associated with the embed, including flags like `isAllowEmailReports`, `isAllowManageMetrics`, and other permissions.
The dashboard configuration and content (layout, metrics, filters, etc.). Structure matches what the Import Dashboard API expects as `importDashboardData`, and what the **Create Empty Dashboard Embed** API expects when you pass `importDashboardData` in the request body.
On error, the API returns a JSON error object with `error.code`, `error.message`, and `error.status`. Possible errors include:
* `INVALID_REQUEST_BODY` – Request validation failed (for example, missing or invalid `embedId`)
* `INVALID_DATA_APP_API_KEY` – Invalid or missing data app API token
* `EMBED_PARAM_ERROR` – Invalid or unknown embed ID for the current data app
* `INVALID_EMBED_ID` – Embed not found
* `INTERNAL_SERVER_ERROR` – Unexpected server error
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds/export?embedId=embed_abc123' \
--header 'Authorization: Bearer dbn_live_abc123...' \
--output dashboard-embed_abc123.json
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const params = new URLSearchParams({ embedId: 'embed_abc123' });
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/embeds/export?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
},
});
if (!response.ok) {
const err = await response.json();
throw new Error(err.error?.message || 'Export failed');
}
const text = await response.text();
const exported = JSON.parse(text);
console.log('Exported at:', exported._meta?.exportedAt);
console.log('Embed dashboard id:', exported._meta?.dashboardId);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/embeds/export"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"embedId": "embed_abc123"
}
response = requests.get(url, headers=headers, params=params)
if not response.ok:
err = response.json().get("error", {})
raise Exception(err.get("message", "Export failed"))
exported = response.json()
print("Exported at:", exported["_meta"]["exportedAt"])
print("Dashboard ID:", exported["_meta"]["dashboardId"])
```
```json Success (truncated) theme={"dark"}
{
"_meta": {
"exportedAt": "2026-03-11T10:00:00.000Z",
"embedId": "embed_abc123",
"name": "Customer Analytics Embed",
"embedType": "dashboard",
"dashboardId": "sales-dashboard-1",
"embedDataAppAccessSetting": {
"isAllowEmailReports": true,
"isAllowManageMetrics": true,
"isAllowCreateDashboardView": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"metricCreationMode": "DRAG_DROP",
"isIncrementalJoin": true
}
},
"data": {
"layout": [...],
"filters": [...],
"metrics": [...],
"...": "additional dashboard configuration"
}
}
```
```json Error Response (400 - invalid embedId) theme={"dark"}
{
"error": {
"code": "EMBED_PARAM_ERROR",
"message": "Invalid default embed id",
"status": 400
}
}
```
```json Error Response (401 - invalid data app token) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Invalid Data App API Key",
"status": 401
}
}
```
## Common Workflow: Clone an Embed Dashboard
1. **Export the embed dashboard configuration**
Use this endpoint to export the configuration for an existing embed:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds/export?embedId=embed_abc123' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
2. **Create a new client dashboard using `importDashboardData`**
Pass the exported `data` payload into the [Create Empty Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed) API:
```json theme={"dark"}
{
"dashboardId": "client-acme-analytics",
"clientId": "acme-corp-123",
"workspaceName": "analytics-workspace",
"name": "ACME Analytics Dashboard",
"isRenameDashboard": true,
"importDashboardData": exported.data,
"accessSettings": {
"datamartName": "customer-analytics",
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowCreateDashboardView": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": false,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"metricCreationMode": "DRAG_DROP"
}
}
```
This flow lets you reuse an existing embedded dashboard as a starting point for new client dashboards while keeping the configuration in sync.
# Fetch Dashboards by Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/fetch-dashboards-by-datapp
GET https://api.usedatabrain.com/api/v2/data-app/dashboards
Retrieve a list of dashboards available in your data app with optional filtering and pagination.
Fetch all dashboards associated with your data app. This endpoint allows you to discover available dashboards for embedding or integration purposes, with support for filtering by dashboard names and pagination.
**API Method Migration Notice:** We're transitioning from POST to GET for this endpoint. The new GET method is recommended for all new integrations. The POST method will be deprecated soon.
This endpoint returns dashboards that have been configured for your data app. Use the dashboard information to create embed configurations or for display purposes.
## API Methods
```
GET https://api.usedatabrain.com/api/v2/data-app/dashboards
```
**Use this method** for all new integrations. This is the recommended approach with query parameters.
```
POST https://api.usedatabrain.com/api/v2/data-app/dashboards
```
This method still works but will be deprecated. Please migrate to the GET method.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Required only for POST method. Must be set to `application/json`.
```
Content-Type: application/json
```
## Query Parameters
Enable pagination to limit the number of results returned. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number for pagination (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
Comma-separated list of dashboard names to filter by. Only dashboards with matching names will be returned.
**Example:** `"Sales Dashboard,Marketing Analytics,Customer Insights"`
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/dashboards?isPagination=true&pageNumber=1&dashboardNames=Sales%20Dashboard,Marketing%20Analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const params = new URLSearchParams({
isPagination: 'true',
pageNumber: '1',
dashboardNames: 'Sales Dashboard,Marketing Analytics'
});
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/dashboards?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Dashboards:', data.data);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/dashboards"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"isPagination": "true",
"pageNumber": "1",
"dashboardNames": "Sales Dashboard,Marketing Analytics"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Dashboards: {data['data']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/dashboards')
params = {
isPagination: 'true',
pageNumber: '1',
dashboardNames: 'Sales Dashboard,Marketing Analytics'
}
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Dashboards: #{data['data']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class DataBrainDashboardsAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String dashboardNames = URLEncoder.encode("Sales Dashboard,Marketing Analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/dashboards?isPagination=true&pageNumber=1&dashboardNames=%s",
dashboardNames
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Dashboard struct {
Name string `json:"name"`
ExternalDashboardID string `json:"externalDashboardId"`
EmbedID string `json:"embedId"`
}
type DashboardResponse struct {
Data []Dashboard `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/dashboards"
params := url.Values{}
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
params.Add("dashboardNames", "Sales Dashboard,Marketing Analytics")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var dashboardResp DashboardResponse
json.NewDecoder(resp.Body).Decode(&dashboardResp)
fmt.Printf("Dashboards: %+v\n", dashboardResp.Data)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'true',
'pageNumber' => '1',
'dashboardNames' => 'Sales Dashboard,Marketing Analytics'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/dashboards?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Dashboards: " . print_r($response['data'], true);
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"name": "Sales Dashboard",
"externalDashboardId": "sales_dash_123",
"embedId": "embed_abc123"
},
{
"name": "Marketing Analytics",
"externalDashboardId": "marketing_dash_456",
"embedId": "embed_def456"
}
]
}
```
```json Empty Results Response theme={"dark"}
{
"data": []
}
```
```json Error Response (401) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Invalid or missing Data App API Key"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Required fields missing or wrong type"
}
}
```
## Legacy Endpoint Examples
The following examples use the deprecated POST method. These are provided for reference only. **Please use the GET method examples above for all new integrations.**
## POST Method (Legacy - Being Deprecated)
### Request Body (POST)
Enable pagination to limit the number of results returned. When enabled, use `pageNumber` to navigate through pages.
Page number for pagination (1-based). Only used when `isPagination` is `true`. Each page returns up to 10 dashboards.
Optional filters to narrow down the dashboard results.
Array of specific dashboard names to filter by. Only dashboards with matching names will be returned.
```json Example theme={"dark"}
["Sales Dashboard", "Marketing Analytics", "Customer Insights"]
```
### POST Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"isPagination": true,
"pageNumber": 1,
"filters": {
"dashboardNames": ["Sales Dashboard", "Marketing Analytics"]
}
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/dashboards', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
isPagination: true,
pageNumber: 1,
filters: {
dashboardNames: ['Sales Dashboard', 'Marketing Analytics']
}
})
});
const data = await response.json();
console.log('Dashboards:', data.data);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
import json
url = "https://api.usedatabrain.com/api/v2/data-app/dashboards"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
payload = {
"isPagination": True,
"pageNumber": 1,
"filters": {
"dashboardNames": ["Sales Dashboard", "Marketing Analytics"]
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
data = response.json()
print(f"Dashboards: {data['data']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/dashboards')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
isPagination: true,
pageNumber: 1,
filters: {
dashboardNames: ['Sales Dashboard', 'Marketing Analytics']
}
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Dashboards: #{data['data']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Arrays;
public class DataBrainDashboardsAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
Map filters = new HashMap<>();
filters.put("dashboardNames", Arrays.asList("Sales Dashboard", "Marketing Analytics"));
Map requestBody = new HashMap<>();
requestBody.put("isPagination", true);
requestBody.put("pageNumber", 1);
requestBody.put("filters", filters);
String jsonBody = mapper.writeValueAsString(requestBody);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/dashboards"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type DashboardFilters struct {
DashboardNames []string `json:"dashboardNames"`
}
type DashboardRequest struct {
IsPagination bool `json:"isPagination"`
PageNumber int `json:"pageNumber"`
Filters DashboardFilters `json:"filters"`
}
type Dashboard struct {
Name string `json:"name"`
ExternalDashboardID string `json:"externalDashboardId"`
EmbedID string `json:"embedId"`
}
type DashboardResponse struct {
Data []Dashboard `json:"data"`
Error interface{} `json:"error"`
}
func main() {
reqBody := DashboardRequest{
IsPagination: true,
PageNumber: 1,
Filters: DashboardFilters{
DashboardNames: []string{"Sales Dashboard", "Marketing Analytics"},
},
}
jsonData, _ := json.Marshal(reqBody)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/dashboards",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var dashboardResp DashboardResponse
json.NewDecoder(resp.Body).Decode(&dashboardResp)
fmt.Printf("Dashboards: %+v\n", dashboardResp.Data)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
true,
'pageNumber' => 1,
'filters' => [
'dashboardNames' => ['Sales Dashboard', 'Marketing Analytics']
]
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Dashboards: " . print_r($response['data'], true);
?>
```
## Response (Success 200)
Array of dashboard objects available in your data app.
Display name of the dashboard.
Unique identifier for the dashboard that can be used in embed configurations.
Embed ID associated with this dashboard, if available.
## Error Response
Error object returned only when the request fails. Not included in successful responses.
Error code identifier.
Human-readable error message.
## Error Codes
**Invalid or missing Data App API Key** - Check your API key and ensure it's valid for your data app
**Invalid request parameters** - Verify that your request body contains valid field types
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | --------------------------------------------------------------- |
| `200` | **OK** - Dashboards retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters or missing API key |
| `401` | **Unauthorized** - Invalid or missing API key |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------- |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INVALID_REQUEST_BODY` | 400 | Invalid request body |
| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Pagination Guide
When using pagination:
1. **Enable pagination** by setting `isPagination` to `true` (GET) or `true` (POST)
2. **Start with page 1** using `pageNumber=1` (GET) or `pageNumber: 1` (POST)
3. **Each page returns up to 10 dashboards**
4. **Continue to next page** if you receive exactly 10 results
5. **Stop pagination** when you receive fewer than 10 results
### GET Method Pagination Example:
```
GET /api/v2/data-app/dashboards?isPagination=true&pageNumber=1
```
### POST Method Pagination Example:
```json theme={"dark"}
{
"isPagination": true,
"pageNumber": 1
}
```
## Filtering Options
### Dashboard Name Filtering
**GET Method:** Use comma-separated values in query parameter
```
?dashboardNames=Dashboard%201,Dashboard%202
```
**POST Method:** Use array in request body
```json theme={"dark"}
{
"filters": {
"dashboardNames": ["Dashboard 1", "Dashboard 2"]
}
}
```
This is useful when you know the exact dashboard names you want to work with.
## Migration Guide: POST to GET
If you're currently using the POST method, here's how to migrate to GET:
### Before (POST):
```javascript theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/dashboards', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
isPagination: true,
pageNumber: 1,
filters: {
dashboardNames: ['Sales Dashboard']
}
})
});
```
### After (GET):
```javascript theme={"dark"}
const params = new URLSearchParams({
isPagination: 'true',
pageNumber: '1',
dashboardNames: 'Sales Dashboard'
});
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/dashboards?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_...'
}
});
```
### Key Differences:
1. **Method**: POST → GET
2. **Parameters**: Request body → Query parameters
3. **Boolean values**: `true` → `"true"` (string in query params)
4. **Number values**: `1` → `"1"` (string in query params)
5. **Dashboard names**: Array `["name1", "name2"]` → Comma-separated string `"name1,name2"`
6. **Content-Type header**: Not needed for GET
## Quick Start Guide
For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
Get all dashboards available in your data app:
```bash theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...'
```
If you're looking for specific dashboards, use query parameters:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/dashboards?dashboardNames=Sales%20Dashboard,Marketing%20Analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Process the dashboard data to create embed configurations:
```javascript theme={"dark"}
const dashboards = await fetchDataAppDashboards();
dashboards.data.forEach(dashboard => {
console.log(`Dashboard: ${dashboard.name}`);
console.log(`External ID: ${dashboard.externalDashboardId}`);
// Use the externalDashboardId to create embed configurations
if (!dashboard.embedId) {
console.log('This dashboard can be made embeddable');
}
});
```
## Next Steps
Use dashboard IDs to create embed configurations
Get metrics available for specific embedded dashboards
Query data from your dashboard metrics
Generate secure tokens for embedded access
# Fetch metric data by data app
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/fetch-metric-data-by-dataapp
POST https://api.usedatabrain.com/api/v2/data-app/query
Execute queries on metrics within your embedded dashboards and retrieve the resulting data.
Query specific metrics from your embedded dashboards to retrieve data programmatically. This endpoint allows you to fetch metric data with optional filtering and is essential for building custom analytics interfaces or exporting data from your embedded dashboards.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/query`. The old endpoint `/api/v2/dataApp/query` will be deprecated soon. Please update your integrations to use the new endpoint format.
This endpoint requires an embed ID, metric ID, and client ID. The metric must be associated with the specified embed configuration for the query to succeed.
## Endpoint Formats
```
POST https://api.usedatabrain.com/api/v2/data-app/query
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/query
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/query \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The unique identifier of the embed configuration containing the metric.
* Use the List All Embeds API to get embed IDs
* Check the response from embed creation
* Available in the DataBrain dashboard when viewing embed configurations
The unique identifier of the metric to query.
* Available in the metric URL: `/metric/{metricId}`
* Retrieved via the [Fetch Metrics by Embed](/developer-docs/helpers/api-reference/fetch-metrics-by-embed-and-client) API
* Found in the DataBrain dashboard when viewing a metric
Unique identifier for the end user making the query. Used for row-level security and access control.
* Should match the clientId used in guest token generation
* Used for applying row-level security filters
* Consistent across user sessions
* Enables multi-tenant data isolation
Dashboard-level filters to apply to the metric query. These filters affect the entire dashboard context.
```json theme={"dark"}
{
"date_range": {
"start": "2024-01-01",
"end": "2024-01-31"
},
"region": "north-america",
"product_category": "electronics"
}
```
Metric-specific filters to apply to the query. Used for row-level security and additional filtering.
```json theme={"dark"}
{
"customer_segment": "enterprise",
"product_category": "software",
"status": "active"
}
```
Optional string. Use when the dashboard’s workspace is configured for **multiple datasources** (`MULTI_DATASOURCE`): pass the datasource **name** (as in Data Studio / your integration credentials) so the query runs against that datasource. If the name does not resolve, the API returns `DATASOURCE_NAME_ERROR` (400).
* Not used for multi-datamart workspaces; use `dataMartName` instead when applicable
* For workspaces that are not multi-datasource, omit this field unless your integration already relies on it
Optional string. Use the exact JSON property name **`dataMartName`** (camelCase with a capital **M** in `Mart`).
When the dashboard’s workspace is configured for **multiple datamarts** (`MULTI_DATAMART`), pass the datamart **name** so the query resolves that datamart’s linked datasource. Names follow the same rules as in the [List Datamarts](/developer-docs/helpers/api-reference/list-datamarts) API. If the name does not resolve, the API returns `DATAMART_NAME_ERROR` (400).
* Not used for multi-datasource workspaces; use `datasourceName` instead when applicable
* Distinct from workspace create/update body field `datamartName` (different casing for this endpoint)
## Response
Array of objects containing the query results. Each object represents a row of data with column names as keys.
```json Example theme={"dark"}
[
{
"date": "2024-01-01",
"revenue": 15000,
"region": "north-america"
},
{
"date": "2024-01-02",
"revenue": 18000,
"region": "north-america"
}
]
```
Query execution time in milliseconds.
Comparison value for metrics with comparison enabled.
Total number of records in the result set.
Metadata about the query results.
Array of column information.
Column name.
Data type of the column (e.g., "string", "number", "date").
List of columns used in GROUP BY operations.
The metric ID that was queried (echo of request parameter).
Error object if the request failed, otherwise `null` for successful requests.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/query \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_123",
"metricId": "metric_456",
"clientId": "user_789",
"dashboardFilter": {
"date_range": {
"start": "2024-01-01",
"end": "2024-01-31"
}
},
"metricFilter": {
"region": "north-america"
}
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/query', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId: 'embed_123',
metricId: 'metric_456',
clientId: 'user_789',
dashboardFilter: {
date_range: {
start: '2024-01-01',
end: '2024-01-31'
}
},
metricFilter: {
region: 'north-america'
}
})
});
const data = await response.json();
console.log('Query results:', data.data.length, 'rows');
console.log('Time taken:', data.timeTaken, 'ms');
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
import json
url = "https://api.usedatabrain.com/api/v2/data-app/query"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
payload = {
"embedId": "embed_123",
"metricId": "metric_456",
"clientId": "user_789",
"dashboardFilter": {
"date_range": {
"start": "2024-01-01",
"end": "2024-01-31"
}
},
"metricFilter": {
"region": "north-america"
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
data = response.json()
print(f"Query results: {len(data['data'])} rows")
print(f"Time taken: {data['timeTaken']} ms")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/query')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
embedId: 'embed_123',
metricId: 'metric_456',
clientId: 'user_789',
dashboardFilter: {
date_range: {
start: '2024-01-01',
end: '2024-01-31'
}
},
metricFilter: {
region: 'north-america'
}
}.to_json
response = http.request(request)
data = JSON.parse(response.body)
puts "Query results: #{data['data'].length} rows"
puts "Time taken: #{data['timeTaken']} ms"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.HashMap;
public class DataBrainQueryAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
Map dashboardFilter = new HashMap<>();
Map dateRange = new HashMap<>();
dateRange.put("start", "2024-01-01");
dateRange.put("end", "2024-01-31");
dashboardFilter.put("date_range", dateRange);
Map metricFilter = new HashMap<>();
metricFilter.put("region", "north-america");
Map requestBody = new HashMap<>();
requestBody.put("embedId", "embed_123");
requestBody.put("metricId", "metric_456");
requestBody.put("clientId", "user_789");
requestBody.put("dashboardFilter", dashboardFilter);
requestBody.put("metricFilter", metricFilter);
String jsonBody = mapper.writeValueAsString(requestBody);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/query"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type QueryRequest struct {
EmbedId string `json:"embedId"`
MetricId string `json:"metricId"`
ClientId string `json:"clientId"`
DashboardFilter map[string]interface{} `json:"dashboardFilter,omitempty"`
MetricFilter map[string]interface{} `json:"metricFilter,omitempty"`
}
type QueryResponse struct {
Data []map[string]interface{} `json:"data"`
TimeTaken int `json:"timeTaken"`
TotalRecords int `json:"totalRecords"`
MetaData map[string]interface{} `json:"metaData"`
}
func main() {
reqBody := QueryRequest{
EmbedId: "embed_123",
MetricId: "metric_456",
ClientId: "user_789",
DashboardFilter: map[string]interface{}{
"date_range": map[string]string{
"start": "2024-01-01",
"end": "2024-01-31",
},
},
MetricFilter: map[string]interface{}{
"region": "north-america",
},
}
jsonData, _ := json.Marshal(reqBody)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/data-app/query",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var queryResp QueryResponse
json.NewDecoder(resp.Body).Decode(&queryResp)
fmt.Printf("Query results: %d rows\n", len(queryResp.Data))
fmt.Printf("Time taken: %d ms\n", queryResp.TimeTaken)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'embed_123',
'metricId' => 'metric_456',
'clientId' => 'user_789',
'dashboardFilter' => [
'date_range' => [
'start' => '2024-01-01',
'end' => '2024-01-31'
]
],
'metricFilter' => [
'region' => 'north-america'
]
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Query results: " . count($response['data']) . " rows\n";
echo "Time taken: " . $response['timeTaken'] . " ms\n";
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"date": "2024-01-01",
"revenue": 15000,
"region": "north-america",
"customer_count": 45
},
{
"date": "2024-01-02",
"revenue": 18500,
"region": "north-america",
"customer_count": 52
},
{
"date": "2024-01-03",
"revenue": 16500,
"region": "north-america",
"customer_count": 138
}
],
"timeTaken": 245,
"comparisonValue": 12500,
"totalRecords": 31,
"metaData": {
"columns": [
{
"name": "date",
"dataType": "date"
},
{
"name": "revenue",
"dataType": "number"
},
{
"name": "region",
"dataType": "string"
},
{
"name": "customer_count",
"dataType": "number"
}
],
"groupbyColumnList": ["date", "region"]
},
"metricid": "metric_456",
"error": null
}
```
```json Empty Results Response theme={"dark"}
{
"data": [],
"timeTaken": 45,
"totalRecords": 0,
"metaData": {
"columns": [],
"groupbyColumnList": []
},
"metricid": "metric_456",
"error": null
}
```
```json Error Response (401) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Invalid or missing Data App API Key"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_EMBED_ID",
"message": "Embed ID not found or access denied",
"status": 400
}
}
```
```json Error Response (404) theme={"dark"}
{
"error": {
"code": "EMBED_PARAM_ERROR",
"message": "Embed ID not found or mismatched with API Key"
}
}
```
## Error Codes
**Invalid embed ID** - The specified embed ID doesn't exist or you don't have access
**Invalid metric ID** - The specified metric ID doesn't exist or isn't associated with the embed
**Missing or invalid data app** - Check your API key and data app configuration
**Embed ID error** - The embed ID was not found or doesn't match the API key being used
**Metric not found** - The specified metric ID doesn't exist or isn't associated with the embed configuration
**Invalid datasource name** - The specified datasource name could not be resolved for a multi-datasource workspace
**Invalid datamart name** - The specified `dataMartName` could not be resolved for a multi-datamart workspace
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ----------------------------------------------------------------------- |
| `200` | **OK** - Query executed successfully |
| `400` | **Bad Request** - Invalid request parameters or missing required fields |
| `401` | **Unauthorized** - Invalid or expired API token |
| `404` | **Not Found** - Embed ID or metric ID not found |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - Unexpected server error |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------ |
| `INVALID_EMBED_ID` | 400 | Embed ID not found |
| `INVALID_METRIC_ID` | 400 | Invalid metric ID |
| `INVALID_DATA_APP_API_KEY` | 401 | Missing or invalid data app |
| `EMBED_PARAM_ERROR` | 404 | Embed ID error |
| `METRIC_NOT_FOUND` | 404 | Metric not found |
| `DATASOURCE_NAME_ERROR` | 400 | Invalid datasource name (multi-datasource) |
| `DATAMART_NAME_ERROR` | 400 | Invalid datamart name (multi-datamart) |
| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests |
| `INTERNAL_SERVER_ERROR` | 500 | Unexpected failure |
## Filtering Guide
### Dashboard Filters
Dashboard filters apply to the entire dashboard context and affect all metrics. Common use cases include:
* **Date range filtering**: Limit data to specific time periods
* **Category filtering**: Filter by region, department, product line, etc.
* **Global parameters**: Set values that affect multiple metrics
```json Example theme={"dark"}
{
"dashboardFilter": {
"date_range": {
"start": "2024-01-01",
"end": "2024-03-31"
},
"region": "north-america",
"product_category": "electronics"
}
}
```
### Metric Filters
Metric filters apply specifically to the metric being queried and can be used for:
* **Row-level security (RLS)**: Restrict data based on client permissions
* **Additional filtering**: Apply metric-specific conditions
* **Client isolation**: Ensure multi-tenant data separation
```json Example theme={"dark"}
{
"metricFilter": {
"department": "sales",
"status": "active",
"client_group": "enterprise"
}
}
```
## Use Cases
### Export Dashboard Data
```javascript theme={"dark"}
async function exportDashboardData(embedId, clientId) {
// Get all metrics
const metricsResponse = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/metrics?embedId=${embedId}&clientId=${clientId}`,
{
headers: { 'Authorization': 'Bearer dbn_live_...' }
}
);
const { data: metrics } = await metricsResponse.json();
// Query each metric
const allData = {};
for (const metric of metrics) {
const queryResponse = await fetch(
'https://api.usedatabrain.com/api/v2/data-app/query',
{
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId,
metricId: metric.metricId,
clientId
})
}
);
const queryResult = await queryResponse.json();
allData[metric.name] = queryResult.data;
}
return allData;
}
```
### Real-time Data Refresh
```javascript theme={"dark"}
async function refreshMetricData(embedId, metricId, clientId, filters) {
const response = await fetch(
'https://api.usedatabrain.com/api/v2/data-app/query',
{
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId,
metricId,
clientId,
dashboardFilter: filters
})
}
);
return await response.json();
}
// Refresh every 5 minutes
setInterval(async () => {
const data = await refreshMetricData(
'embed_123',
'metric_456',
'user_789',
{ date_range: { start: 'today', end: 'today' } }
);
updateDashboard(data);
}, 5 * 60 * 1000);
```
### Multi-Tenant Data Access
```javascript theme={"dark"}
async function getClientMetricData(embedId, metricId, clientId) {
// Apply client-specific filters automatically
const response = await fetch(
'https://api.usedatabrain.com/api/v2/data-app/query',
{
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId,
metricId,
clientId,
metricFilter: {
// RLS ensures clients only see their data
client_id: clientId
}
})
}
);
return await response.json();
}
```
## Best Practices
1. **Cache responses** - Cache query results when appropriate to reduce API calls and improve performance
2. **Use filters efficiently** - Apply filters at the query level rather than filtering data client-side
3. **Handle pagination** - For large datasets, implement pagination or limit results
4. **Error handling** - Implement robust error handling and retry logic
5. **Rate limiting** - Respect rate limits and implement exponential backoff
6. **Security** - Never expose API keys in client-side code; proxy requests through your backend
## Performance Tips
* **Minimize filter complexity** - Complex filters can slow down queries
* **Request only needed columns** - If possible, select only required columns
* **Use date ranges** - Limit queries to specific time periods
* **Cache when possible** - Cache frequently accessed data
* **Batch requests** - When querying multiple metrics, consider batching requests
## Quick Start Guide
First, get your embed ID and metric ID from your DataBrain dashboard or via the List APIs:
```bash theme={"dark"}
# List your embeds to find the embedId
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Use the [Fetch Metrics by Embed](/developer-docs/helpers/api-reference/fetch-metrics-by-embed-and-client) endpoint to get a list of available metrics:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/metrics?embedId=embed_123&clientId=user_789' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Query a metric with minimal parameters:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/query \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_123",
"metricId": "metric_456",
"clientId": "user_789"
}'
```
Include filters to narrow down your results:
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/query \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_123",
"metricId": "metric_456",
"clientId": "user_789",
"dashboardFilter": {
"date_range": {
"start": "2024-01-01",
"end": "2024-01-31"
}
}
}'
```
Use the returned data in your application:
```javascript theme={"dark"}
const queryData = await queryMetric({
embedId: 'embed_123',
metricId: 'metric_456',
clientId: 'user_789'
});
console.log(`Found ${queryData.totalRecords} records`);
console.log(`Query took ${queryData.timeTaken}ms`);
queryData.data.forEach(row => {
// Process each data row
console.log(row);
});
```
## Next Steps
Get a list of available metrics before querying
Retrieve available dashboards in your data app
Set up embed configurations for your data app
Generate secure tokens for embedded access
# Fetch Metrics by Embed and Client
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/fetch-metrics-by-embed-and-client
GET https://api.usedatabrain.com/api/v2/data-app/metrics?embedId={id}&clientId={client_xyz789}&isPagination=true&pageNumber=1
Retrieve metrics available for a specific embed configuration and client, with support for pagination and client-specific filtering.
Get a list of metrics that are accessible through a specific embed configuration for a particular client. This endpoint is essential for understanding what metrics are available for querying within an embedded dashboard context.
This endpoint returns metrics filtered by client access. Client-created metrics are only visible to the specific client that created them, while shared metrics are visible to all clients.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/metrics \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The embed configuration ID to fetch metrics for. This identifies which embedded dashboard's metrics you want to retrieve.
* Created when you configure an embed via the [Create Embed API](/developer-docs/helpers/api-reference/create-embed)
* Retrieved via the [List Embeds API](/developer-docs/helpers/api-reference/list-embed)
* Available in your DataBrain dashboard embed settings
The client identifier for filtering metrics. Determines which metrics the client has access to based on their permissions and ownership.
Enable pagination to limit the number of results returned. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number for pagination (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
When set to `"true"`, returns only the list of metrics — excluding elements and summaries. Pass `"false"` or omit this parameter to return all items, including non-metric components.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Filter metrics by the user identifier who created them. When provided, only returns metrics created by the specified user.
* When `userIdentifier` is provided: Returns only metrics where `createdByIdentifier` matches
* When omitted: Returns all metrics the client has access to
* System-created metrics (no creator) are excluded when filtering by user
* Useful for showing "My Metrics" views in your application
## Response
Array of metric objects available for the specified embed and client.
Display name of the metric.
Unique identifier for the metric that can be used in query operations.
Indicates whether the metric is published and visible to end users.
* `true`: Metric is published and visible
* `false`: Metric is unpublished (hidden but not deleted)
* System-created metrics (without a creator) are always `true`
The identifier of the user who created this metric, or `null` for system-created metrics.
* Non-null value: Indicates a user-created metric with the creator's identifier
* `null`: Indicates a system-created or admin-created metric
* Useful for implementing "My Metrics" filtering and ownership displays
Error object returned only when the request fails. Not present in successful responses.
Machine-readable error code for programmatic handling.
Human-readable error message explaining what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/metrics?embedId=embed_abc123&clientId=client_xyz789&isPagination=true&pageNumber=1&isMetric=true' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js theme={"dark"}
const params = new URLSearchParams({
embedId: 'embed_abc123',
clientId: 'client_xyz789',
isPagination: 'true',
pageNumber: '1',
isMetric: 'true'
});
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/metrics?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Available metrics:', data.data);
```
```python Python theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/metrics"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"embedId": "embed_abc123",
"clientId": "client_xyz789",
"isPagination": "true",
"pageNumber": "1",
"isMetric": "true"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Available metrics: {data['data']}")
```
```ruby Ruby theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/metrics')
params = {
embedId: 'embed_abc123',
clientId: 'client_xyz789',
isPagination: 'true',
pageNumber: '1',
isMetric: 'true'
}
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Available metrics: #{data['data']}"
```
```java Java theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainMetricsAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String url = "https://api.usedatabrain.com/api/v2/data-app/metrics" +
"?embedId=embed_abc123&clientId=client_xyz789&isPagination=true&pageNumber=1&isMetric=true";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Metric struct {
Name string `json:"name"`
MetricID string `json:"metricId"`
IsPublished bool `json:"isPublished"`
CreatedByUser *string `json:"createdByUser"`
}
type MetricResponse struct {
Data []Metric `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/metrics"
params := url.Values{}
params.Add("embedId", "embed_abc123")
params.Add("clientId", "client_xyz789")
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
params.Add("isMetric", "true")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var metricResp MetricResponse
json.NewDecoder(resp.Body).Decode(&metricResp)
fmt.Printf("Available metrics: %+v\n", metricResp.Data)
}
```
```php PHP theme={"dark"}
'embed_abc123',
'clientId' => 'client_xyz789',
'isPagination' => 'true',
'pageNumber' => '1',
'isMetric' => 'true'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/metrics?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Available metrics: " . print_r($response['data'], true);
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"name": "Total Revenue",
"metricId": "metric_revenue_123",
"isPublished": true,
"createdByUser": null
},
{
"name": "Active Users",
"metricId": "metric_users_456",
"isPublished": true,
"createdByUser": "user_abc123"
},
{
"name": "Conversion Rate",
"metricId": "metric_conversion_789",
"isPublished": false,
"createdByUser": "user_abc123"
}
]
}
```
```json Empty Results Response theme={"dark"}
{
"data": []
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "EMBED_PARAM_ERROR",
"message": "invalid embed id, embed id not found for given data app"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"embedId\" is required"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------- |
| `200` | **OK** - Metrics retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters, missing required fields, invalid API key, or embed ID not found |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------------------------- |
| `INVALID_DATA_APP_API_KEY` | 400 | Invalid or expired API key |
| `EMBED_PARAM_ERROR` | 400 | Embed ID not found for data app |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid required parameters |
## Client Access Control
### Metric Visibility Rules
1. **Shared Metrics**: Available to all clients within the embed
2. **Client-Created Metrics**: Only visible to the client that created them
3. **Access Settings**: Controlled by the embed configuration's access settings
### Understanding Client-Specific Results
The API automatically filters metrics based on the client's access permissions:
```javascript theme={"dark"}
// Client A will see their own metrics + shared metrics
const clientAMetrics = await fetchMetrics('embed_123', 'client_A');
// Client B will see their own metrics + shared metrics (different from Client A)
const clientBMetrics = await fetchMetrics('embed_123', 'client_B');
```
# Fetch Metrics by Workspace
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/fetch-metrics-by-workspace
POST https://api.usedatabrain.com/api/v2/workspace/metrics
Retrieve metrics from a workspace with optional pagination support.
Retrieve metrics available in a workspace. Use this endpoint to discover metrics for provisioning and embedding in your application.
This endpoint operates at the workspace level using a service token. Use the workspace name to scope which metrics are returned. Supports pagination for workspaces with many metrics.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the workspace to fetch metrics from. Must match an existing workspace in your organization.
* Use the [List Workspaces](/developer-docs/helpers/api-reference/list-workspaces) endpoint to see all available workspaces
* Names are case-sensitive
* Must be an exact match
Enable pagination to retrieve metrics in batches of 10.
* `true`: Enable pagination with page-based retrieval (10 items per page)
* `false` (default): Return all metrics in a single response
- Use pagination when you have more than 20 metrics in a workspace
- Improves response times for large datasets
- Each page returns up to 10 metrics
The page number to retrieve when pagination is enabled. Pages are 1-indexed.
**Note:** This parameter is only used when `isPagination` is set to `true`.
## Response
Array of metric objects. Returns empty array if no metrics exist or page number exceeds available pages.
Display name of the metric.
Unique identifier for the metric.
Error object if the request failed, otherwise `null` for successful requests.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - All Metrics theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace/metrics \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "my-workspace"
}'
```
```bash cURL - With Pagination theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/workspace/metrics \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "my-workspace",
"isPagination": true,
"pageNumber": 1
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace/metrics', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
workspaceName: 'my-workspace',
isPagination: true,
pageNumber: 1
})
});
const result = await response.json();
console.log('Metrics:', result.data);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/workspace/metrics',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'workspaceName': 'my-workspace',
'isPagination': True,
'pageNumber': 1
}
)
result = response.json()
print(f"Metrics: {result['data']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/workspace/metrics')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
workspaceName: 'my-workspace',
isPagination: true,
pageNumber: 1
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Metrics: #{result['data']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class FetchMetrics {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"workspaceName": "my-workspace",
"isPagination": true,
"pageNumber": 1
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/workspace/metrics"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type MetricsRequest struct {
WorkspaceName string `json:"workspaceName"`
IsPagination bool `json:"isPagination,omitempty"`
PageNumber int `json:"pageNumber,omitempty"`
}
func main() {
reqData := MetricsRequest{
WorkspaceName: "my-workspace",
IsPagination: true,
PageNumber: 1,
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("POST",
"https://api.usedatabrain.com/api/v2/workspace/metrics",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'my-workspace',
'isPagination' => true,
'pageNumber' => 1
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
print_r($result['data']);
?>
```
```json 200 - Success theme={"dark"}
{
"data": [
{
"name": "Monthly Revenue",
"metricId": "metric_abc123"
},
{
"name": "Active Users",
"metricId": "metric_def456"
}
],
"error": null
}
```
```json 200 - Empty Results theme={"dark"}
{
"data": [],
"error": null
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"workspaceName\" is required"
}
}
```
```json 400 - Workspace Not Found theme={"dark"}
{
"error": {
"code": "WORKSPACE_ID_ERROR",
"message": "The workspace name provided does not exist"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "API Key is not provided or Invalid!"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Metrics retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------ |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid request body parameters |
| `WORKSPACE_ID_ERROR` | 400 | Workspace name does not exist |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid or expired API key |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Next Steps
Retrieve dashboards from a workspace
List all workspaces in your organization
Create a new workspace for your analytics environment
Generate secure tokens for embedded access
# Get AWSS3 sync Progress status
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/get-awss3-sync-progress-status
POST https://api.usedatabrain.com/api/v2/datasource/getDatasourceProgress
## Endpoint:
```bash theme={"dark"}
POST /datasource/getDatasourceProgress
```
## Headers
Bearer [API TOKEN](https://docs.usedatabrain.com/developer-docs/helpers/api-token)
## Request Body
Input object containing the datasource configuration.
The unique identifier of the datasource to check sync progress for.
## Request Example
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource/getDatasourceProgress \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"input": {
"datasourceId": "your-datasource-id"
}
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/datasource/getDatasourceProgress', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
input: {
datasourceId: 'your-datasource-id'
}
})
});
const data = await response.json();
console.log('Progress:', data.status.progress);
console.log('Error:', data.status.error);
```
```python Python theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/datasource/getDatasourceProgress',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'input': {
'datasourceId': 'your-datasource-id'
}
}
)
data = response.json()
print(f"Progress: {data['status']['progress']}")
print(f"Error: {data['status']['error']}")
```
## Response Body
```json theme={"dark"}
{
"status": {
"progress": "16/16",
"error": ""
}
}
```
### Response Body:
Below is a response when no sync is completed for AWSS3:
```json theme={"dark"}
{
"status": {
"progress": "0/...",
"error": ""
}
}
```
### Response Error:
Below is a response error when while syncing AWSS3 throws an error:
```json theme={"dark"}
{
"status": {
"progress": "0/...",
"error": "Error: Bind error data type"
}
}
```
## Error Codes
* **INVALID\_REQUEST\_BODY**: The request body is invalid.
* **DATASOURCE\_ID\_ERROR**: The datasource ID provided does not exist or is invalid.
# Get Semantic Layer
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/get-semantic-layer
GET https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer
Retrieve the semantic layer configuration for a datamart, including table descriptions, column metadata, and completion score.
Retrieve the full semantic layer for a given datamart. The response includes table and column metadata (descriptions, synonyms, column types), feedback text, a completion score, and the last-updated timestamp.
This endpoint returns data for datamarts that exist in your organization — even if no semantic layer has been configured yet. In that case, tables are returned with `null`/empty semantic fields.
## Authentication
This endpoint requires a **service token** in the Authorization header. Data app API tokens are not permitted and will be rejected with a `403` error.
To access your service token:
1. Go to your Databrain dashboard and open **Settings**.
2. Navigate to **Settings**.
3. Find the **Service Tokens** section.
4. Click the **"Generate Token"** button to generate a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The name of the datamart whose semantic layer you want to retrieve. Must match an existing datamart in your organization.
* Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to get all datamart names
* Names are case-sensitive and must match exactly
## Response
The semantic layer data for the requested datamart.
Name of the datamart.
Array of table objects with semantic metadata.
Table name from the datasource.
Schema name, or `null` if not set.
Human-readable description of the table.
Alternative names for the table. Empty array if none set.
Additional context for AI query generation.
Array of column objects with semantic metadata.
Column name from the datasource.
The underlying SQL datatype of the column.
Human-readable description of the column.
Alternative names for the column.
Additional context for AI query generation.
Semantic column type. One of: `String`, `Long String`, `String (Custom)`, `ENUM`, `Mapper`, `Range`, `Expression`, `Identifier`, `Number`, `JSON`.
Stored column-type configuration as saved via the API (object maps for ENUM-like types, `{ lowerLimit, upperLimit }` for Range, strings for Expression/JSON, or `null`).
Whether this column is marked as an identifier.
Whether this column is excluded from AI indexing.
Global feedback text providing context to the AI about this datamart.
A score from 0 to 100 indicating how thoroughly the semantic layer is configured.
ISO 8601 timestamp of the last semantic layer update, or `null` if never updated.
Error object if the request failed, otherwise not present for successful requests.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const datamartName = 'sales-analytics';
const response = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=${encodeURIComponent(datamartName)}`,
{
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
}
);
const result = await response.json();
console.log('Tables:', result.data.tables.length);
console.log('Completion:', result.data.completionScore);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.get(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...'
},
params={
'datamartName': 'sales-analytics'
}
)
result = response.json()
print(f"Tables: {len(result['data']['tables'])}")
print(f"Completion: {result['data']['completionScore']}%")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
params = { datamartName: 'sales-analytics' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Tables: #{result['data']['tables'].length}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class GetSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String datamartName = URLEncoder.encode("sales-analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=%s",
datamartName
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"
params := url.Values{}
params.Add("datamartName", "sales-analytics")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Response: %v\n", result)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Tables: " . count($response['data']['tables']);
?>
```
```json 200 - Success theme={"dark"}
{
"data": {
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"schemaName": "public",
"description": "Customer purchase orders",
"synonyms": ["purchases", "transactions"],
"miscellaneousInfo": null,
"columns": [
{
"name": "order_id",
"datatype": "integer",
"description": "Unique order identifier",
"synonyms": ["id", "order number"],
"miscellaneousInfo": null,
"columnType": "Identifier",
"columnTypeConfig": null,
"isIdentifier": true,
"isNotIndexed": false
},
{
"name": "status",
"datatype": "varchar",
"description": "Current order status",
"synonyms": ["order status", "state"],
"miscellaneousInfo": null,
"columnType": "ENUM",
"columnTypeConfig": null,
"isIdentifier": false,
"isNotIndexed": false
},
{
"name": "amount",
"datatype": "numeric",
"description": "Total order amount in USD",
"synonyms": ["total", "price"],
"miscellaneousInfo": null,
"columnType": "Number",
"columnTypeConfig": null,
"isIdentifier": false,
"isNotIndexed": false
}
]
}
],
"feedback": "This datamart covers e-commerce sales data. Amounts are in USD.",
"completionScore": 75,
"lastUpdated": "2026-03-15T10:30:00.000Z"
}
}
```
```json 200 - No Semantic Data theme={"dark"}
{
"data": {
"datamartName": "raw-datamart",
"tables": [
{
"name": "events",
"schemaName": "public",
"description": null,
"synonyms": [],
"miscellaneousInfo": null,
"columns": [
{
"name": "event_id",
"datatype": "integer",
"description": null,
"synonyms": [],
"miscellaneousInfo": null,
"columnType": null,
"columnTypeConfig": null,
"isIdentifier": false,
"isNotIndexed": false
}
]
}
],
"feedback": null,
"completionScore": 0,
"lastUpdated": null
}
}
```
```json 400 - Missing datamartName theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART",
"message": "datamartName query parameter is required"
}
}
```
```json 400 - Datamart Not Found theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART",
"message": "Datamart 'nonexistent' not found"
}
}
```
```json 403 - Data App Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------ |
| `200` | **OK** — Semantic layer retrieved successfully |
| `400` | **Bad Request** — Missing or invalid datamartName |
| `401` | **Unauthorized** — Invalid or missing API token |
| `403` | **Forbidden** — Data app token used instead of service token |
| `500` | **Internal Server Error** — Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | ------------------------------------------------- |
| `INVALID_DATAMART` | 400 | datamartName is missing or datamart doesn't exist |
| `AUTHENTICATION_ERROR` | 403 | Data app token used instead of service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Next Steps
Add semantic metadata to your datamart
Modify existing semantic layer metadata
Learn how to configure the semantic layer in the UI
Find datamart names in your organization
# Import Dashboard
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/import-dashboard
POST https://api.usedatabrain.com/api/v2/data-app/import-dashboard
Import a dashboard from a previously exported JSON payload into a workspace.
Import a dashboard into a workspace using JSON data from the [Export Dashboard API](/developer-docs/helpers/api-reference/export-dashboard) or from a file exported via the Databrain UI. The dashboard layout, metrics, and filters are recreated in the target workspace.
**Authentication Requirement:** This endpoint requires a **service token** (company-level), not a data app API key. The workspace must belong to your company.
## Authentication
Use your service token in the `Authorization` header. See [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) for how to obtain a service token.
```bash Authentication theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/import-dashboard \
--header 'Authorization: Bearer YOUR_SERVICE_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"workspaceName":"Target Workspace","importDashboardData":{...}}'
```
## Headers
Bearer token for API authentication. Use your **service token** (company-level).
```
Authorization: Bearer dbn_live_...
```
Must be `application/json`.
```
Content-Type: application/json
```
## Request Body
Validated with **`importDashboardSchema`**: **`workspaceName`** (string, required) and **`importDashboardData`** (object, required) are required. **`dashboardId`**, **`dashboardName`**, and **`schemaPairs`** are optional. Each **`schemaPairs`** item must include **`replaceSchema`** and **`targetSchema`** (strings).
The name of the workspace where the dashboard should be imported. Must match an existing workspace name in your company.
The dashboard payload to import. Must be a non-null object. Use the `data` property from an [Export Dashboard](/developer-docs/helpers/api-reference/export-dashboard) response, or the equivalent structure from a UI-exported JSON file. Contains layout, filters, metrics configuration, and related dashboard structure.
* From **Export Dashboard API**: use the `data` property of the exported JSON.
* From **UI export file**: use the `data` property from the downloaded JSON file.
Optional stable identifier for the imported dashboard in the target workspace.
* If provided, this value is used as the external dashboard ID.
* If omitted, a new unique ID is generated automatically.
* If a dashboard with the same ID already exists in the target workspace, the import returns an error message and no new dashboard is created.
Optional display name to assign to the imported dashboard in the target workspace.
If omitted, the name from the exported payload is used.
Optional. Maps schema names in the exported SQL/dashboard payload to schema names in the target workspace (for example when moving from staging to production).
Each array element is an object with:
* **`replaceSchema`** — string (required in each item)
* **`targetSchema`** — string (required in each item)
```json theme={"dark"}
"schemaPairs": [
{ "replaceSchema": "databrain_dev1", "targetSchema": "databrain_dev2" }
]
```
## Response
Result of the import operation.
On success, `data.response` contains:
* `message` – human-readable summary of the import (including the number of imported metrics)
* `dashboardId` – external dashboard ID in the target workspace
* `dashboardName` – name of the imported dashboard in the target workspace
* `workspaceName` – name of the workspace where the dashboard was imported
On error, the API returns a JSON object with `error.code` and `error.message` and HTTP status 400 or 500.
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url 'https://api.usedatabrain.com/api/v2/data-app/import-dashboard' \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "Target Workspace",
"importDashboardData": {
"layout": [],
"filters": [],
"gridMargin": {}
},
"dashboardId": "sales-dashboard-1-copy",
"dashboardName": "Sales Dashboard (Copy)",
"schemaPairs": [
{ "replaceSchema": "source_schema", "targetSchema": "public" }
]
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
// Assume exportedJson is the object from Export Dashboard API or from reading the exported file
const exportedJson = { _meta: {...}, data: {...} };
const importDashboardData = exportedJson.data || exportedJson;
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/import-dashboard', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
workspaceName: 'Target Workspace',
importDashboardData,
dashboardId: 'sales-dashboard-1-copy',
dashboardName: 'Sales Dashboard (Copy)',
schemaPairs: [
{ replaceSchema: 'source_schema', targetSchema: 'public' }
]
})
});
const result = await response.json();
if (result.error) {
throw new Error(result.error.message);
}
console.log('Imported:', result.data);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/import-dashboard"
headers = {
"Authorization": "Bearer dbn_live_...",
"Content-Type": "application/json"
}
# Use the "data" part of an exported dashboard JSON
payload = {
"workspaceName": "Target Workspace",
"importDashboardData": {
"layout": [],
"filters": [],
"gridMargin": {}
},
"dashboardId": "sales-dashboard-1-copy",
"dashboardName": "Sales Dashboard (Copy)",
"schemaPairs": [
{"replaceSchema": "source_schema", "targetSchema": "public"}
]
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if "error" in data:
raise Exception(data["error"].get("message", "Import failed"))
print("Imported:", data.get("data"))
```
```json Success Response theme={"dark"}
{
"data": {
"response": {
"message": "Imported Dashboard with 10 metrics",
"dashboardId": "sales-dashboard-1-copy",
"dashboardName": "Sales Dashboard (Copy)",
"workspaceName": "Target Workspace"
}
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"workspaceName\" is required"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "WORKSPACE_ID_ERROR",
"message": "invalid workspace name, workspace name not found"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | -------------------------------------------------------------------------------------- |
| `200` | **OK** – Dashboard imported successfully |
| `400` | **Bad Request** – Invalid or missing parameters, invalid token, or workspace not found |
| `500` | **Internal Server Error** – Server error during import |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | --------------------------------------------------------------------------------------- | ----------- |
| `INVALID_REQUEST_BODY` | Joi validation message (e.g. `"workspaceName" is required`, invalid `schemaPairs` item) | 400 |
| `AUTHENTICATION_ERROR` | Invalid Service Token (e.g. missing/invalid company context on token) | 400 |
| `WORKSPACE_ID_ERROR` | invalid workspace name, workspace name not found | 400 |
| `INTERNAL_SERVER_ERROR` | Server error message | 500 |
## Related
* [Export Dashboard](/developer-docs/helpers/api-reference/export-dashboard) – Export a dashboard to get the payload for import
* [Import/Export Dashboard (UI)](/guides/dashboards/import-export-dashboard) – UI guide for import/export
# List API Tokens for Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-api-tokens
GET https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName={name}
Retrieve a list of all API tokens associated with a specific Data App.
Get a list of all API tokens for a specific Data App. This is useful for managing and auditing API tokens associated with your Data Apps.
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage API tokens across your organization.
## Endpoint Formats
```
GET https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName={name}
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
GET https://api.usedatabrain.com/api/v2/dataApp/api-tokens?dataAppName={name}
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
## Query Parameters
The name of the Data App to list API tokens for. This must exactly match an existing Data App name.
* Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to get all Data App names
* Check your Databrain dashboard for Data App configurations
* The name is case-sensitive
Whether to paginate results. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number to retrieve (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
## Response
Array of API token objects with their metadata.
The API key value (UUID). Use this key for authentication when making API requests.
The descriptive name/label assigned to the API token when it was created.
The description of the API token, typically indicating the Data App it belongs to.
ISO 8601 formatted timestamp indicating when the API token was created.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Get All Tokens theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName=Customer%20Portal%20Analytics' \
--header 'Authorization: Bearer service_token_xyz...'
```
```bash cURL - With Pagination theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName=Customer%20Portal%20Analytics&isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer service_token_xyz...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const dataAppName = 'Customer Portal Analytics';
const params = new URLSearchParams({
dataAppName: dataAppName,
isPagination: 'true',
pageNumber: '1'
});
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/api-tokens?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer service_token_xyz...'
}
});
const data = await response.json();
console.log('Found API Tokens:', data.data.length);
data.data.forEach(token => {
console.log(`- ${token.name} (created: ${token.createdAt})`);
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/api-tokens"
headers = {
"Authorization": "Bearer service_token_xyz..."
}
params = {
"dataAppName": "Customer Portal Analytics",
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Found API Tokens: {len(data['data'])}")
for token in data['data']:
print(f"- {token['name']} (created: {token['createdAt']})")
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class ListApiTokens {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String dataAppName = URLEncoder.encode("Customer Portal Analytics", StandardCharsets.UTF_8);
String url = String.format(
"https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName=%s&isPagination=true&pageNumber=1",
dataAppName
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer service_token_xyz...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type ApiToken struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
CreatedAt string `json:"createdAt"`
}
type ListApiTokensResponse struct {
Data []ApiToken `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/api-tokens"
params := url.Values{}
params.Add("dataAppName", "Customer Portal Analytics")
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer service_token_xyz...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result ListApiTokensResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Found API Tokens: %d\n", len(result.Data))
for _, token := range result.Data {
fmt.Printf("- %s (created: %s)\n", token.Name, token.CreatedAt)
}
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Customer Portal Analytics',
'isPagination' => 'true',
'pageNumber' => '1'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/api-tokens?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer service_token_xyz...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Found API Tokens: " . count($response['data']) . "\n";
foreach ($response['data'] as $token) {
echo "- " . $token['name'] . " (created: " . $token['createdAt'] . ")\n";
}
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/api-tokens')
params = {
dataAppName: 'Customer Portal Analytics',
isPagination: 'true',
pageNumber: '1'
}
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Found API Tokens: #{result['data'].length}"
result['data'].each do |token|
puts "- #{token['name']} (created: #{token['createdAt']})"
end
```
```json 200 - Success theme={"dark"}
{
"data": [
{
"key": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Key",
"description": "API key for data app Customer Portal Analytics",
"createdAt": "2024-01-15T10:30:00Z"
},
{
"key": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Development Token",
"description": "API key for data app Customer Portal Analytics",
"createdAt": "2024-01-10T14:15:00Z"
},
{
"key": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"name": "Staging Environment",
"description": "API key for data app Customer Portal Analytics",
"createdAt": "2024-01-08T09:00:00Z"
}
]
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"dataAppName\" is required"
}
}
```
```json 400 - Data App Not Found theme={"dark"}
{
"error": {
"code": "DATA_APP_NOT_FOUND",
"message": "Data app not found"
}
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - API tokens retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | ---------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid dataAppName |
| `DATA_APP_NOT_FOUND` | 400 | Data App with given name not found |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
In **Settings** page, navigate to the **Service Tokens** section. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to find the Data App name:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
Get all API tokens for the Data App:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/api-tokens?dataAppName=My%20Data%20App' \
--header 'Authorization: Bearer service_token_xyz...'
```
Use the token information to manage your API keys:
```javascript theme={"dark"}
const tokens = await listApiTokens({ dataAppName: 'My Data App' });
tokens.data.forEach(token => {
console.log(`Token: ${token.name}`);
console.log(` Key: ${token.key}`);
console.log(` Created: ${token.createdAt}`);
// Check if token is old and might need rotation
const createdDate = new Date(token.createdAt);
const daysSinceCreation = (Date.now() - createdDate) / (1000 * 60 * 60 * 24);
if (daysSinceCreation > 90) {
console.log(` ⚠️ Consider rotating this token (${Math.floor(daysSinceCreation)} days old)`);
}
});
```
## Next Steps
Generate new API tokens for your Data Apps
Rotate API keys for enhanced security
View all Data Apps in your organization
Use your API tokens to create embed configurations
# List Data Apps
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-data-apps
GET https://api.usedatabrain.com/api/v2/data-app
Retrieve a list of all Data Apps in your organization with their embed configurations.
Get a comprehensive list of all Data Apps in your organization, including their embed configurations, creation timestamps, and embed counts.
This endpoint returns all Data Apps of type "embedded" in your organization. Each Data App includes summary information about its associated embeds.
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage Data Apps across your organization.
## Endpoint Formats
```
GET https://api.usedatabrain.com/api/v2/data-app
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
GET https://api.usedatabrain.com/api/v2/dataApp
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
## Query Parameters
Whether to paginate results. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number to retrieve (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
## Response
Array of Data App objects with their configuration details.
The name of the Data App.
The type of the Data App. Currently always `"embedded"`.
ISO 8601 formatted timestamp indicating when the Data App was created.
ISO 8601 formatted timestamp indicating when the Data App was last updated.
The total number of embed configurations associated with this Data App.
Array of embed configurations associated with this Data App.
The name of the embed configuration.
The unique identifier for the embed configuration.
ISO 8601 formatted timestamp indicating when the embed was created.
ISO 8601 formatted timestamp indicating when the embed was last updated.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Get All Data Apps theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
```bash cURL - With Pagination theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer service_token_xyz...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app', {
method: 'GET',
headers: {
'Authorization': 'Bearer service_token_xyz...'
}
});
const data = await response.json();
console.log('Found Data Apps:', data.data.length);
data.data.forEach(app => {
console.log(`- ${app.name} (${app.embedCount} embeds)`);
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app"
headers = {
"Authorization": "Bearer service_token_xyz..."
}
params = {
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Found Data Apps: {len(data['data'])}")
for app in data['data']:
print(f"- {app['name']} ({app['embedCount']} embeds)")
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class ListDataApps {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String url = "https://api.usedatabrain.com/api/v2/data-app" +
"?isPagination=true&pageNumber=1";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer service_token_xyz...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Embed struct {
Name string `json:"name"`
EmbedId string `json:"embedId"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
type DataApp struct {
Name string `json:"name"`
Type string `json:"type"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
EmbedCount int `json:"embedCount"`
Embeds []Embed `json:"embeds"`
}
type ListDataAppsResponse struct {
Data []DataApp `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app"
params := url.Values{}
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer service_token_xyz...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result ListDataAppsResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Found Data Apps: %d\n", len(result.Data))
for _, app := range result.Data {
fmt.Printf("- %s (%d embeds)\n", app.Name, app.EmbedCount)
}
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'true',
'pageNumber' => '1'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer service_token_xyz...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Found Data Apps: " . count($response['data']) . "\n";
foreach ($response['data'] as $app) {
echo "- " . $app['name'] . " (" . $app['embedCount'] . " embeds)\n";
}
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app')
params = { isPagination: 'true', pageNumber: '1' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Found Data Apps: #{result['data'].length}"
result['data'].each do |app|
puts "- #{app['name']} (#{app['embedCount']} embeds)"
end
```
```json 200 - Success theme={"dark"}
{
"data": [
{
"name": "Customer Portal Analytics",
"type": "embedded",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:45:00Z",
"embedCount": 3,
"embeds": [
{
"name": "Sales Dashboard Embed",
"embedId": "sales-dashboard-123",
"createdAt": "2024-01-15T11:00:00Z",
"updatedAt": "2024-01-18T09:30:00Z"
},
{
"name": "Revenue Metrics Embed",
"embedId": "revenue-metrics-456",
"createdAt": "2024-01-16T14:15:00Z",
"updatedAt": "2024-01-19T16:00:00Z"
},
{
"name": "Customer Overview",
"embedId": "customer-overview-789",
"createdAt": "2024-01-17T08:45:00Z",
"updatedAt": "2024-01-20T11:20:00Z"
}
]
},
{
"name": "Partner Dashboard",
"type": "embedded",
"createdAt": "2024-01-10T09:00:00Z",
"updatedAt": "2024-01-15T12:30:00Z",
"embedCount": 1,
"embeds": [
{
"name": "Partner Analytics",
"embedId": "partner-analytics-001",
"createdAt": "2024-01-10T10:00:00Z",
"updatedAt": "2024-01-15T12:30:00Z"
}
]
}
]
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Data Apps retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | -------------------------------- |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
In **Settings** page, navigate to the **Service Tokens** section. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Make a GET request to retrieve all Data Apps:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
If you have many Data Apps, use pagination:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer service_token_xyz...'
```
Use the response to manage your Data Apps:
```javascript theme={"dark"}
const dataApps = await listDataApps();
dataApps.data.forEach(app => {
console.log(`Data App: ${app.name}`);
console.log(` Type: ${app.type}`);
console.log(` Embeds: ${app.embedCount}`);
console.log(` Created: ${app.createdAt}`);
app.embeds.forEach(embed => {
console.log(` - ${embed.name} (${embed.embedId})`);
});
});
```
## Next Steps
Create new Data Apps for your organization
Remove Data Apps you no longer need
Generate API tokens for your Data Apps
View API tokens for a specific Data App
# List Datamarts
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-datamarts
GET https://api.usedatabrain.com/api/v2/data-app/datamarts
Retrieve a list of all datamarts in your data app with their configurations and access settings.
Get a comprehensive list of all datamarts in your data app, including their configurations, datasources, and access settings. Useful for managing and auditing your data organization.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/datamarts`. The old endpoint `/api/v2/dataApp/datamarts` will be deprecated soon. Please update your integrations to use the new endpoint format.
This endpoint returns all datamarts you have access to within the authenticated data app. The response includes metadata and access permissions for each datamart.
Use the **`expandDetails`** parameter when you only need names and organization metadata and want a smaller payload: when `expandDetails` is `false`, **`datamartTables`** and **`datamartRelationships`** are omitted from each item (see [Query Parameters](#query-parameters)).
## Endpoint Formats
```
GET https://api.usedatabrain.com/api/v2/data-app/datamarts
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/datamart/list
Content-Type: application/json
{
"isPagination": true,
"pageNumber": 1,
"expandDetails": false
}
```
This endpoint still works but will be deprecated. **Content-Type:** `application/json`. The same **`getDatamartListSchema`** rules apply: optional **`isPagination`** (boolean), **`pageNumber`** (number), **`expandDetails`** (boolean).
Send **`isPagination`** and **`pageNumber`** as JSON boolean and number — string values (for example `"true"`) usually fail Joi validation. For **`expandDetails`**, the route normalizes the body value before validation (booleans or string forms such as `"true"` / `"false"`); if **`expandDetails`** is omitted, **`getDatamartList`** defaults to expanded details, same as GET when the query parameter is omitted. Set it to `false` to omit **`datamartTables`** and **`datamartRelationships`** from each datamart.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
```bash Authentication theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
Enable pagination for the results. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"` (not boolean values).
Page number to retrieve (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`, `"3"`).
**GET only** (query string). Controls whether each datamart includes **`datamartTables`** (with **`datamartTableColumns`**) and **`datamartRelationships`** in the response.
* If the **`expandDetails`** query parameter is **omitted**, the route passes **`expandDetails: true`** into **`getDatamartList`** (expanded).
* If present, use the strings **`"true"`** or **`"false"`** (the server compares to `'true'`).
When expanded details are **off** (`false`), each item still includes **`name`**, **`createdAt`**, **`updatedAt`**, **`datamartOrganization`**, and **`companyIntegration`**.
**Legacy POST** accepts **`expandDetails`** in the JSON body; the route coerces it to a boolean before **`getDatamartListSchema`** runs (see the Legacy tab). Omit **`expandDetails`** to default to expanded details.
**Note:** On GET, query parameters are strings — use `"true"` or `"false"`, not raw booleans.
**Validation:** **`getDatamartListSchema`** allows optional **`isPagination`** (boolean), **`pageNumber`** (number), and **`expandDetails`** (boolean). On **GET** `/api/v2/data-app/datamarts`, query strings are mapped first: **`isPagination`** is `true` only when equal to **`"true"`**; **`pageNumber`** uses **`parseInt`** when present; **`expandDetails`** defaults to **`true`** when the query parameter is omitted, otherwise it is **`true`** only when the string equals **`"true"`**. On **POST** `/api/v2/dataApp/datamart/list`, **`isPagination`** and **`pageNumber`** are taken from the JSON body as-is; **`expandDetails`** is normalized from the body, then the same schema validates the combined payload inside **`getDatamartList`**.
## Response
The **`datamartTables`** and **`datamartRelationships`** fields documented below are present **only when expanded details are enabled** (`expandDetails` not set to `false`). With `expandDetails=false`, rely on `name`, `createdAt`, `updatedAt`, `datamartOrganization`, and `companyIntegration` only.
Array of datamart objects with their configuration details.
The name of the datamart.
Organization settings for the datamart.
The tenancy level (`TABLE`, `DATABASE`, or `MULTI_DATABASE`).
Schema name for the organization table.
Table name for the organization.
Type of the client column.
Primary database name for `DATABASE` or `MULTI_DATABASE` tenancy. `null` when not set or when tenancy level is `TABLE`.
Column name for client identification.
Primary key column name.
Integration details for the datamart.
Name of the datasource integration.
Array of tables included in the datamart.
Schema name of the table.
Name of the table.
Label for the table providing a human-readable display name. Empty string when not set.
Client/tenant column configured for this table. `null` when not set.
Indicates whether the table is hidden in the datamart UI. Defaults to `false`.
Array of columns in the table.
Name of the column.
Data type of the column.
Alias for the column.
Label for the column providing better readability.
Indicates whether the column is hidden in the datamart UI. Defaults to `false`.
Indicates whether this is a custom/calculated column defined by a SQL expression. `true` when the column was created with `isCustomColumn: true`.
The SQL expression for custom columns. Empty string when `isCustomColumn` is `false`.
Indicates whether timezone conversion is enabled for this column. When `true`, datetime values are converted at query time using the timezone specified in `params.timezone` of the guest token. Defaults to `false`.
Default sort direction configured for the column. Returns `ASC`, `DESC`, or `null` when no default sort is configured.
Array of relationships defined between tables in the datamart. Can be an empty array if no relationships are configured.
Name of the parent table in the relationship.
Column name in the parent table that participates in the relationship.
Name of the child table in the relationship.
Column name in the child table that participates in the relationship.
Descriptive name for the relationship.
The cardinality of the relationship. Can be: `ManyToMany`, `ManyToOne`, `OneToMany`, `OneToOne`, or `null` if not specified.
The type of SQL join used. Can be: `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`, or `null` if not specified.
Error field, null when successful.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL - List without expanded tables & relationships theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts?expandDetails=false&isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1', {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Found datamarts:', data.data.length);
```
```python Python theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/datamarts"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Found datamarts: {len(data['data'])}")
```
```ruby Ruby theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts')
params = { isPagination: 'true', pageNumber: '1' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Found datamarts: #{data['data'].length}"
```
```java Java theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainDatamartAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String url = "https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type DatamartListResponse struct {
Data []interface{} `json:"data"`
}
func main() {
url := "https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var datamartResp DatamartListResponse
json.NewDecoder(resp.Body).Decode(&datamartResp)
fmt.Printf("Found datamarts: %d\n", len(datamartResp.Data))
}
```
```php PHP theme={"dark"}
[
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Found datamarts: " . count($response['data']);
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"name": "sales-analytics",
"datamartOrganization": {
"tenancyLevel": "TABLE",
"primaryDatabase": null,
"schemaName": "public",
"tableName": "organizations",
"clientColumnType": "STRING",
"tableClientNameColumn": "name",
"tablePrimaryKeyColumn": "id"
},
"companyIntegration": {
"name": "postgres-prod"
},
"datamartTables": [
{
"schemaName": "public",
"tableName": "customers",
"label": "Customer Records",
"clientColumn": "id",
"isHide": false,
"datamartTableColumns": [
{
"columnName": "id",
"datatype": "integer",
"alias": "customer_id",
"label": "Customer ID",
"isHide": false,
"isCustomColumn": false,
"sql": "",
"isApplyTimezone": false,
"defaultSort": "ASC"
},
{
"columnName": "name",
"datatype": "varchar",
"alias": "customer_name",
"label": "Customer Name",
"isHide": false,
"isCustomColumn": false,
"sql": "",
"isApplyTimezone": false,
"defaultSort": null
},
{
"columnName": "created_at",
"datatype": "timestamp",
"alias": "created_at",
"label": "Created At",
"isHide": false,
"isCustomColumn": false,
"sql": "",
"isApplyTimezone": true,
"defaultSort": "DESC"
}
]
}
]
}
],
"datamartRelationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}
],
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Missing or invalid data app",
"status": 400
}
}
```
## Error Codes
**Missing or invalid data app** - Check your API key and data app configuration
**Unexpected failure** - Internal server error occurred
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | --------------------------------------------------------------- |
| 200 | **OK** - Request successful |
| 400 | **Bad Request** - Invalid request parameters or missing API key |
| 401 | **Unauthorized** - Invalid or expired API token |
| 500 | **Internal Server Error** - Unexpected server error |
## Possible Errors
| Code | Message | HTTP Status |
| ---------------------------- | --------------------------- | ----------- |
| INVALID\_DATA\_APP\_API\_KEY | Missing or invalid data app | 400 |
| INTERNAL\_SERVER\_ERROR | Unexpected failure | 500 |
## Usage Examples
### Basic Usage
```javascript theme={"dark"}
// Get all datamarts
const datamarts = await listDatamarts();
console.log(`Total datamarts: ${datamarts.data.length}`);
```
### With Pagination
```javascript theme={"dark"}
// Get first page of datamarts
const datamarts = await listDatamarts({
isPagination: true,
pageNumber: 1
});
console.log(`Page 1 datamarts: ${datamarts.data.length}`);
```
### Processing Results
```javascript theme={"dark"}
// Process each datamart
const datamarts = await listDatamarts();
datamarts.data.forEach(datamart => {
console.log(`Datamart: ${datamart.name}`);
console.log(`Tables: ${datamart.datamartTables.length}`);
console.log(`Datasource: ${datamart.companyIntegration.name}`);
});
```
## Best Practices
Use pagination for data apps with many datamarts
Cache datamart lists to reduce API calls
Always handle API errors gracefully
Monitor API usage and response times
## Quick Start Guide
For detailed instructions, see the [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) guide.
Make a simple request to see all your datamarts:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Note: You can add query parameters for pagination if needed.
If you have many datamarts, enable pagination using query parameters:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Use the datamart information for embed configurations:
```javascript theme={"dark"}
const datamarts = await listDatamarts();
datamarts.data.forEach(datamart => {
console.log(`Datamart: ${datamart.name}`);
console.log(`Tables: ${datamart.datamartTables.length}`);
});
```
## Next Steps
Create new datamarts for your data app
Remove datamarts you no longer need
Create embeddable configurations for your datamarts
Generate secure tokens for embedded access
# List Datasources
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-datasources
GET https://api.usedatabrain.com/api/v2/datasource
Retrieve a list of all datasources in your organization. Supports optional pagination for large datasets.
Get a list of all datasources configured in your organization. Useful for managing datasources, verifying configurations, and identifying datasource names for use in other APIs.
This endpoint returns all datasources you have access to within your organization. The response includes only the datasource names for security reasons - full credentials are never returned.
## Endpoint
```
GET https://api.usedatabrain.com/api/v2/datasource
```
## Self-hosted Databrain Endpoint
```
GET /api/v2/datasource
```
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
```bash Authentication theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/datasource?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
Enable pagination for the results. Pass `"true"` to enable pagination with a limit of 10 datasources per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"` (not boolean values).
Page number to retrieve (1-based). Only used when `isPagination` is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`, `"3"`).
* First page is `"1"` (not `"0"`)
* Each page returns up to 10 datasources
* Only effective when `isPagination` is `"true"`
## Response
Array of datasource objects. Each object contains only the datasource name for security reasons.
The name of the datasource. This name can be used in other APIs to reference the datasource.
Error field, null when successful. Not included in successful responses.
## Examples
```bash cURL - Without Pagination theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL - With Pagination theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/datasource?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js theme={"dark"}
// List all datasources
const response = await fetch('https://api.usedatabrain.com/api/v2/datasource', {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
if (data.error) {
console.error('Error:', data.error);
} else {
console.log('Found datasources:', data.data.length);
data.data.forEach(datasource => {
console.log('-', datasource.name);
});
}
```
```javascript Node.js - With Pagination theme={"dark"}
// List datasources with pagination
const pageNumber = 1;
const response = await fetch(
`https://api.usedatabrain.com/api/v2/datasource?isPagination=true&pageNumber=${pageNumber}`,
{
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
}
);
const data = await response.json();
console.log(`Page ${pageNumber} datasources:`, data.data.length);
```
```python Python theme={"dark"}
import requests
# List all datasources
response = requests.get(
'https://api.usedatabrain.com/api/v2/datasource',
headers={
'Authorization': 'Bearer dbn_live_abc123...'
}
)
data = response.json()
if data.get('error'):
print('Error:', data['error'])
else:
print(f'Found {len(data["data"])} datasources:')
for datasource in data['data']:
print(f" - {datasource['name']}")
```
```python Python - With Pagination theme={"dark"}
import requests
# List datasources with pagination
url = "https://api.usedatabrain.com/api/v2/datasource"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Page 1 datasources: {len(data['data'])}")
```
```json Success Response theme={"dark"}
{
"data": [
{
"name": "production-postgres"
},
{
"name": "analytics-snowflake"
},
{
"name": "warehouse-bigquery"
}
]
}
```
```json Success Response - Empty List theme={"dark"}
{
"data": []
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid pagination parameters",
"status": 400
}
}
```
```json Error Response (401) theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "AUTHENTICATION_ERROR",
"status": 401
}
}
```
```json Error Response (500) theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal server error",
"status": 500
}
}
```
## Error Codes
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | -------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Invalid pagination parameters |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error occurred |
## Next Steps
Create new datasources for your organization
Update existing datasource credentials
Remove datasources you no longer need
Sync datasource schema after changes
# List All Embeds
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-embed
GET https://api.usedatabrain.com/api/v2/data-app/embeds
Fetch a list of all embeds created by the authenticated data app.
Get a comprehensive list of all embed configurations created by your data app, including both dashboard and metric embeds with their associated metadata.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/embeds`. The old endpoint `/api/v2/dataApp/embeds` will be deprecated soon. Please update your integrations to use the new endpoint format.
This endpoint returns all embeds you have access to within the authenticated data app. The response includes embed IDs, types, and associated dashboard/metric information.
## Endpoint Formats
```
GET https://api.usedatabrain.com/api/v2/data-app/embeds
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/embed/list
Content-Type: application/json
{
"isPagination": true,
"pageNumber": 1
}
```
This endpoint still works but will be deprecated. Uses POST method with JSON body.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
Whether to paginate results. Pass `"true"` to enable pagination with a limit of 10 per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number to retrieve (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
Optional client ID to filter embeds. When provided, only returns dashboard embeds where the dashboard was created by the specified client.
## Response
Array of embed objects with their configuration details.
Unique identifier for the embed configuration.
Type of embed: "dashboard" or "metric".
The human-readable name of the embed configuration. This is the name set when creating or renaming the embed configuration.
Dashboard information (present when embedType is "dashboard", null otherwise).
Unique identifier for the external dashboard.
Dashboard metadata information.
Name of the dashboard.
Metric information (present when embedType is "metric", null otherwise).
Unique identifier for the external metric.
Name of the metric.
Consolidated metadata object containing key embed information for easy access.
Unique identifier for the embed configuration.
The human-readable name of the embed configuration.
Type of embed: "dashboard" or "metric".
Name of the data app associated with this embed.
Unique identifier for the metric (present when embedType is "metric", null otherwise).
Unique identifier for the dashboard (present when embedType is "dashboard", null otherwise).
ISO 8601 formatted timestamp indicating when the embed configuration was created.
ISO 8601 formatted timestamp indicating when the embed configuration was last updated.
Error field, null when successful. Not included in successful responses.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds?isPagination=true&pageNumber=1', {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Found embeds:', data.data.length);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/embeds"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Found embeds: {len(data['data'])}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/embeds')
params = { isPagination: 'true', pageNumber: '1' }
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Found embeds: #{data['data'].length}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainEmbedAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String url = "https://api.usedatabrain.com/api/v2/data-app/embeds" +
"?isPagination=true&pageNumber=1";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type EmbedListResponse struct {
Data []interface{} `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/embeds"
params := url.Values{}
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var embedResp EmbedListResponse
json.NewDecoder(resp.Body).Decode(&embedResp)
fmt.Printf("Found embeds: %d\n", len(embedResp.Data))
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'true',
'pageNumber' => '1'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/embeds?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Found embeds: " . count($response['data']);
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"embedId": "dashboard-123",
"embedType": "dashboard",
"name": "Sales Dashboard Embed",
"externalDashboard": {
"externalDashboardId": "dashboard-uuid-456",
"metadata": {
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:45:00Z"
},
"name": "Sales Analytics Dashboard"
},
"externalMetric": null,
"embedMetadata": {
"embedId": "dashboard-123",
"name": "Sales Dashboard Embed",
"embedType": "dashboard",
"dataAppName": "Production Data App",
"metricId": null,
"dashboardId": "dashboard-uuid-456",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:45:00Z"
}
},
{
"embedId": "metric-456",
"embedType": "metric",
"name": "Revenue Metric Embed",
"externalDashboard": null,
"externalMetric": {
"metricId": "metric-uuid-789",
"name": "Monthly Revenue"
},
"embedMetadata": {
"embedId": "metric-456",
"name": "Revenue Metric Embed",
"embedType": "metric",
"dataAppName": "Production Data App",
"metricId": "metric-uuid-789",
"dashboardId": null,
"createdAt": "2024-01-16T08:15:00Z",
"updatedAt": "2024-01-18T12:30:00Z"
}
}
],
"error": null
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
## Error Codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | --------------------------- |
| `INVALID_DATA_APP_API_KEY` | 400 | Missing or invalid data app |
| `INTERNAL_SERVER_ERROR` | 500 | Server error occurred |
## Quick Start Guide
For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
Get all your embed configurations:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Note: You can add query parameters for pagination or filtering if needed.
If you have many embed configurations, use pagination with query parameters:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Use the embed information to manage your configurations:
```javascript theme={"dark"}
const embeds = await listEmbeds();
embeds.data.forEach(embed => {
console.log(`Embed ID: ${embed.embedId}`);
console.log(`Embed Name: ${embed.name}`);
console.log(`Type: ${embed.embedType}`);
// Access timestamps and IDs from embedMetadata
console.log(`Created: ${embed.embedMetadata.createdAt}`);
console.log(`Updated: ${embed.embedMetadata.updatedAt}`);
console.log(`Data App: ${embed.embedMetadata.dataAppName}`);
if (embed.embedType === 'dashboard' && embed.externalDashboard) {
console.log(`Dashboard ID: ${embed.externalDashboard.externalDashboardId}`);
console.log(`Dashboard: ${embed.externalDashboard.name}`);
console.log(`Dashboard ID (from metadata): ${embed.embedMetadata.dashboardId}`);
} else if (embed.embedType === 'metric' && embed.externalMetric) {
console.log(`Metric ID: ${embed.externalMetric.metricId}`);
console.log(`Metric: ${embed.externalMetric.name}`);
console.log(`Metric ID (from metadata): ${embed.embedMetadata.metricId}`);
}
});
```
## Next Steps
Learn how to create new embed configurations
Modify existing embed access settings
Remove embed configurations you no longer need
Query data from your embedded metrics
# List Schedule Reports by Embed
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-schedule-reports-by-embed
GET https://api.usedatabrain.com/api/v2/data-app/embeds/reports?embedId={id}&clientId={client_xyz789}&isPagination=true&pageNumber=1
Retrieve scheduled email reports for a specific embed configuration, with support for pagination and filtering by client or user identifier.
Get a list of scheduled email reports associated with a specific embed configuration. This endpoint allows you to retrieve all scheduled reports for an embed, with optional filtering by client ID or user identifier, and supports pagination for large result sets.
This endpoint returns scheduled email reports that have been configured for the specified embed. Reports are filtered based on the embed's data app and can be further filtered by client ID or user identifier.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/embeds/reports \
--header 'Authorization: Bearer dbn_live_...'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
The embed configuration ID to fetch scheduled reports for. This identifies which embedded dashboard's scheduled reports you want to retrieve.
* Created when you configure an embed via the [Create Embed API](/developer-docs/helpers/api-reference/create-embed)
* Retrieved via the [List Embeds API](/developer-docs/helpers/api-reference/list-embed)
* Available in your DataBrain dashboard embed settings
Optional client identifier for filtering reports. When provided, only returns scheduled reports associated with the specified client.
* When `clientId` is provided: Returns only reports configured for that specific client
* When omitted: Returns all scheduled reports for the embed (across all clients)
* Useful for multi-tenant applications where each client has their own scheduled reports
Enable pagination to limit the number of results returned. Pass `"true"` to enable pagination with a limit of 10 reports per page.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"`.
Page number for pagination (1-based). Only used when isPagination is `"true"`. Must be a numeric string (e.g., `"1"`, `"2"`).
**Default:** If pagination is enabled and pageNumber is not provided, defaults to page 1.
Filter reports by the user identifier who created them. When provided, only returns scheduled reports created by the specified user.
* When `userIdentifier` is provided: Returns only reports where `createdByIdentifier` matches
* When omitted: Returns all scheduled reports for the embed (regardless of creator)
* Useful for showing "My Scheduled Reports" views in your application
## Response
Array of scheduled email report objects for the specified embed.
Unique identifier for the scheduled email report.
The subject line of the scheduled email report.
Array of charts/metrics included in this scheduled report.
The unique identifier of the metric included in the report.
Configuration object defining when and how often the report is scheduled to be sent.
Contains scheduling details such as frequency (daily, weekly, monthly), time of day, timezone, and other scheduling parameters.
ISO 8601 timestamp indicating when the scheduled report was created.
ISO 8601 timestamp indicating when the scheduled report was last updated.
The client identifier associated with this scheduled report. This is extracted from the guest token used when creating the report.
The embed configuration ID this scheduled report is associated with.
The identifier of the user who created this scheduled report, or `null` if not specified.
* Non-null value: Indicates a user-created scheduled report with the creator's identifier
* `null`: Indicates a system-created or admin-created scheduled report
Error object returned only when the request fails. Not present in successful responses.
Machine-readable error code for programmatic handling.
Human-readable error message explaining what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/embeds/reports?embedId=embed_abc123&clientId=client_xyz789&isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js theme={"dark"}
const params = new URLSearchParams({
embedId: 'embed_abc123',
clientId: 'client_xyz789',
isPagination: 'true',
pageNumber: '1'
});
const response = await fetch(`https://api.usedatabrain.com/api/v2/data-app/embeds/reports?${params}`, {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const data = await response.json();
console.log('Scheduled reports:', data.data);
```
```python Python theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/dataApp/embeds/reports"
headers = {
"Authorization": "Bearer dbn_live_abc123..."
}
params = {
"embedId": "embed_abc123",
"clientId": "client_xyz789",
"isPagination": "true",
"pageNumber": "1"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(f"Scheduled reports: {data['data']}")
```
```ruby Ruby theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/embeds/reports')
params = {
embedId: 'embed_abc123',
clientId: 'client_xyz789',
isPagination: 'true',
pageNumber: '1'
}
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
data = JSON.parse(response.body)
puts "Scheduled reports: #{data['data']}"
```
```java Java theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class DataBrainScheduleReportsAPI {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String url = "https://api.usedatabrain.com/api/v2/data-app/embeds/reports" +
"?embedId=embed_abc123&clientId=client_xyz789&isPagination=true&pageNumber=1";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type ScheduleReport struct {
Subject string `json:"subject"`
ScheduleEmailReportCharts []struct {
ExternalMetric struct {
MetricID string `json:"metricId"`
} `json:"externalMetric"`
} `json:"scheduleEmailReportCharts"`
TimeConfigurations interface{} `json:"timeConfigurations"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
ClientID string `json:"clientId"`
EmbedID string `json:"embedId"`
CreatedByIdentifier *string `json:"createdByIdentifier"`
}
type ScheduleReportResponse struct {
Data []ScheduleReport `json:"data"`
Error interface{} `json:"error"`
}
func main() {
baseURL := "https://api.usedatabrain.com/api/v2/data-app/embeds/reports"
params := url.Values{}
params.Add("embedId", "embed_abc123")
params.Add("clientId", "client_xyz789")
params.Add("isPagination", "true")
params.Add("pageNumber", "1")
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, _ := http.NewRequest("GET", fullURL, nil)
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var reportResp ScheduleReportResponse
json.NewDecoder(resp.Body).Decode(&reportResp)
fmt.Printf("Scheduled reports: %+v\n", reportResp.Data)
}
```
```php PHP theme={"dark"}
'embed_abc123',
'clientId' => 'client_xyz789',
'isPagination' => 'true',
'pageNumber' => '1'
]);
$url = 'https://api.usedatabrain.com/api/v2/data-app/embeds/reports?' . $params;
$options = [
'http' => [
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
echo "Scheduled reports: " . print_r($response['data'], true);
?>
```
```json Success Response theme={"dark"}
{
"data": [
{
"id": "report-1",
"subject": "Daily Sales Report",
"scheduleEmailReportCharts": [
{
"externalMetric": {
"metricId": "metric_revenue_123"
}
},
{
"externalMetric": {
"metricId": "metric_orders_456"
}
}
],
"timeConfigurations": {
"frequency": "daily",
"time": "09:00",
"timezone": "UTC"
},
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-20T14:22:00Z",
"clientId": "client_xyz789",
"embedId": "embed_abc123",
"createdByIdentifier": "user_abc123"
},
{
"id": "report-2",
"subject": "Weekly Summary Report",
"scheduleEmailReportCharts": [
{
"externalMetric": {
"metricId": "metric_users_789"
}
}
],
"timeConfigurations": {
"frequency": "weekly",
"day": "monday",
"time": "08:00",
"timezone": "UTC"
},
"createdAt": "2024-01-10T08:15:00Z",
"updatedAt": "2024-01-10T08:15:00Z",
"clientId": "client_xyz789",
"embedId": "embed_abc123",
"createdByIdentifier": null
}
]
}
```
```json Empty Results Response theme={"dark"}
{
"data": []
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_EMBED_ID",
"message": "invalid embed id, embed id not found for given data app"
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"embedId\" is required"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------- |
| `200` | **OK** - Scheduled reports retrieved successfully |
| `400` | **Bad Request** - Invalid request parameters, missing required fields, invalid API key, or embed ID not found |
| `500` | **Internal Server Error** - Server error occurred while processing the request |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------------------------------ |
| `INVALID_DATA_APP_API_KEY` | 400 | Invalid or expired API key, or data app not found |
| `INVALID_EMBED_ID` | 400 | Embed ID not found for the given data app |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid required parameters (e.g., embedId is required) |
| `INTERNAL_SERVER_ERROR` | 500 | An unexpected error occurred on the server |
## Filtering and Pagination
### Client Filtering
When `clientId` is provided, the API returns only scheduled reports associated with that specific client:
```javascript theme={"dark"}
// Get reports for a specific client
const clientReports = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123&clientId=client_A`);
// Get all reports for the embed (across all clients)
const allReports = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123`);
```
### User Filtering
When `userIdentifier` is provided, the API returns only scheduled reports created by that user:
```javascript theme={"dark"}
// Get reports created by a specific user
const userReports = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123&userIdentifier=user_abc`);
// Get all reports (regardless of creator)
const allReports = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123`);
```
### Combined Filtering
You can combine `clientId` and `userIdentifier` to filter reports by both client and creator:
```javascript theme={"dark"}
// Get reports for a specific client created by a specific user
const filteredReports = await fetch(
`/api/v2/data-app/embeds/reports?embedId=embed_123&clientId=client_A&userIdentifier=user_abc`
);
```
### Pagination
When pagination is enabled, results are limited to 10 reports per page:
```javascript theme={"dark"}
// Get first page (reports 1-10)
const page1 = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123&isPagination=true&pageNumber=1`);
// Get second page (reports 11-20)
const page2 = await fetch(`/api/v2/data-app/embeds/reports?embedId=embed_123&isPagination=true&pageNumber=2`);
```
## Use Cases
### 1. Display Scheduled Reports in Dashboard
Show all scheduled reports configured for an embed in your application's settings page:
```javascript theme={"dark"}
async function loadScheduledReports(embedId) {
const response = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/embeds/reports?embedId=${embedId}`,
{
headers: {
'Authorization': `Bearer ${apiToken}`
}
}
);
const { data } = await response.json();
return data; // Display in UI
}
```
### 2. Client-Specific Report Management
Allow clients to view and manage only their own scheduled reports:
```javascript theme={"dark"}
async function getClientReports(embedId, clientId) {
const response = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/embeds/reports?embedId=${embedId}&clientId=${clientId}`,
{
headers: {
'Authorization': `Bearer ${apiToken}`
}
}
);
const { data } = await response.json();
return data;
}
```
### 3. User-Specific Report View
Show users only the reports they created:
```javascript theme={"dark"}
async function getUserReports(embedId, userIdentifier) {
const response = await fetch(
`https://api.usedatabrain.com/api/v2/data-app/embeds/reports?embedId=${embedId}&userIdentifier=${userIdentifier}`,
{
headers: {
'Authorization': `Bearer ${apiToken}`
}
}
);
const { data } = await response.json();
return data;
}
```
# List Workspaces
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/list-workspaces
GET https://api.usedatabrain.com/api/v2/workspace
Retrieve all workspaces in your organization with optional pagination support for efficient data retrieval.
Retrieve a list of all workspaces in your organization. This endpoint supports pagination to efficiently handle large numbers of workspaces.
Use pagination when you have many workspaces to improve response times and reduce data transfer. The default page limit is 10 workspaces per page.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Query Parameters
Enable pagination to retrieve workspaces in batches. Pass `"true"` to enable pagination.
**Note:** Query parameters are passed as strings. Use `"true"` or `"false"` (not boolean values).
* `"true"`: Enable pagination with page-based retrieval (10 items per page)
* `"false"` (default): Return all workspaces in a single response
- Use pagination when you have more than 50 workspaces
- Improves response times for large datasets
- Reduces memory usage in your application
- Each page returns up to 10 workspaces
The page number to retrieve when pagination is enabled. Must be a numeric string (e.g., `"1"`, `"2"`, `"3"`).
**Note:** This parameter is only used when `isPagination` is set to `"true"`.
* Pages start at 1 (first page)
* Each page contains up to 10 workspaces
* Returns empty array if page number exceeds available pages
## Response
Array of workspace objects. Returns empty array if no workspaces exist or page number exceeds available pages.
The name of the workspace.
Error object if the request failed, otherwise `null` for successful requests.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - All Workspaces theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/workspace' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL - With Pagination theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/workspace?isPagination=true&pageNumber=1' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL - Second Page theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/workspace?isPagination=true&pageNumber=2' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```javascript Node.js - All Workspaces icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace', {
method: 'GET',
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
});
const result = await response.json();
console.log(result.data); // Array of all workspaces
```
```javascript Node.js - With Pagination icon="fa-brands fa-node-js" theme={"dark"}
async function fetchAllWorkspaces() {
let allWorkspaces = [];
let pageNumber = 1;
let hasMorePages = true;
while (hasMorePages) {
const response = await fetch(
`https://api.usedatabrain.com/api/v2/workspace?isPagination=true&pageNumber=${pageNumber}`,
{
headers: {
'Authorization': 'Bearer dbn_live_abc123...'
}
}
);
const result = await response.json();
if (result.data && result.data.length > 0) {
allWorkspaces = allWorkspaces.concat(result.data);
pageNumber++;
} else {
hasMorePages = false;
}
}
return allWorkspaces;
}
const workspaces = await fetchAllWorkspaces();
console.log(`Total workspaces: ${workspaces.length}`);
```
```python Python - All Workspaces icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.get(
'https://api.usedatabrain.com/api/v2/workspace',
headers={
'Authorization': 'Bearer dbn_live_abc123...'
}
)
result = response.json()
workspaces = result['data']
print(f"Total workspaces: {len(workspaces)}")
```
```python Python - With Pagination icon="fa-brands fa-python" theme={"dark"}
import requests
def fetch_all_workspaces(api_key):
all_workspaces = []
page_number = 1
has_more_pages = True
while has_more_pages:
response = requests.get(
'https://api.usedatabrain.com/api/v2/workspace',
params={
'isPagination': 'true',
'pageNumber': page_number
},
headers={
'Authorization': f'Bearer {api_key}'
}
)
result = response.json()
if result['data'] and len(result['data']) > 0:
all_workspaces.extend(result['data'])
page_number += 1
else:
has_more_pages = False
return all_workspaces
workspaces = fetch_all_workspaces('dbn_live_abc123...')
print(f"Total workspaces: {len(workspaces)}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/workspace')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
response = http.request(request)
result = JSON.parse(response.body)
puts "Total workspaces: #{result['data'].length}"
result['data'].each do |workspace|
puts "- #{workspace['name']}"
end
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class ListWorkspaces {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/workspace"))
.header("Authorization", "Bearer dbn_live_abc123...")
.GET()
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go - With Pagination icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
type WorkspaceResponse struct {
Data []Workspace `json:"data"`
Error interface{} `json:"error"`
}
type Workspace struct {
Name string `json:"name"`
}
func fetchAllWorkspaces(apiKey string) ([]Workspace, error) {
var allWorkspaces []Workspace
pageNumber := 1
for {
url := fmt.Sprintf(
"https://api.usedatabrain.com/api/v2/workspace?isPagination=true&pageNumber=%d",
pageNumber,
)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
var result WorkspaceResponse
json.Unmarshal(body, &result)
if len(result.Data) == 0 {
break
}
allWorkspaces = append(allWorkspaces, result.Data...)
pageNumber++
}
return allWorkspaces, nil
}
func main() {
workspaces, _ := fetchAllWorkspaces("dbn_live_abc123...")
fmt.Printf("Total workspaces: %d\n", len(workspaces))
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
[
'header' => 'Authorization: Bearer dbn_live_abc123...',
'method' => 'GET'
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Total workspaces: " . count($result['data']) . "\n";
foreach ($result['data'] as $workspace) {
echo "- " . $workspace['name'] . "\n";
}
?>
```
```json 200 - Success (Multiple Workspaces) theme={"dark"}
{
"data": [
{
"name": "Sales Analytics"
},
{
"name": "Customer Insights"
},
{
"name": "Marketing Dashboard"
}
],
"error": null
}
```
```json 200 - Success (Empty) theme={"dark"}
{
"data": [],
"error": null
}
```
```json 200 - Success (First Page) theme={"dark"}
{
"data": [
{
"name": "Workspace 1"
},
{
"name": "Workspace 2"
},
{
"name": "Workspace 3"
},
{
"name": "Workspace 4"
},
{
"name": "Workspace 5"
},
{
"name": "Workspace 6"
},
{
"name": "Workspace 7"
},
{
"name": "Workspace 8"
},
{
"name": "Workspace 9"
},
{
"name": "Workspace 10"
}
],
"error": null
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Workspaces retrieved successfully |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description | Solution |
| -------------------------- | ----------- | --------------- | --------------------------------------------------------- |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key | Verify your API key is correct and has proper permissions |
| `INTERNAL_SERVER_ERROR` | 500 | Server error | Contact support if error persists |
## Pagination Details
When `isPagination` is set to `true`:
* Each page returns up to **10 workspaces**
* Pages are 1-indexed (first page is `pageNumber=1`)
* An empty array is returned when you've reached the end
* Use this to implement "load more" or infinite scroll patterns
**Example flow:**
1. Request page 1 → Returns 10 workspaces
2. Request page 2 → Returns 10 more workspaces
3. Request page 3 → Returns 5 workspaces
4. Request page 4 → Returns empty array (no more data)
**Use pagination when:**
* You have more than 50 workspaces
* Building user interfaces with "load more" functionality
* Implementing infinite scroll
* Optimizing for mobile or slow connections
**Skip pagination when:**
* You have fewer than 20 workspaces
* You need all workspace data for processing
* Implementing search or filter functionality client-side
* **Cache results**: Store workspace lists client-side to reduce API calls
* **Handle empty pages**: Check for empty arrays to detect the last page
* **Show loading states**: Display loading indicators between page requests
* **Error handling**: Implement retry logic for failed requests
* **Rate limiting**: Respect API rate limits when fetching multiple pages
## Quick Start: Implement Pagination
For large workspace lists, implement pagination to efficiently fetch results page by page:
```javascript theme={"dark"}
async function loadWorkspacePage(pageNumber) {
const response = await fetch(
`https://api.usedatabrain.com/api/v2/workspace?isPagination=true&pageNumber=${pageNumber}`,
{
headers: { 'Authorization': 'Bearer dbn_live_abc123...' }
}
);
return await response.json();
}
// Load first page
const page1 = await loadWorkspacePage(1);
```
Implement a "Load More" button that increments the page number on each click to fetch additional workspaces.
# Proxy Authentication
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/proxy-authentication
Configure a proxy server to securely forward requests to your Databrain backend with authentication.
This page explains how to:
1. Create YOUR OWN proxy server that forwards requests to your Databrain backend
2. Configure the proxy to validate requests and add authentication headers
Your proxy acts as a secure gateway between your frontend and the Databrain backend.
Proxy authentication lets you host a secure intermediary server that validates incoming requests and forwards them to your Databrain backend. This approach keeps your plugin tokens secure on your server, never exposing them to the client.
**Enhanced Security:** With proxy authentication, your frontend never handles plugin tokens. Your proxy validates requests and adds the required authentication before forwarding to Databrain.
## How Proxy Authentication Works
```mermaid theme={"dark"}
sequenceDiagram
participant Client as Client (Browser)
participant Proxy as Your Proxy Server
participant Backend as Databrain Backend
Client->>Proxy: Request with X-Proxy-Auth-Key (or X-Authorization)
Proxy->>Proxy: Validate & add X-Plugin-Token
Proxy->>Backend: Forward request (method + body + headers)
Backend-->>Proxy: Response (status + body + headers)
Proxy-->>Client: Forward response exactly
```
Your frontend sends a request to your proxy server with the `X-Proxy-Auth-Key: ` or `X-Authorization: ` header for validation.
Your proxy validates the `X-Proxy-Auth-Key: ` or `X-Authorization: ` header. If invalid or missing, return an error response.
Your proxy constructs the upstream URL, adds the `X-Plugin-Token` header, and forwards the request to your Databrain backend exactly as received.
Your proxy returns the Databrain backend response to the client exactly as received (status code, body, and headers).
## What Your Proxy Must Do
Your proxy can be built on **any backend**: Node.js, Express, FastAPI, Python, Go, Lambda, Cloudflare Worker, etc. It must receive requests from your frontend and forward them to your Databrain backend exactly as-is, with required headers added.
### 1. Read the Incoming Request
Capture all parts of the incoming request:
* Path
* Query parameters
* HTTP method
* Headers
* **Body** (JSON, text, or binary/raw)
Body must **not** be modified. Preserve the raw content if it's binary (zip, pdf, excel, etc.) or text/JSON for other API calls.
### 2. Validate Proxy Authentication
Your proxy must read and validate either the `X-Proxy-Auth-Key` header or the `X-Authorization` header:
```
X-Proxy-Auth-Key:
```
Or:
```
X-Authorization:
```
Compare with your stored secret value. If missing or invalid, return an error:
```json theme={"dark"}
{
"error": { "message": "missing or invalid proxy auth key" }
}
```
Return appropriate HTTP status (401 or 403).
### 3. Forward Request to Databrain Backend
#### Construct Upstream URL
```
/?
```
#### Forward Original Method
Forward the exact HTTP method: GET, POST, PUT, PATCH, DELETE.
#### Forward Body Exactly
Do not modify the request payload in any way.
#### Required Upstream Headers
Send these headers to your Databrain backend:
| Header | Description |
| ------------------ | -------------------------------------- |
| `Accept` | Forward from incoming request |
| `Accept-Language` | Forward from incoming request |
| `User-Agent` | Forward from incoming request |
| `Content-Type` | Forward if present in incoming request |
| `X-Plugin-Origin` | Forward if provided by frontend |
| `X-Proxy-Auth-Key` | Forward original value (if provided) |
| `X-Authorization` | Forward original value (if provided) |
| `X-Proxy-Auth-Url` | Forward original value |
| `X-Plugin-Token` | **Your plugin token (added by proxy)** |
| `Origin` | Forward original value |
### 4. Return Response Exactly
Return **exactly** what the Databrain backend returns:
* Status code
* Response body (binary or text, do not transform)
* Response headers
**Binary responses** (zip, pdf, xlsx) must be forwarded as-is. Do not convert binary content to text.
## About X-Plugin-Token
The `X-Plugin-Token` header authenticates your requests with the Databrain backend. You can provide this token in two ways:
1. **A saved token** - Use a pre-generated guest token stored in your environment
2. **Generate on demand** - Call the [Databrain Guest Token API](/developer-docs/helpers/api-reference/token) to generate tokens dynamically
## Error Response Format
Every error your proxy returns should follow this format:
```json theme={"dark"}
{
"error": { "message": "description of the error" }
}
```
**Examples:**
```json theme={"dark"}
{
"error": { "message": "missing or invalid proxy auth key" }
}
```
```json theme={"dark"}
{
"error": { "message": "upstream fetch failed" }
}
```
## Requirements Summary
* Keep method, path, and query unchanged
* Preserve body type: JSON, text, or binary
* Pass all required headers (including `Origin`)
* Add `X-Plugin-Token` header
* Validate `X-Proxy-Auth-Key` **or** `X-Authorization` before forwarding
* Use correct error format
* Return upstream response exactly (status, body, headers)
* Forward binary responses (zip, pdf, xlsx) as-is
* Do not rewrite paths
* Do not remove fields from body
* Do not add custom fields to body
* Do not modify query parameters
* Do not transform the response
## Implementation Examples
```typescript theme={"dark"}
import express from "express";
import fetch from "node-fetch";
import bodyParser from "body-parser";
const app = express();
app.use(bodyParser.raw({ type: "*/*" })); // preserve raw body
// --- Environment variables ---
const PROXY_AUTH_KEY = process.env.PROXY_AUTH_KEY; // secret key for validating requests
const SELFHOSTED_BACKEND_URL = process.env.SELFHOSTED_BACKEND_URL; // your Databrain backend
const GUEST_TOKEN = process.env.GUEST_TOKEN; // plugin token (saved or generated via API)
app.all('/proxy-auth/*', async (req, res) => {
try {
// --- Extract path and query ---
const upstreamPath = req.path.replace(/^\/proxy-auth/, '') || '/';
const queryString = req.originalUrl.split('?')[1] || '';
const upstreamUrl = `${SELFHOSTED_BACKEND_URL}${upstreamPath}${queryString ? `?${queryString}` : ''}`;
const method = req.method;
const incomingHeaders = req.headers || {};
// --- Handle preflight OPTIONS request ---
if (method === 'OPTIONS') {
return res.status(204).end();
}
// --- Validate proxy key ---
const incomingProxyKey = incomingHeaders['x-proxy-auth-key'] || incomingHeaders['x-authorization'];
if (!incomingProxyKey || incomingProxyKey !== PROXY_AUTH_KEY) {
return res.status(401).json({
error: { message: 'missing or invalid proxy auth key' },
});
}
// --- Build upstream headers ---
const upstreamHeaders: Record = {
Accept: incomingHeaders['accept'] || '*/*',
'Accept-Language': incomingHeaders['accept-language'] || 'en-US',
'User-Agent': incomingHeaders['user-agent'] || 'Mozilla/5.0',
'X-Plugin-Token': GUEST_TOKEN,
};
if (incomingHeaders['content-type']) {
upstreamHeaders['Content-Type'] = incomingHeaders['content-type'];
}
if (incomingHeaders['x-plugin-origin']) {
upstreamHeaders['X-Plugin-Origin'] = incomingHeaders['x-plugin-origin'];
}
if (incomingHeaders['x-proxy-auth-url']) {
upstreamHeaders['X-Proxy-Auth-Url'] = incomingHeaders['x-proxy-auth-url'];
}
if (incomingHeaders['x-proxy-auth-key']) {
upstreamHeaders['X-Proxy-Auth-Key'] = incomingHeaders['x-proxy-auth-key'];
}
if (incomingHeaders['x-authorization']) {
upstreamHeaders['X-Authorization'] = incomingHeaders['x-authorization'];
}
if (incomingHeaders['origin']) {
upstreamHeaders['Origin'] = incomingHeaders['origin'];
}
// --- Prepare request body for non-GET/HEAD methods ---
let upstreamBody;
if (!['GET', 'HEAD'].includes(method)) {
upstreamBody = req.is('application/json') ? JSON.stringify(req.body) : req.body;
}
// --- Forward request to backend ---
let upstreamResponse;
try {
upstreamResponse = await fetch(upstreamUrl, {
method,
headers: upstreamHeaders,
body: upstreamBody,
});
} catch (err: any) {
return res.status(502).json({
error: { message: 'upstream fetch failed' },
detail: err.message,
});
}
// --- Forward upstream headers as-is ---
const outHeaders: Record = {};
upstreamResponse.headers.forEach((v, k) => (outHeaders[k] = v));
// --- Handle binary vs text responses ---
const contentType = upstreamResponse.headers.get('content-type') || '';
if (contentType.startsWith('text/') || contentType.includes('json')) {
const text = await upstreamResponse.text();
res.status(upstreamResponse.status).set(outHeaders).send(text);
} else {
const buffer = Buffer.from(await upstreamResponse.arrayBuffer());
res.status(upstreamResponse.status).set(outHeaders).send(buffer);
}
} catch (err: any) {
return res.status(500).json({
error: { message: 'internal server error' },
detail: err.message,
});
}
});
// --- Start server ---
app.listen(3000, () => {
console.log('Proxy server running on port 3000');
});
```
```python theme={"dark"}
from fastapi import FastAPI, Request, Response
from fastapi.responses import JSONResponse
import httpx
import os
app = FastAPI()
# --- Environment variables ---
PROXY_AUTH_KEY = os.getenv("PROXY_AUTH_KEY") # secret key for validating requests
SELFHOSTED_BACKEND_URL = os.getenv("SELFHOSTED_BACKEND_URL") # your Databrain backend
GUEST_TOKEN = os.getenv("GUEST_TOKEN") # plugin token (saved or generated via API)
@app.api_route("/proxy-auth/{path:path}", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"])
async def proxy_handler(request: Request, path: str):
try:
method = request.method
# --- Handle preflight OPTIONS request ---
if method == "OPTIONS":
return Response(status_code=204)
# --- Validate proxy key ---
incoming_proxy_key = request.headers.get("x-proxy-auth-key") or request.headers.get("x-authorization")
if not incoming_proxy_key or incoming_proxy_key != PROXY_AUTH_KEY:
return JSONResponse(
status_code=401,
content={"error": {"message": "missing or invalid proxy auth key"}}
)
# --- Construct upstream URL ---
query_string = str(request.query_params)
upstream_url = f"{SELFHOSTED_BACKEND_URL}/{path}"
if query_string:
upstream_url += f"?{query_string}"
# --- Build upstream headers ---
upstream_headers = {
"Accept": request.headers.get("accept", "*/*"),
"Accept-Language": request.headers.get("accept-language", "en-US"),
"User-Agent": request.headers.get("user-agent", "Mozilla/5.0"),
"X-Plugin-Token": GUEST_TOKEN,
}
if content_type := request.headers.get("content-type"):
upstream_headers["Content-Type"] = content_type
if plugin_origin := request.headers.get("x-plugin-origin"):
upstream_headers["X-Plugin-Origin"] = plugin_origin
if proxy_auth_url := request.headers.get("x-proxy-auth-url"):
upstream_headers["X-Proxy-Auth-Url"] = proxy_auth_url
if proxy_auth_key := request.headers.get("x-proxy-auth-key"):
upstream_headers["X-Proxy-Auth-Key"] = proxy_auth_key
if x_authorization := request.headers.get("x-authorization"):
upstream_headers["X-Authorization"] = x_authorization
if origin := request.headers.get("origin"):
upstream_headers["Origin"] = origin
# --- Get request body ---
body = await request.body() if method not in ["GET", "HEAD"] else None
# --- Forward request to backend ---
async with httpx.AsyncClient() as client:
try:
upstream_response = await client.request(
method=method,
url=upstream_url,
headers=upstream_headers,
content=body,
)
except httpx.RequestError as e:
return JSONResponse(
status_code=502,
content={"error": {"message": "upstream fetch failed"}, "detail": str(e)}
)
# --- Forward upstream headers as-is ---
out_headers = dict(upstream_response.headers)
# Remove hop-by-hop headers
for header in ["transfer-encoding", "connection", "keep-alive"]:
out_headers.pop(header, None)
# --- Handle binary vs text responses ---
# Response.content is already bytes, works for both binary and text
return Response(
content=upstream_response.content,
status_code=upstream_response.status_code,
headers=out_headers,
media_type=upstream_response.headers.get("content-type"),
)
except Exception as e:
return JSONResponse(
status_code=500,
content={"error": {"message": "internal server error"}, "detail": str(e)}
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3000)
```
```python theme={"dark"}
from flask import Flask, request, Response, jsonify
import requests
import os
app = Flask(__name__)
# --- Environment variables ---
PROXY_AUTH_KEY = os.getenv("PROXY_AUTH_KEY") # secret key for validating requests
SELFHOSTED_BACKEND_URL = os.getenv("SELFHOSTED_BACKEND_URL") # your Databrain backend
GUEST_TOKEN = os.getenv("GUEST_TOKEN") # plugin token (saved or generated via API)
@app.route("/proxy-auth/", methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"])
def proxy_handler(path):
try:
method = request.method
# --- Handle preflight OPTIONS request ---
if method == "OPTIONS":
return Response(status=204)
# --- Validate proxy key ---
incoming_proxy_key = request.headers.get("X-Proxy-Auth-Key") or request.headers.get("X-Authorization")
if not incoming_proxy_key or incoming_proxy_key != PROXY_AUTH_KEY:
return jsonify({"error": {"message": "missing or invalid proxy auth key"}}), 401
# --- Construct upstream URL ---
query_string = request.query_string.decode("utf-8")
upstream_url = f"{SELFHOSTED_BACKEND_URL}/{path}"
if query_string:
upstream_url += f"?{query_string}"
# --- Build upstream headers ---
upstream_headers = {
"Accept": request.headers.get("Accept", "*/*"),
"Accept-Language": request.headers.get("Accept-Language", "en-US"),
"User-Agent": request.headers.get("User-Agent", "Mozilla/5.0"),
"X-Plugin-Token": GUEST_TOKEN,
}
if content_type := request.headers.get("Content-Type"):
upstream_headers["Content-Type"] = content_type
if plugin_origin := request.headers.get("X-Plugin-Origin"):
upstream_headers["X-Plugin-Origin"] = plugin_origin
if proxy_auth_url := request.headers.get("X-Proxy-Auth-Url"):
upstream_headers["X-Proxy-Auth-Url"] = proxy_auth_url
if proxy_auth_key := request.headers.get("X-Proxy-Auth-Key"):
upstream_headers["X-Proxy-Auth-Key"] = proxy_auth_key
if x_authorization := request.headers.get("X-Authorization"):
upstream_headers["X-Authorization"] = x_authorization
if origin := request.headers.get("Origin"):
upstream_headers["Origin"] = origin
# --- Get request body ---
body = request.get_data() if method not in ["GET", "HEAD"] else None
# --- Forward request to backend ---
try:
upstream_response = requests.request(
method=method,
url=upstream_url,
headers=upstream_headers,
data=body,
)
except requests.RequestException as e:
return jsonify({"error": {"message": "upstream fetch failed"}, "detail": str(e)}), 502
# --- Forward upstream headers as-is ---
out_headers = dict(upstream_response.headers)
# Remove hop-by-hop headers
for header in ["Transfer-Encoding", "Connection", "Keep-Alive"]:
out_headers.pop(header, None)
# --- Handle binary vs text responses ---
# upstream_response.content is already bytes, works for both binary and text
return Response(
response=upstream_response.content,
status=upstream_response.status_code,
headers=out_headers,
mimetype=upstream_response.headers.get("Content-Type"),
)
except Exception as e:
return jsonify({"error": {"message": "internal server error"}, "detail": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=3000)
```
```java theme={"dark"}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.RestClientException;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/proxy-auth")
public class DatabrainProxyController {
@Value("${PROXY_AUTH_KEY}")
private String proxyAuthKey;
@Value("${SELFHOSTED_BACKEND_URL}")
private String selfhostedBackendUrl;
@Value("${GUEST_TOKEN}")
private String guestToken;
private final RestTemplate restTemplate = new RestTemplate();
@RequestMapping(value = "/**", method = {
RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT,
RequestMethod.PATCH, RequestMethod.DELETE, RequestMethod.OPTIONS
})
public ResponseEntity> proxyHandler(
HttpServletRequest request,
@RequestBody(required = false) byte[] body,
@RequestHeader Map headers
) {
try {
String method = request.getMethod();
// --- Handle preflight OPTIONS request ---
if ("OPTIONS".equals(method)) {
return ResponseEntity.status(204).build();
}
// --- Validate proxy key ---
String incomingProxyKey = headers.getOrDefault("x-proxy-auth-key", headers.get("x-authorization"));
if (incomingProxyKey == null || !incomingProxyKey.equals(proxyAuthKey)) {
return ResponseEntity.status(401).body(Map.of(
"error", Map.of("message", "missing or invalid proxy auth key")
));
}
// --- Construct upstream URL ---
String path = request.getRequestURI().replaceFirst("^/proxy-auth", "");
String queryString = request.getQueryString();
String upstreamUrl = selfhostedBackendUrl + path;
if (queryString != null && !queryString.isEmpty()) {
upstreamUrl += "?" + queryString;
}
// --- Build upstream headers ---
HttpHeaders upstreamHeaders = new HttpHeaders();
upstreamHeaders.set("Accept", headers.getOrDefault("accept", "*/*"));
upstreamHeaders.set("Accept-Language", headers.getOrDefault("accept-language", "en-US"));
upstreamHeaders.set("User-Agent", headers.getOrDefault("user-agent", "Mozilla/5.0"));
upstreamHeaders.set("X-Plugin-Token", guestToken);
if (headers.containsKey("content-type")) {
upstreamHeaders.set("Content-Type", headers.get("content-type"));
}
if (headers.containsKey("x-plugin-origin")) {
upstreamHeaders.set("X-Plugin-Origin", headers.get("x-plugin-origin"));
}
if (headers.containsKey("x-proxy-auth-url")) {
upstreamHeaders.set("X-Proxy-Auth-Url", headers.get("x-proxy-auth-url"));
}
if (headers.containsKey("x-proxy-auth-key")) {
upstreamHeaders.set("X-Proxy-Auth-Key", headers.get("x-proxy-auth-key"));
}
if (headers.containsKey("x-authorization")) {
upstreamHeaders.set("X-Authorization", headers.get("x-authorization"));
}
if (headers.containsKey("origin")) {
upstreamHeaders.set("Origin", headers.get("origin"));
}
// --- Prepare request entity ---
HttpEntity requestEntity = new HttpEntity<>(
"GET".equals(method) || "HEAD".equals(method) ? null : body,
upstreamHeaders
);
// --- Forward request to backend ---
ResponseEntity upstreamResponse;
try {
upstreamResponse = restTemplate.exchange(
upstreamUrl,
HttpMethod.valueOf(method),
requestEntity,
byte[].class
);
} catch (RestClientException e) {
return ResponseEntity.status(502).body(Map.of(
"error", Map.of("message", "upstream fetch failed"),
"detail", e.getMessage()
));
}
// --- Forward upstream headers as-is ---
HttpHeaders outHeaders = new HttpHeaders();
upstreamResponse.getHeaders().forEach((key, values) -> {
// Skip hop-by-hop headers
if (!key.equalsIgnoreCase("Transfer-Encoding") &&
!key.equalsIgnoreCase("Connection") &&
!key.equalsIgnoreCase("Keep-Alive")) {
outHeaders.put(key, values);
}
});
// --- Handle binary vs text responses ---
// byte[] response body works for both binary and text content
return ResponseEntity
.status(upstreamResponse.getStatusCode())
.headers(outHeaders)
.body(upstreamResponse.getBody());
} catch (Exception e) {
return ResponseEntity.status(500).body(Map.of(
"error", Map.of("message", "internal server error"),
"detail", e.getMessage()
));
}
}
}
```
```go theme={"dark"}
package main
import (
"io"
"log"
"net/http"
"os"
"strings"
)
var (
proxyAuthKey = os.Getenv("PROXY_AUTH_KEY")
selfhostedBackendURL = os.Getenv("SELFHOSTED_BACKEND_URL")
guestToken = os.Getenv("GUEST_TOKEN")
)
func proxyHandler(w http.ResponseWriter, r *http.Request) {
// --- Handle preflight OPTIONS request ---
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}
// --- Validate proxy key ---
incomingProxyKey := r.Header.Get("X-Proxy-Auth-Key")
if incomingProxyKey == "" {
incomingProxyKey = r.Header.Get("X-Authorization")
}
if incomingProxyKey == "" || incomingProxyKey != proxyAuthKey {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(`{"error":{"message":"missing or invalid proxy auth key"}}`))
return
}
// --- Construct upstream URL ---
path := strings.TrimPrefix(r.URL.Path, "/proxy-auth")
if path == "" {
path = "/"
}
upstreamURL := selfhostedBackendURL + path
if r.URL.RawQuery != "" {
upstreamURL += "?" + r.URL.RawQuery
}
// --- Read request body ---
var body io.Reader
if r.Method != "GET" && r.Method != "HEAD" {
body = r.Body
defer r.Body.Close()
}
// --- Create upstream request ---
upstreamReq, err := http.NewRequest(r.Method, upstreamURL, body)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(`{"error":{"message":"internal server error"}}`))
return
}
// --- Build upstream headers ---
upstreamReq.Header.Set("Accept", getOrDefault(r.Header.Get("Accept"), "*/*"))
upstreamReq.Header.Set("Accept-Language", getOrDefault(r.Header.Get("Accept-Language"), "en-US"))
upstreamReq.Header.Set("User-Agent", getOrDefault(r.Header.Get("User-Agent"), "Mozilla/5.0"))
upstreamReq.Header.Set("X-Plugin-Token", guestToken)
if ct := r.Header.Get("Content-Type"); ct != "" {
upstreamReq.Header.Set("Content-Type", ct)
}
if po := r.Header.Get("X-Plugin-Origin"); po != "" {
upstreamReq.Header.Set("X-Plugin-Origin", po)
}
if pau := r.Header.Get("X-Proxy-Auth-Url"); pau != "" {
upstreamReq.Header.Set("X-Proxy-Auth-Url", pau)
}
if pak := r.Header.Get("X-Proxy-Auth-Key"); pak != "" {
upstreamReq.Header.Set("X-Proxy-Auth-Key", pak)
}
if xa := r.Header.Get("X-Authorization"); xa != "" {
upstreamReq.Header.Set("X-Authorization", xa)
}
if origin := r.Header.Get("Origin"); origin != "" {
upstreamReq.Header.Set("Origin", origin)
}
// --- Forward request to backend ---
client := &http.Client{}
upstreamResp, err := client.Do(upstreamReq)
if err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadGateway)
w.Write([]byte(`{"error":{"message":"upstream fetch failed"},"detail":"` + err.Error() + `"}`))
return
}
defer upstreamResp.Body.Close()
// --- Forward upstream headers as-is ---
for key, values := range upstreamResp.Header {
// Skip hop-by-hop headers
lowerKey := strings.ToLower(key)
if lowerKey == "transfer-encoding" || lowerKey == "connection" || lowerKey == "keep-alive" {
continue
}
for _, value := range values {
w.Header().Add(key, value)
}
}
// --- Forward upstream response (handles both binary and text) ---
w.WriteHeader(upstreamResp.StatusCode)
io.Copy(w, upstreamResp.Body)
}
func getOrDefault(value, defaultValue string) string {
if value == "" {
return defaultValue
}
return value
}
func main() {
http.HandleFunc("/proxy-auth/", proxyHandler)
log.Println("Proxy server running on port 3000")
log.Fatal(http.ListenAndServe(":3000", nil))
}
```
## Frontend Configuration
Configure your frontend to send requests through your proxy server instead of directly to the Databrain backend.
### Configuration Setup
```javascript React theme={"dark"}
import { Databrain } from '@databrainhq/plugin';
// Configure proxy authentication globally
if (typeof window !== 'undefined') {
window.dbn = {
proxyAuthUrl: 'https://your-proxy-server.com/proxy-auth',
proxyAuthKey: 'your-proxy-authentication-key',
isEnableProxyAuth: true
};
}
function MyDashboard() {
return (
);
}
```
```javascript Vue.js theme={"dark"}
```
```html Vanilla JavaScript theme={"dark"}
```
**TypeScript Users:** You need to declare the global `window.dbn` type in your project:
```typescript theme={"dark"}
declare global {
interface Window {
dbn?: {
proxyAuthUrl?: string;
proxyAuthKey?: string;
isEnableProxyAuth?: boolean;
};
}
}
```
### Configuration Properties
| Property | Type | Required | Description |
| ------------------------------ | --------- | -------: | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `window.dbn.proxyAuthUrl` | `string` | Yes | The full URL of your proxy endpoint. This is sent as the `X-Proxy-Auth-Url` header. Example: `https://your-proxy-server.com/proxy-auth`. |
| `window.dbn.proxyAuthKey` | `string` | Yes | Secret key your frontend sends as `X-Proxy-Auth-Key` (or `X-Authorization`) for your proxy to validate. |
| `window.dbn.isEnableProxyAuth` | `boolean` | Yes | Enables proxy authentication mode. Use `true` to enable proxy auth. Use `false` (or omit) to use direct token authentication. |
Generate a strong, random key and store it securely. This key must match the one your proxy expects.
## Environment Variables
Your proxy server requires these environment variables:
| Variable | Description |
| ------------------------ | --------------------------------------------------------------------------------------------- |
| `PROXY_AUTH_KEY` | Secret key to validate incoming requests (must match frontend `proxyAuthKey`) |
| `SELFHOSTED_BACKEND_URL` | Your Databrain backend URL (e.g., `https://api.usedatabrain.com`) |
| `GUEST_TOKEN` | Your plugin token (saved or [generated via API](/developer-docs/helpers/api-reference/token)) |
## Security Best Practices
* **Use Strong Keys:** Generate a cryptographically random proxy authentication key
* **Validate Every Request:** Always verify the `X-Proxy-Auth-Key` header
* **HTTPS Only:** Ensure your proxy endpoint is only accessible via HTTPS
* **Rotate Keys:** Periodically rotate your proxy authentication keys
Add rate limiting to prevent abuse:
* Limit requests per IP address
* Limit requests per user/session
* Implement exponential backoff for repeated failures
* Log all proxy requests for audit purposes
* Monitor for unusual traffic patterns
* Set up alerts for authentication failures
* Store `GUEST_TOKEN` securely in environment variables
* Never expose tokens in client-side code
* Consider generating tokens dynamically for enhanced security
## Error Handling
### Common Errors
**Error:** `{"error": {"message": "missing or invalid X-Proxy-Auth-Key"}}`
**Cause:** The `X-Proxy-Auth-Key` header is missing or doesn't match.
**Solution:** Verify that `window.dbn.proxyAuthKey` matches your proxy's `PROXY_AUTH_KEY` environment variable.
**Error:** `{"error": {"message": "upstream fetch failed"}}`
**Cause:** Your proxy cannot reach the Databrain backend.
**Solution:**
* Verify `SELFHOSTED_BACKEND_URL` is correct
* Check network connectivity from your proxy server
* Verify firewall rules allow outbound connections
**Error:** `{"error": {"message": "internal server error"}}`
**Cause:** An unexpected error occurred in your proxy.
**Solution:** Check your proxy server logs for detailed error information.
## Testing Your Proxy
Use curl to test your proxy endpoint:
```bash theme={"dark"}
# Test with valid proxy key (X-Proxy-Auth-Key)
curl -X GET "https://your-proxy-server.com/proxy-auth/api/health" \
-H "X-Proxy-Auth-Key: your-proxy-key"
# Test with valid proxy key (X-Authorization)
curl -X GET "https://your-proxy-server.com/proxy-auth/api/health" \
-H "X-Authorization: your-proxy-key"
# Test authentication validation (should return 401)
curl -X GET "https://your-proxy-server.com/proxy-auth/api/health" \
-H "X-Proxy-Auth-Key: invalid-key"
# Test authentication validation (should return 401)
curl -X GET "https://your-proxy-server.com/proxy-auth/api/health" \
-H "X-Authorization: invalid-key"
```
## Related Resources
Learn about generating guest tokens for your proxy
Explore all DataBrain component configuration options
Comprehensive guide to DataBrain authentication
Learn about multi-tenant access control and security
# Publish/Unpublish Metric
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/publish-metric
PUT https://api.usedatabrain.com/api/v2/data-app/metrics/publish
Publish or unpublish metrics in an embed configuration to control which metrics are visible to end users.
Control the visibility of metrics within an embed by publishing or unpublishing them. Published metrics are visible to end users, while unpublished metrics remain hidden but can be published later.
This endpoint allows you to dynamically control metric visibility without deleting metrics or modifying embed configurations. Useful for staged rollouts, A/B testing, or hiding metrics temporarily.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The embed configuration ID where the metric is located.
* Use the [List Embeds API](/developer-docs/helpers/api-reference/list-embed) to get all embed IDs
* Check the response when creating an embed
* Available in your data app embed configurations
The ID of the metric to publish or unpublish.
* Use the [Fetch Metrics by Embed API](/developer-docs/helpers/api-reference/fetch-metrics-by-embed-and-client) to get metric IDs
* Available in metric URLs in your dashboard
* Returned when creating metrics via API
Set the publication status of the metric.
* `true`: Publish the metric (make it visible to end users)
* `false`: Unpublish the metric (hide it from end users)
- **Published metrics**: Visible in the embed, can be accessed by end users
- **Unpublished metrics**: Hidden from the embed, but not deleted
- **State preservation**: Metric configuration remains intact when unpublished
- **Quick toggle**: Can be republished instantly without recreating
## Response
The metric ID that was successfully updated on success.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Publish Metric theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/metrics/publish \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_abc123",
"metricId": "metric_xyz789",
"isPublished": true
}'
```
```bash cURL - Unpublish Metric theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/metrics/publish \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_abc123",
"metricId": "metric_xyz789",
"isPublished": false
}'
```
```javascript Node.js - Publish Metric icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/metrics/publish', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId: 'embed_abc123',
metricId: 'metric_xyz789',
isPublished: true
})
});
const result = await response.json();
console.log('Metric published:', result.id);
```
```javascript Node.js - Batch Publish icon="fa-brands fa-node-js" theme={"dark"}
// Publish multiple metrics sequentially
async function publishMetrics(embedId, metricIds, isPublished = true) {
const results = [];
for (const metricId of metricIds) {
const response = await fetch(
'https://api.usedatabrain.com/api/v2/data-app/metrics/publish',
{
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({ embedId, metricId, isPublished })
}
);
const result = await response.json();
results.push({ metricId, success: !result.error });
}
return results;
}
// Usage
const metrics = ['metric_1', 'metric_2', 'metric_3'];
const results = await publishMetrics('embed_abc123', metrics, true);
console.log('Published metrics:', results);
```
```python Python - Publish Metric icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.put(
'https://api.usedatabrain.com/api/v2/data-app/metrics/publish',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'embedId': 'embed_abc123',
'metricId': 'metric_xyz789',
'isPublished': True
}
)
result = response.json()
if result.get('error'):
print(f"Publish failed: {result['error']['message']}")
else:
print(f"Metric published: {result['id']}")
```
```python Python - Batch Operations icon="fa-brands fa-python" theme={"dark"}
import requests
def publish_metrics(embed_id, metric_ids, is_published=True):
"""Publish or unpublish multiple metrics"""
results = []
for metric_id in metric_ids:
response = requests.put(
'https://api.usedatabrain.com/api/v2/data-app/metrics/publish',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'embedId': embed_id,
'metricId': metric_id,
'isPublished': is_published
}
)
result = response.json()
results.append({
'metricId': metric_id,
'success': 'error' not in result
})
return results
# Usage
metrics = ['metric_1', 'metric_2', 'metric_3']
results = publish_metrics('embed_abc123', metrics, True)
print(f"Published {sum(r['success'] for r in results)} metrics")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/metrics/publish')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
embedId: 'embed_abc123',
metricId: 'metric_xyz789',
isPublished: true
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
if result['error']
puts "Publish failed: #{result['error']['message']}"
else
puts "Metric published: #{result['id']}"
end
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class PublishMetric {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"embedId": "embed_abc123",
"metricId": "metric_xyz789",
"isPublished": true
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/metrics/publish"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type PublishMetricRequest struct {
EmbedId string `json:"embedId"`
MetricId string `json:"metricId"`
IsPublished bool `json:"isPublished"`
}
func main() {
reqData := PublishMetricRequest{
EmbedId: "embed_abc123",
MetricId: "metric_xyz789",
IsPublished: true,
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("PUT",
"https://api.usedatabrain.com/api/v2/data-app/metrics/publish",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Metric published successfully")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'embed_abc123',
'metricId' => 'metric_xyz789',
'isPublished' => true
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'PUT',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
if (isset($result['error'])) {
echo "Publish failed: " . $result['error']['message'];
} else {
echo "Metric published: " . $result['id'];
}
?>
```
```json 200 - Success theme={"dark"}
{
"id": "metric_xyz789"
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"embedId\" is required"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Invalid Metric or Embed theme={"dark"}
{
"error": {
"code": "INVALID_METRIC_ID",
"message": "Invalid metric id or embed id"
}
}
```
```json 500 - Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------- |
| `200` | **OK** - Metric publication status updated |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error or invalid IDs |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ----------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid parameters |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INVALID_METRIC_ID` | 500 | Invalid metric or embed ID |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
# Rename an Embed
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/rename-embed
PUT https://api.usedatabrain.com/api/v2/data-app/embeds/rename
Rename an existing embed and optionally its underlying dashboard, without changing its access settings.
Use this endpoint to **rename an existing embed**. This is useful when you want to improve naming, align with client labels, or clean up your embed catalog without changing permissions or the underlying data.\
Optionally, you can also rename the underlying dashboard by setting `isRenameDashboard` to `true`.
## Endpoint
```bash theme={"dark"}
PUT https://api.usedatabrain.com/api/v2/data-app/embeds/rename
```
## Authentication
All API requests must include your **data app API key** in the `Authorization` header. Get your API token when creating a data app – see the [data app creation guide](/guides/datasources/create-a-data-app) for details.
For details on managing API tokens, see the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your data app API key.
```bash theme={"dark"}
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```bash theme={"dark"}
Content-Type: application/json
```
## Request Body
The public embed ID you want to rename (for example: `"embed-123"`).\
You can retrieve embed IDs from the [List All Embeds](/developer-docs/helpers/api-reference/list-embed) API or from the embed configuration UI.
The new human‑readable name for the embed configuration.\
Must be a non‑empty string.
Optional flag to also rename the underlying dashboard associated with this embed.\
When set to `true`, DataBrain attempts to update the dashboard's name to match the new embed name. Defaults to `false` if omitted.
### Example Request
```bash cURL theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/embeds/rename \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed-123",
"name": "Executive Sales Overview",
"isRenameDashboard": true
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch(
'https://api.usedatabrain.com/api/v2/data-app/embeds/rename',
{
method: 'PUT',
headers: {
Authorization: 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
embedId: 'embed-123',
name: 'Executive Sales Overview',
isRenameDashboard: true,
}),
}
);
const data = await response.json();
console.log('Renamed embed:', data.id, '->', data.name);
```
```python Python theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/embeds/rename"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json",
}
payload = {
"embedId": "embed-123",
"name": "Executive Sales Overview",
}
response = requests.put(url, headers=headers, json=payload)
data = response.json()
print(f"Renamed embed: {data['id']} -> {data['name']}")
```
## Response
The embed ID that was renamed.
The updated name of the embed configuration.
Error object if the request failed, otherwise `null` for successful requests.
### Example Responses
```json 200 - Success theme={"dark"}
{
"id": "embed-123",
"name": "Executive Sales Overview",
"error": null
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "embedId is required"
}
}
```
```json 400 - Invalid Name theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "name cannot be empty"
}
}
```
```json 400 - Invalid Embed ID theme={"dark"}
{
"error": {
"code": "INVALID_EMBED_ID",
"message": "Embed configuration not found"
}
}
```
```json 400 - Invalid API Key theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "Missing or invalid data app"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | -------------------------------------------------------------------- |
| `200` | **OK** – Embed renamed successfully |
| `400` | **Bad Request** – Invalid body, invalid embed ID, or invalid API key |
| `500` | **Internal Server Error** – Unexpected server error |
## Common Error Codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid `embedId` or `name` |
| `INVALID_EMBED_ID` | 400 | Embed configuration does not exist |
| `INVALID_DATA_APP_API_KEY` | 400 | Missing or invalid data app API key |
| `INTERNAL_SERVER_ERROR` | 500 | Unexpected failure on the server |
## Usage Patterns
### Rename for Better UX Labels
```javascript theme={"dark"}
// Align embed name with customer-facing label
await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds/rename', {
method: 'PUT',
headers: {
Authorization: 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
embedId: 'embed-123',
name: 'Revenue Overview (ACME)',
}),
});
```
### Bulk Rename Embeds During Migration
```javascript theme={"dark"}
const renames = [
{ embedId: 'embed-001', name: 'Sales Overview' },
{ embedId: 'embed-002', name: 'Marketing Performance' },
];
for (const rename of renames) {
await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds/rename', {
method: 'PUT',
headers: {
Authorization: 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify(rename),
});
}
```
## Related APIs
* [Embed a Pre-built Dashboard/Metric](/developer-docs/helpers/api-reference/create-embed)
* [Create an Empty Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed)
* [Update an Embed](/developer-docs/helpers/api-reference/update-embed)
* [Delete an Embed](/developer-docs/helpers/api-reference/delete-embed)
* [List All Embeds](/developer-docs/helpers/api-reference/list-embed)
# Reset Admin Password (Self-Hosted)
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/reset-admin-password
POST https://api.usedatabrain.com/api/v2/service-token/reset-password
Change the password for the currently authenticated admin user on a self-hosted Databrain instance. Self-hosted only.
Change the password for the admin user identified by the current authentication token. Requires the current password and the new password. The new password should meet the same complexity rules as sign-up (see [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account)).
**Self-Hosted Only:** This endpoint is available only on **self-hosted** Databrain instances.
**Authentication Requirement:** This endpoint requires an authenticated admin user. Use the Bearer token from [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt).
## Authentication
Use a valid admin JWT in the `Authorization` header. Obtain one via [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt).
## Headers
Bearer token for the admin whose password is being changed.
```
Authorization: Bearer
```
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
The admin's current password.
The new password. Should meet the same requirements as sign-up: minimum 8 characters, at least one uppercase, one lowercase, one digit, one special character, no spaces.
## Response
On success, the API returns **200** with a JSON object:
Wrapper object for the response payload.
`true` when the password was changed successfully.
On error, the API returns a JSON object with `error.code` and `error.message` and an appropriate HTTP status (400 or 500).
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/service-token/reset-password \
--header 'Authorization: Bearer YOUR_ADMIN_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"currentPassword":"OldP@ss1","password":"NewSecureP@ss2"}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/service-token/reset-password', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ADMIN_ACCESS_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
currentPassword: 'OldP@ss1',
password: 'NewSecureP@ss2'
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
console.log('Password reset:', data.data.success);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/service-token/reset-password"
headers = {
"Authorization": "Bearer YOUR_ADMIN_ACCESS_TOKEN",
"Content-Type": "application/json"
}
payload = {
"currentPassword": "OldP@ss1",
"password": "NewSecureP@ss2"
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if data.get("error"):
raise Exception(data["error"].get("message", "Request failed"))
print("Password reset:", data["data"]["success"])
```
```json Success (200) theme={"dark"}
{
"data": {
"success": true
}
}
```
```json Error (400) theme={"dark"}
{
"error": {
"code": "RESET_PASSWORD_ERROR",
"message": "The current password is not correct!"
}
}
```
```json Error (500) theme={"dark"}
{
"error": {
"code": "SELFHOSTED_APP_ERROR",
"message": "This feature is only available for self-hosted instances"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ---------------------------------------------------------------------------- |
| `200` | **OK** – Password changed successfully; `data.success` is `true` |
| `400` | **Bad Request** – Wrong current password or validation error on new password |
| `500` | **Internal Server Error** – Server error or self-hosted-only error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | -------------------------------------------------------------------------------- | ----------- |
| `RESET_PASSWORD_ERROR` | Error message from password change (e.g. "The current password is not correct!") | 400 |
| `SELFHOSTED_APP_ERROR` | This feature is only available for self-hosted instances | 500 |
| `INTERNAL_SERVER_ERROR` | Internal server error or GraphQL error message | 500 |
## Related
* [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) – Sign in to get an access token
* [Create Admin Account](/developer-docs/helpers/api-reference/create-admin-account) – Create the first admin account
# Rotate API Key
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/rotate-api-key
POST https://api.usedatabrain.com/api/v2/data-app/rotate-api
Rotate your Data App API key to enhance security and manage key lifecycle effectively.
Rotate your data app API key to maintain security best practices by periodically refreshing credentials. This endpoint expires the current API key and generates a new one, ensuring seamless transition while maintaining security.
The API key used in the `Authorization` header **is** the key being rotated. You only need to provide `expireAt` in the request body — no `key` field required.
## Authentication
This endpoint requires the **data app API key** you want to rotate in the `Authorization` header. The key used for authentication is the key that will be expired and replaced with a new one.
To access your data app API key:
1. Go to your Databrain dashboard and open the **Data Apps** section.
2. Select the data app whose API key you want to rotate.
3. Find the **API Key** under the data app settings.
Use this key as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use the **data app API key** you want to rotate.
```
Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Duration in seconds until the current API key expires. This allows for a grace period to update your applications before the old key stops working. Accepts a number or a numeric string.
* `0` - Expire immediately (instant rotation)
* `300` - 5 minutes
* `3600` - 1 hour
* `86400` - 24 hours
* `604800` - 7 days
**Recommended:** Set a grace period (e.g., `3600`) to allow time for updating your applications without service interruption.
## Response
The newly generated API key (UUID format). Use this key for all future API requests.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Immediate Rotation theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/rotate-api \
--header 'Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{
"expireAt": 0
}'
```
```bash cURL - Rotation with Grace Period theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/data-app/rotate-api \
--header 'Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{
"expireAt": 3600
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/rotate-api', {
method: 'POST',
headers: {
'Authorization': 'Bearer 550e8400-e29b-41d4-a716-446655440000',
'Content-Type': 'application/json'
},
body: JSON.stringify({
expireAt: 3600
})
});
const data = await response.json();
console.log('New API Key:', data.key);
```
```python Python theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/data-app/rotate-api',
headers={
'Authorization': 'Bearer 550e8400-e29b-41d4-a716-446655440000',
'Content-Type': 'application/json'
},
json={
'expireAt': 3600
}
)
data = response.json()
print('New API Key:', data['key'])
```
```java Java theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
Map requestBody = Map.of(
"expireAt", 3600
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/rotate-api"))
.header("Authorization", "Bearer 550e8400-e29b-41d4-a716-446655440000")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(requestBody)))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
```
```php PHP theme={"dark"}
3600
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/data-app/rotate-api',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo 'New API Key: ' . $result['key'];
?>
```
```ruby Ruby theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/rotate-api')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer 550e8400-e29b-41d4-a716-446655440000'
request['Content-Type'] = 'application/json'
request.body = {
expireAt: 3600
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "New API Key: #{result['key']}"
```
```go Go theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type RotateKeyRequest struct {
ExpireAt int `json:"expireAt"`
}
type RotateKeyResponse struct {
Key string `json:"key"`
}
func main() {
requestBody := RotateKeyRequest{
ExpireAt: 3600,
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/data-app/rotate-api", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer 550e8400-e29b-41d4-a716-446655440000")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result RotateKeyResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("New API Key: %s\n", result.Key)
}
```
```csharp C# theme={"dark"}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class RotateKeyRequest
{
[JsonProperty("expireAt")]
public int ExpireAt { get; set; }
}
public class RotateKeyResponse
{
[JsonProperty("key")]
public string Key { get; set; }
}
var client = new HttpClient();
var request = new RotateKeyRequest { ExpireAt = 3600 };
var json = JsonConvert.SerializeObject(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer 550e8400-e29b-41d4-a716-446655440000");
var response = await client.PostAsync("https://api.usedatabrain.com/api/v2/data-app/rotate-api", content);
var result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
Console.WriteLine($"New API Key: {result.Key}");
```
```json 200 - Success theme={"dark"}
{
"key": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"expireAt\" is required"
}
}
```
```json 400 - Invalid API Key Format theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is not provided or Invalid!"
}
}
```
```json 401 - API Key Not Found or Expired theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is invalid or expired!"
}
}
```
```json 400 - Not a Data App API Key theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ----------------------------------------------------------------- |
| `200` | **OK** - Key rotated successfully |
| `400` | **Bad Request** - Invalid request parameters or invalid key state |
| `401` | **Unauthorized** - API key not found in DB or already expired |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid `expireAt` parameter |
| `AUTHENTICATION_ERROR` | 400 / 401 | API key missing or not a valid UUID (400); or not found / already expired in DB (401) |
| `INVALID_DATA_APP_API_KEY` | 400 | Token is a service token (no `dataAppId`), key not found, belongs to a different org, or the key already has an expiry date set |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Related Resources
Learn about API token management and authentication
Create data apps and generate initial API tokens
Generate guest tokens using your data app API key
List all embed configurations for your data app
# Rotate Service Token
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/rotate-service-token
POST https://api.usedatabrain.com/api/v2/service-token/rotate
Rotate your service token. Expires the current token after an optional grace period and returns a new token.
Rotate your organization service token. The current token is set to expire after a grace period (in seconds), and a new service token is returned. Use this for key rotation and security best practices.
The service token used in the `Authorization` header **is** the token being rotated. You only need to provide `expireAt` in the request body — no `token` field required.
## Authentication
Use your current **service token** in the `Authorization` header. The token provided here is the one that will be expired and replaced.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
## Headers
Bearer token for API authentication. Use the **service token** you want to rotate.
```
Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000
```
Must be `application/json` when sending a JSON body.
```
Content-Type: application/json
```
## Request Body
Duration in **seconds** until the current token expires. The old token remains valid until this many seconds from the request, then it is invalidated. Accepts a number or a numeric string. Use `0` to expire immediately. Common values: `0` (immediate), `3600` (1 hour), `86400` (24 hours).
## Response
On success, the API returns **200** with a JSON object:
The new service token (UUID). Use this for all future service-level API calls. Store it securely; the previous token will expire per `expireAt`.
On error, the API returns a JSON object with `error.code` and `error.message` and an appropriate HTTP status (400, 401, or 500).
## Examples
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/service-token/rotate \
--header 'Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000' \
--header 'Content-Type: application/json' \
--data '{"expireAt":3600}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/service-token/rotate', {
method: 'POST',
headers: {
'Authorization': 'Bearer 550e8400-e29b-41d4-a716-446655440000',
'Content-Type': 'application/json'
},
body: JSON.stringify({
expireAt: 3600
})
});
const data = await response.json();
if (data.error) throw new Error(data.error.message);
console.log('New service token:', data.key);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/service-token/rotate"
headers = {
"Authorization": "Bearer 550e8400-e29b-41d4-a716-446655440000",
"Content-Type": "application/json"
}
payload = {
"expireAt": 3600
}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
if data.get("error"):
raise Exception(data["error"].get("message", "Request failed"))
print("New service token:", data["key"])
```
```json Success (200) theme={"dark"}
{
"key": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}
```
```json Error (400) - Invalid request body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"expireAt\" is required"
}
}
```
```json Error (400) - Invalid API key format theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is not provided or Invalid!"
}
}
```
```json Error (401) - API key not found or expired theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "API Key is invalid or expired!"
}
}
```
```json Error (400) - Not a service token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json Error (400) - Token already expired theme={"dark"}
{
"error": {
"code": "EXPIRED_SERVICE_TOKEN",
"message": "Service token is already expired"
}
}
```
```json Error (500) theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal server error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------------------------------------------------- |
| `200` | **OK** – New service token returned in `key` |
| `400` | **Bad Request** – Missing parameters, invalid key format, not a service token, or token already expired |
| `401` | **Unauthorized** – Service token not found in DB or already expired |
| `500` | **Internal Server Error** – Server error |
## Possible Errors
| Code | Message | HTTP Status |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| `INVALID_REQUEST_BODY` | Joi validation message (e.g. `"expireAt" is required`) | 400 |
| `AUTHENTICATION_ERROR` | `"API Key is not provided or Invalid!"` – missing/invalid UUID format (400); `"API Key is invalid or expired!"` – not found or expired in DB (401); `"Invalid Service Token"` – token is a data app key, not a service token (400) | 400 / 401 |
| `EXPIRED_SERVICE_TOKEN` | Service token is already expired | 400 |
| `INVALID_SERVICE_TOKEN` | Invalid service token | 400 |
| `INTERNAL_SERVER_ERROR` | Internal server error or GraphQL error message | 500 |
## Related
* [Create Service Token](/developer-docs/helpers/api-reference/create-service-token) – Create or save a service token
* [Rotate API Key](/developer-docs/helpers/api-reference/rotate-api-key) – Rotate a data app API key
* [Create Admin JWT](/developer-docs/helpers/api-reference/create-admin-jwt) – Get admin access token
# Semantic Layer API
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/semantic-layer-api
APIs to create, read, update, and delete semantic layer configurations for your datamarts. The semantic layer enriches your datamart with business-friendly metadata — descriptions, synonyms, column types, and feedback — to power AI chat mode and improve data discoverability.
The Semantic Layer API operates on **existing datamarts**. You must create a datamart first using the [Datamart API](/developer-docs/helpers/api-reference/create-datamart) before adding a semantic layer.
## API Endpoints
### Cloud Databrain Endpoint
```bash theme={"dark"}
https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer
```
### Self-hosted Databrain Endpoint
```bash theme={"dark"}
/api/v2/data-app/datamarts/semantic-layer
```
The same routes are also mounted at `/api/v2/dataApp/...` (camelCase) if your client or proxy uses that prefix.
## Authentication
All semantic layer endpoints require a **service token** (not a data app API token). Data app tokens will be rejected with a `403 AUTHENTICATION_ERROR`.
Bearer token for API authentication. Must be a service token.
```
Authorization: Bearer dbn_live_abc123...
```
## Available Operations
Retrieve the semantic layer for a datamart including tables, columns, and completion score.
Add semantic metadata to a datamart that doesn't have one yet.
Modify existing semantic layer metadata (descriptions, synonyms, feedback).
Remove all semantic layer metadata from a datamart.
## Key Concepts
### Tables & Columns
Enrich your datamart tables and columns with:
* **Descriptions** — natural-language explanations of what the data represents
* **Synonyms** — alternative names users might search for (up to 10 per entity)
* **Column types** — semantic classifications like `String`, `Number`, `ENUM`, `Range`, `Identifier`, etc.
* **Column type config** — type-specific shape (e.g. value-to-description maps for `ENUM` / `String` types, `{ lowerLimit, upperLimit }` for `Range`, strings for `Expression` / `JSON`)
* **Miscellaneous info** — extra context for the AI to improve query generation
### Feedback
A free-text field (up to 2000 characters) providing global context about the datamart to guide AI behavior.
### Completion Score
A computed score (0–100) reflecting how thoroughly the semantic layer is filled out. Returned by the GET endpoint.
# SMTP Settings
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/smtp-settings
PUT https://api.usedatabrain.com/api/v2/data-app/smtp-settings
Configure SMTP settings for your data app so scheduled reports can be sent by email.
Set or update the SMTP configuration used to send scheduled reports and other emails for your data app. The API validates the connection before saving; if the credentials or server are invalid, the request fails and settings are not stored.
You can also configure email in the UI: **Settings → Embed Settings → Email Settings**. This API is for automation and integration. See [Email Settings for Scheduled Reports](/guides/preview-of-dashboards/email-settings-for-scheduled-reports) for the UI flow.
## Endpoint
```
PUT https://api.usedatabrain.com/api/v2/data-app/smtp-settings
```
## Authentication
All requests must include your **data app API key** in the `Authorization` header. See the [data app creation guide](/guides/datasources/create-a-data-app) and the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your data app API key.
```
Authorization: Bearer dbn_live_abc123...
```
Must be `application/json`.
## Request Body
SMTP server hostname (e.g. `smtp.example.com`).
SMTP server port as integer (e.g. `587` for STARTTLS, `465` for implicit SSL).
SMTP authentication username.
SMTP authentication password.
Sender email address. Must be a valid email format (e.g. `noreply@example.com`).
Reply-to email address. Must be a valid email format.
Whether to use TLS/SSL for the connection. Use `true` for port 465; use `false` for port 587 with STARTTLS.
## Response
`true` when settings were saved successfully.
## Examples
```bash cURL theme={"dark"}
curl --request PUT \
--url 'https://api.usedatabrain.com/api/v2/data-app/smtp-settings' \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"host": "smtp.example.com",
"port": 587,
"username": "smtp-user",
"password": "your-password",
"fromAddress": "noreply@example.com",
"replyToAddress": "support@example.com",
"secure": false
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/smtp-settings', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
host: 'smtp.example.com',
port: 587,
username: 'smtp-user',
password: 'your-password',
fromAddress: 'noreply@example.com',
replyToAddress: 'support@example.com',
secure: false,
}),
});
const result = await response.json();
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app/smtp-settings"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json",
}
payload = {
"host": "smtp.example.com",
"port": 587,
"username": "smtp-user",
"password": "your-password",
"fromAddress": "noreply@example.com",
"replyToAddress": "support@example.com",
"secure": False,
}
response = requests.put(url, headers=headers, json=payload)
data = response.json()
```
```json Success theme={"dark"}
{
"data": {
"success": true
}
}
```
```json Error – Validation theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"fromAddress\" must be a valid email"
}
}
```
```json Error – SMTP test failed theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "SMTP connection test failed"
}
}
```
```json Error – Invalid API key theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
## Error codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------------------------------------ |
| `INVALID_DATA_APP_API_KEY` | 400 | Missing or invalid data app API key |
| `INVALID_SERVICE_TOKEN` | 400 | Invalid or expired token; cannot resolve company context |
| `INVALID_REQUEST_BODY` | 400 | Invalid or missing body fields (e.g. invalid email, missing host) |
| `INTERNAL_SERVER_ERROR` | 400 / 500 | SMTP connection test failed (400) or unexpected server error (500) |
## Related
Configure email in the UI
Manage embedding domains
# Sync Datasource
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/sync-datasource
POST https://api.usedatabrain.com/api/v2/datasource/sync
### Overview
The Databrain APIs provides endpoints to sync you Datasource in both Cloud Databrain and Selfhosted Databrain environment. To use the API, you need to pass a parameter `datasourceId`.
## Self-hosted Databrain Endpoint
```bash theme={"dark"}
POST /api/v2/datasource/sync
```
## Headers
Bearer [API TOKEN](https://docs.usedatabrain.com/developer-docs/helpers/api-token)
## Request Body
Input object containing the datasource configuration.
The unique identifier of the datasource to sync. You can find this in the URL query params on the datasource page.
## Request Example
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datasource/sync \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"input": {
"datasourceId": "your-datasource-id"
}
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/datasource/sync', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
input: {
datasourceId: 'your-datasource-id'
}
})
});
const data = await response.json();
console.log(data.data.message);
```
```python Python theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/datasource/sync',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'input': {
'datasourceId': 'your-datasource-id'
}
}
)
data = response.json()
print(data['data']['message'])
```
## Response Body
```json theme={"dark"}
{
"data": {
"message": "Sync completed"
}
}
```
> Get your `datasourceId` from the URL query params on the datasource page.
## Error Codes
* **INVALID\_REQUEST\_BODY**: The request body is invalid.
* **DATASOURCE\_ID\_ERROR**: The datasource ID provided does not exist or is invalid.
# Guest Token
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/token
POST https://api.usedatabrain.com/api/v2/guest-token/create
Generate secure guest tokens for embedding DataBrain dashboards and metrics in your application.
Guest tokens are designed for frontend embedding. Never expose your API key in frontend code - always generate tokens from your backend.
**Simple Usage:** Only `clientId` and `dataAppName` are required. All other parameters (`params`, `permissions`, `expiryTime`, `datasourceName`, `datamartName`) are optional for advanced use cases.
The request body is validated strictly — any field not documented on this page is rejected with `INVALID_REQUEST_BODY`. In particular, `dataAppId`, `client_id`, `tenant_id`, and `permissions.dashboards` are **not** valid fields.
Guest tokens are free. There is no charge, metering, or purchase involved in generating them.
**Advanced Features Available:**
* Dashboard & metric-level filtering (`dashboardAppFilters`, `appFilters`)
* Per-dashboard metric visibility (`params.hideDashboardMetrics`)
* Embed allowlisting (`params.allowedEmbeds`)
* Fine-grained permissions control (`permissions` object)
* Private metrics for end users (`userIdentifier`)
* Timezone-aware queries (`params.timezone`)
* Multi-datasource support (`datasourceName`)
* Multi-datamart support (`datamartName`)
* Conditional filter visibility (`hideDashboardFilters`, `isShowOnUrl`)
* Token expiration management (`expiryTime`)
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json'
```
#### Cloud Databrain Endpoint:
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
#### Self-hosted Databrain Endpoint:
```http theme={"dark"}
POST /api/v2/guest-token/create
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Unique identifier for the end user. This should be your user's ID from your system. Used for row-level security and access control.
Use `"None"` as the value if no tenancy is configured for your workspace (e.g. `"clientId": "None"`).
* Use your internal user ID
* Keep it consistent across sessions
* Alphanumeric characters recommended
The name of your data application. Must match an existing data app in your workspace and be alphanumeric.
* `"sales-dashboard"`
* `"marketing-metrics"`
* `"customer-analytics"`
Additional parameters for token customization and filtering.
Optional allowlist of IDs this token can load.
* Each entry must match the ID you pass to the embed component's `dashboardId` attribute — embed IDs and dashboard IDs both resolve.
* If you provide `allowedEmbeds`, loading any ID not in the list fails with `UNAUTHORIZED`.
* If this is omitted, there is no restriction on which embeds can be loaded by the token.
* This is useful to restrict or enforce which dashboards or embedded analytics a guest can view, adding an extra layer of access control.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"allowedEmbeds": ["", ""]
}
}
```
Row-level security rules per metric. Each entry is `{ "metricId": string, "values": object }`, where `values` maps RLS variable names to the values enforced for this token. Unlike dashboard filters, RLS values are enforced server-side and cannot be changed by the end user.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"rlsSettings": [
{ "metricId": "metric_123", "values": { "customer_id": "456", "region": "north-america" } }
]
}
}
```
End-user dashboard- and metric-filter controls. Supported fields include the filter permissions, optional column allowlists, and filter-name rename permissions.
Application-level filters for controlling access to individual metrics. Unlike RLS settings, app filters restrict access without requiring end user input.
App filters are ideal for implementing metric-level access control that is invisible to end users.
The metric ID to apply filters to. Required if appFilters is provided.
Filter values to apply to the metric. Supports multiple data types:
Keys in `values` can use either the filter `label` or internal filter `name` (case-insensitive).
* **Boolean**: `"paid_orders": true`
* **Number**: `"amount": 500`
* **String**: `"country": "USA"`
* **Array** (multi-select): `"countries": ["USA", "CANADA"]`
* **Date preset shortcut**: `"order_date": "Last 30 days"`
* **SQL Query**: `{ "sql": "SELECT...", "columnName": "name" }`
```json theme={"dark"}
{
"metricId": "metric_123",
"values": {
"paid_orders": true,
"amount": 500,
"country": ["USA", "CANADA"],
"region": {
"sql": "SELECT \"name\" FROM \"public\".\"regions\" WHERE isActive=true",
"columnName": "name"
}
}
}
```
Dashboard-level filters that apply to all metrics on a dashboard. Supports multiple filter types for flexible data filtering.
The dashboard ID to apply filters to. Required if dashboardAppFilters is provided.
Filter values to apply to the dashboard. Supports various filter formats:
Keys in `values` can use either the dashboard filter `label` or internal filter `name` (case-insensitive).
* **Single string**: `"name": "Eric"`
* **Multi-select**: `"country": ["USA", "CANADA"]`
* **Date range**: `"timePeriod": { "startDate": "2024-01-01", "endDate": "2024-03-23" }`
* **Date preset shortcut**: `"timePeriod": "Last 30 days"`
* **Number range**: `"price": { "min": 1000, "max": 5000 }`
* **SQL query**: `{ "sql": "SELECT...", "columnName": "name" }`
```json theme={"dark"}
{
"dashboardId": "dashboard_abc123",
"values": {
"name": "Eric",
"country": ["USA", "CANADA"],
"timePeriod": {
"startDate": "2024-01-01",
"endDate": "2024-03-23"
},
"price": { "min": 1000, "max": 5000 },
"region": {
"sql": "SELECT \"name\" FROM \"public\".\"countries\" WHERE isEnabled=true",
"columnName": "name"
}
},
"isShowOnUrl": false
}
```
Controls visibility of filter values in URL search parameters. When `false`, filters are applied but not visible to end users in the URL.
Set to `false` to hide sensitive filter criteria from end users while still applying the filtering logic.
Array of filter names to hide from the dashboard interface. Use this to conditionally hide specific filters based on user permissions or context.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"hideDashboardFilters": ["region_filter", "date_range", "status"]
}
}
```
Metrics to hide from specific embedded dashboards. Each item targets one dashboard and removes the selected metrics and their layout cards from that dashboard's embed response.
External ID of the dashboard on which to hide the metrics. The dashboard must belong to the data app and workspace scope associated with the API token.
Public metric IDs to hide on the specified dashboard. Every metric must be present on that dashboard.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"hideDashboardMetrics": [
{
"dashboardId": "sales-overview",
"metricIds": ["revenue-by-region", "gross-margin"]
}
]
}
}
```
This setting controls dashboard presentation for this guest token. It does not delete, archive, or change the metrics globally. Configurations for other dashboard IDs do not affect the current dashboard. If the same dashboard appears more than once, the backend combines the metric IDs from all matching entries.
Optional advanced access controls for end-user dashboard filtering.
Enables or disables end-user dashboard filter controls in embedded mode.
Optional allowlist for dashboard filterable columns. Each item must include `tableName` and `columns`.
Fully qualified table name used in dashboard filters.
Column names allowed for dashboard filter evaluation for the specified table.
Enables or disables end-user metric filter interactions in embedded mode.
Optional allowlist for columns that end users can use in metric filters. Each item must include `tableName` and `columns`.
Fully qualified table name used in metric filters.
Column names allowed for metric filter evaluation for the specified table.
Enables or disables end-user renaming of dashboard filter labels in embedded mode.
Enables or disables end-user renaming of metric filter labels in embedded mode.
Unique identifier for the end user in your system. Enables features like creating **private metrics** and **publishing metrics** directly from the embed view.
The `isAllowPrivateMetricsByDefault` setting must be enabled when creating the dashboard for this feature to work.
When set, metrics created by this user identifier can be:
* Saved as private (visible only to this user)
* Published to share with other users
* Managed independently per user
```json theme={"dark"}
{
"clientId": "client-123",
"dataAppName": "analytics-app",
"params": {
"userIdentifier": "user_john_doe_789"
}
}
```
IANA timezone string for timezone-aware queries and date/time formatting. When provided, SQL queries will be executed with this timezone setting, ensuring consistent date/time handling across different timezones.
The timezone is used to set the database session timezone for SQL queries, ensuring that date/time operations are performed in the specified timezone.
**Supported Datasources:**
* Clickhouse
* Trino
* Redshift
* CockroachDB
* Postgres
* MSSQL
Want to implement timezone-aware dashboards end to end? See the full step-by-step guide: [Timezone Handling in Guest Token](/developer-docs/solutions-alchemy/guest-token-timezone).
* `"UTC"` - Coordinated Universal Time
* `"America/New_York"` - Eastern Time (US)
* `"America/Los_Angeles"` - Pacific Time (US)
* `"Europe/London"` - Greenwich Mean Time / British Summer Time
* `"Asia/Kolkata"` - Indian Standard Time
* `"Australia/Sydney"` - Australian Eastern Time
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"timezone": "America/New_York"
}
}
```
Permission settings for the embedded interface.
Allow archiving metrics.
Allow managing metrics (view, edit, organize).
Allow creating custom dashboard views.
Allow updating metric configurations.
Allow customizing dashboard layout.
Allow viewing underlying data behind charts.
Allow downloading metric data.
Show the sidebar navigation.
Show the dashboard name in the interface.
Disable metric creation in embedded dashboards. When set to `true`, end users cannot create new metrics.
* Setting this to `true` disables only the metric creation feature for end users in the embedded interface.
* If you want to allow metric creation again, mint a new token with this option set to `false` or removed, and check the Data App's Access Control settings and the component options (`options.disableMetricCreation`).
* Overrides other metric creation permissions when enabled.
**Optional.** Token expiration time in milliseconds from now. If not provided, token never expires.
* `3600000` - 1 hour (3600 \* 1000 ms)
* `86400000` - 24 hours
* `604800000` - 7 days
**Optional.** Scope the token to a specific Datamart.
**Optional.** Datasource name for multi-datasource connection setups. Required when your data app uses multiple datasources.
The datasource name is available in the **Data Studio** tab of your dashboard. This parameter is only necessary if you have configured multiple datasources for your data app.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "analytics-app",
"datasourceName": "production_db_replica"
}
```
**Optional.** Datamart name for multi-datamart connection setups. Use this when your data app can resolve multiple datamarts and you want to pin token execution to one datamart.
If both `datasourceName` and `datamartName` are omitted, Databrain resolves defaults from the data app context.
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "analytics-app",
"datamartName": "sales-datamart"
}
```
```bash cURL (Simple) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-456",
"dataAppName": "sales-dashboard"
}'
```
```bash cURL (Advanced) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"rlsSettings": [
{
"metricId": "metric_123",
"values": {
"customer_id": "456",
"region": "north-america"
}
}
]
},
"expiryTime": 3600000
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
clientId: 'user-456',
dataAppName: 'sales-dashboard',
params: {
rlsSettings: [
{
metricId: 'metric_123',
values: {
customer_id: '456',
region: 'north-america'
}
}
]
},
expiryTime: 3600000
})
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/guest-token/create',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'clientId': 'user-456',
'dataAppName': 'sales-dashboard',
'params': {
'rlsSettings': [
{
'metricId': 'metric_123',
'values': {
'customer_id': '456',
'region': 'north-america'
}
}
]
},
'expiryTime': 3600000
}
)
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.List;
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
Map requestBody = Map.of(
"clientId", "user-456",
"dataAppName", "sales-dashboard",
"params", Map.of(
"rlsSettings", List.of(
Map.of(
"metricId", "metric_123",
"values", Map.of(
"customer_id", "456",
"region", "north-america"
)
)
)
),
"expiryTime", 3600000
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/guest-token/create"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(requestBody)))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'user-456',
'dataAppName' => 'sales-dashboard',
'params' => [
'rlsSettings' => [
[
'metricId' => 'metric_123',
'values' => [
'customer_id' => '456',
'region' => 'north-america'
]
]
]
],
'expiryTime' => 3600000
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/guest-token/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/guest-token/create')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
clientId: 'user-456',
dataAppName: 'sales-dashboard',
params: {
rlsSettings: [
{
metricId: 'metric_123',
values: {
customer_id: '456',
region: 'north-america'
}
}
]
},
expiryTime: 3600000
}.to_json
response = http.request(request)
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"net/http"
)
type RLSValue struct {
CustomerID string `json:"customer_id"`
Region string `json:"region"`
}
type RLSSetting struct {
MetricID string `json:"metricId"`
Values RLSValue `json:"values"`
}
type Params struct {
RLSSettings []RLSSetting `json:"rlsSettings"`
}
type RequestBody struct {
ClientID string `json:"clientId"`
DataAppName string `json:"dataAppName"`
Params Params `json:"params"`
ExpiryTime int `json:"expiryTime"`
}
func main() {
requestBody := RequestBody{
ClientID: "user-456",
DataAppName: "sales-dashboard",
Params: Params{
RLSSettings: []RLSSetting{
{
MetricID: "metric_123",
Values: RLSValue{
CustomerID: "456",
Region: "north-america",
},
},
},
},
ExpiryTime: 3600000,
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/guest-token/create", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
```
```csharp C# icon="fa-solid fa-code" theme={"dark"}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class GuestTokenRequest
{
[JsonProperty("clientId")]
public string ClientId { get; set; }
[JsonProperty("dataAppName")]
public string DataAppName { get; set; }
[JsonProperty("params")]
public Params Params { get; set; }
[JsonProperty("expiryTime")]
public int ExpiryTime { get; set; }
}
public class Params
{
[JsonProperty("rlsSettings")]
public RLSSetting[] RlsSettings { get; set; }
}
public class RLSSetting
{
[JsonProperty("metricId")]
public string MetricId { get; set; }
[JsonProperty("values")]
public Values Values { get; set; }
}
public class Values
{
[JsonProperty("customer_id")]
public string CustomerId { get; set; }
[JsonProperty("region")]
public string Region { get; set; }
}
var client = new HttpClient();
var request = new GuestTokenRequest
{
ClientId = "user-456",
DataAppName = "sales-dashboard",
Params = new Params
{
RlsSettings = new[]
{
new RLSSetting
{
MetricId = "metric_123",
Values = new Values
{
CustomerId = "456",
Region = "north-america"
}
}
}
},
ExpiryTime = 3600000
};
var json = JsonConvert.SerializeObject(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer dbn_live_abc123...");
var response = await client.PostAsync("https://api.usedatabrain.com/api/v2/guest-token/create", content);
```
```bash cURL (Dashboard Filters) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-789",
"dataAppName": "regional-analytics",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard_abc123",
"values": {
"region": ["north-america", "europe"],
"timePeriod": {
"startDate": "2024-01-01",
"endDate": "2024-12-31"
},
"revenue": {
"min": 10000,
"max": 500000
}
},
"isShowOnUrl": false
}
]
},
"expiryTime": 7200000
}'
```
```bash cURL (Permissions + Private Metrics) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "tenant-456",
"dataAppName": "self-service-analytics",
"params": {
"userIdentifier": "analyst_john_123",
"timezone": "America/New_York",
"appFilters": [
{
"metricId": "metric_abc",
"values": {
"paid_orders": true,
"amount": 1000,
"countries": ["USA", "CANADA"]
}
}
],
"hideDashboardFilters": ["internal_cost", "profit_margin"]
},
"permissions": {
"isEnableArchiveMetrics": true,
"isEnableManageMetrics": true,
"isEnableMetricUpdation": true,
"isEnableCustomizeLayout": true,
"isEnableUnderlyingData": false,
"isEnableDownloadMetrics": true,
"isDisableMetricCreation": false
}
}'
```
```bash cURL (Multi-Datasource) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "production-client",
"dataAppName": "enterprise-bi",
"datasourceName": "production_replica_west",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "ops_dashboard",
"values": {
"environment": "production"
}
}
]
},
"expiryTime": 3600000
}'
```
```json 200 - Success theme={"dark"}
{
"token": "3affda8b-7bd4-4a88-9687-105a94cfffab"
}
```
```json 400 - Bad Request theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_NAME",
"message": "invalid data app name, data app name not found",
"status": 400
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid or missing API key",
"status": 401
}
}
```
## Response
UUID token for authentication. Pass this to your frontend component for embedding.
Error object if the request failed, otherwise `null` for successful requests.
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Request succeeded |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `403` | **Forbidden** - Access denied to resource |
| `404` | **Not Found** - Resource not found |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - Server error occurred |
## Error Codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing API key |
| `INVALID_REQUEST_BODY` | 400 | Missing, invalid, or unknown parameters (unrecognized fields are rejected) |
| `CLIENT_ID_ERROR` | 400 | Invalid clientId format or value |
| `INVALID_DATA_APP_NAME` | 400 | `dataAppName` doesn't match any Data App (case-sensitive) |
| `WORKSPACE_ID_ERROR` | 404 | Workspace not found or inaccessible |
| `DASHBOARD_PARAM_ERROR` | 400 | Invalid dashboard filter parameters or a `hideDashboardMetrics` dashboard outside the API token's data app/workspace scope |
| `INVALID_METRIC_ID` | 400 | A `hideDashboardMetrics.metricIds` value is not present on the specified dashboard |
| `APP_FILTER_PARAM_ERROR` | 400 | Invalid app filter configuration |
| `RLS_SETTINGS_PARAM_ERROR` | 400 | Invalid RLS settings |
| `DATASOURCE_NAME_ERROR` | 400 | `datasourceName` doesn't resolve |
| `DATAMART_NAME_ERROR` | 400 | `datamartName` doesn't resolve |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
These are the mint-time errors from this endpoint. At embed runtime (after minting), the distinct errors are `INVALID_TOKEN` (token not found in this deployment), `TOKEN_EXPIRED`, `UNAUTHORIZED_ORIGIN`, `UNAUTHORIZED`, and `INVALID_ID` — see the [Error Codes Reference](/developer-docs/reference/error-codes). Rate limiting surfaces as HTTP `429` with a `Retry-After` header (see [Rate Limiting](/developer-docs/rate-limiting)).
## Quick Start Guide
**Rate Limiting**: API requests are limited to prevent abuse. Implement exponential backoff for rate limited requests (429 status).
## Next Steps
Create embed configurations for your data apps
Create data apps and get your API tokens
Learn how to embed dashboards in your app
Learn more about API token management
# Update Data App
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-data-app
PUT https://api.usedatabrain.com/api/v2/data-app
Update the name and settings of an existing Data App.
Update the name and configuration of an existing Data App. This is useful for renaming Data Apps or updating their settings.
Updating a Data App name will not affect existing embed configurations or API tokens. They will continue to work with the renamed Data App.
**Authentication Requirement:** This endpoint requires a **service token** (not a data app API key). Service tokens have elevated permissions to manage Data Apps across your organization.
## Endpoint Formats
```
PUT https://api.usedatabrain.com/api/v2/data-app
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
PUT https://api.usedatabrain.com/api/v2/dataApp
```
This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token (not data app API key).
```
Authorization: Bearer service_token_xyz...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The current name of the Data App to update. This must exactly match an existing Data App name.
* Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to get all Data App names
* Check your Databrain dashboard for Data App configurations
* The name is case-sensitive
The new name for the Data App. This name must be unique within your organization.
* Names must be unique within your organization
* Use descriptive names that indicate the purpose (e.g., "Customer Portal Analytics", "Partner Dashboard")
* Avoid special characters that might cause URL encoding issues
## Response
The updated name of the Data App.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Customer Analytics",
"updateName": "Updated Customer Analytics"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app', {
method: 'PUT',
headers: {
'Authorization': 'Bearer service_token_xyz...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Customer Analytics',
updateName: 'Updated Customer Analytics'
})
});
const data = await response.json();
console.log('Updated Data App:', data.name);
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
url = "https://api.usedatabrain.com/api/v2/data-app"
headers = {
"Authorization": "Bearer service_token_xyz...",
"Content-Type": "application/json"
}
payload = {
"name": "Customer Analytics",
"updateName": "Updated Customer Analytics"
}
response = requests.put(url, headers=headers, json=payload)
data = response.json()
print(f"Updated Data App: {data['name']}")
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class UpdateDataApp {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"name": "Customer Analytics",
"updateName": "Updated Customer Analytics"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app"))
.header("Authorization", "Bearer service_token_xyz...")
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println("Response: " + response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type UpdateDataAppRequest struct {
Name string `json:"name"`
UpdateName string `json:"updateName"`
}
type UpdateDataAppResponse struct {
Name string `json:"name"`
Error interface{} `json:"error"`
}
func main() {
requestBody := UpdateDataAppRequest{
Name: "Customer Analytics",
UpdateName: "Updated Customer Analytics",
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("PUT", "https://api.usedatabrain.com/api/v2/data-app", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer service_token_xyz...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result UpdateDataAppResponse
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("Updated Data App: %s\n", result.Name)
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Customer Analytics',
'updateName' => 'Updated Customer Analytics'
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/data-app',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer service_token_xyz...',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
echo 'Updated Data App: ' . $result['name'];
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer service_token_xyz...'
request['Content-Type'] = 'application/json'
request.body = {
name: 'Customer Analytics',
updateName: 'Updated Customer Analytics'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Updated Data App: #{result['name']}"
```
```json 200 - Success theme={"dark"}
{
"name": "Updated Customer Analytics"
}
```
```json 400 - Invalid Request Body theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"updateName\" is required"
}
}
```
```json 400 - Data App Not Found theme={"dark"}
{
"error": {
"code": "DATA_APP_NOT_FOUND",
"message": "Data app not found"
}
}
```
```json 400 - Invalid Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid Service Token"
}
}
```
```json 500 - Internal Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "INTERNAL_SERVER_ERROR"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Data App updated successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | -------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid parameters |
| `DATA_APP_NOT_FOUND` | 400 | Data App with specified name not found |
| `AUTHENTICATION_ERROR` | 400 | Invalid or missing service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
In **Settings** page, navigate to the **Service Tokens** section. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use the [List Data Apps](/developer-docs/helpers/api-reference/list-data-apps) API to verify the current Data App configuration:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
Make a PUT request with the current name and the new name:
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app \
--header 'Authorization: Bearer service_token_xyz...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Current Data App Name",
"updateName": "New Data App Name"
}'
```
List Data Apps again to confirm the update:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app' \
--header 'Authorization: Bearer service_token_xyz...'
```
## Next Steps
View all Data Apps in your organization
Create new Data Apps for your organization
Remove Data Apps you no longer need
Generate API tokens for your Data Apps
# Update Datamart
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-datamart
PUT https://api.usedatabrain.com/api/v2/data-app/datamarts
Update an existing datamart's table configurations and tenancy settings without recreating from scratch.
Update the table list and tenancy settings of an existing datamart. This endpoint allows you to modify which tables and columns are accessible through the datamart, as well as update multi-tenant configurations.
**Destructive Operation:** Updating a datamart will delete all existing table and column configurations before applying the new ones. Ensure your new configuration includes all tables and columns you need.
The datamart name identifies which datamart to update and cannot be changed through this endpoint. To rename a datamart, you'll need to delete the old one and create a new one with the desired name.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the existing datamart to update. Must match exactly (case-sensitive).
* Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to get all datamart names
* Names are case-sensitive and must match exactly
* This field identifies which datamart to update (cannot be used to rename)
Array of tables with columns to include in the datamart. Optional - if not provided, only tenancy settings will be updated.
**Replaces all existing tables:** The new table list completely replaces the existing configuration. Include all tables you want to keep.
Table name from your datasource. Must exist in the datasource schema.
Optional schema name (required only for schema-based datasources like PostgreSQL, SQL Server).
Optional column name in this table that identifies the client/tenant. This column is used for multi-tenant data isolation at the table level. Must exist in the table schema.
* Used for table-level tenancy when `tenancyLevel` is `TABLE`
* The column should contain client/tenant identifiers
Optional flag to hide the table from the datamart interface.
Optional label for the table to provide a human-readable display name. When provided, this label can be used in the UI instead of the technical table name for better readability.
* Provides a user-friendly display name for the table
* Useful when table names are cryptic or technical
* Does not affect the actual table reference in queries
Optional wildcard index pattern for OpenSearch tables. When set, this value is used as the table name in queries, enabling you to query multiple OpenSearch indices that match a pattern.
* Only applicable to **OpenSearch** datasources
* Accepts a valid OpenSearch index wildcard pattern (e.g., `logs-*`, `events-2024-*`)
* When set, the wildcard value is used instead of the exact `name` when constructing the FROM clause
* Allows a single datamart table to cover multiple time-partitioned or sharded OpenSearch indices
List of column objects for this table. Must be non-empty.
Column name from the table. Must exist in the datasource schema.
Optional alias for the column to display a different name.
Optional label for the column for better readability.
Optional flag to hide the column from the datamart interface. Defaults to `false`.
Optional flag to mark this as a custom/calculated column. When `true`, the `sql` field is required to define the column's SQL expression.
* Custom columns allow you to define calculated fields using SQL expressions
* The `name` field should reference an existing column from the datasource schema
* Use the `alias` field to give the calculated column a custom display name
* The SQL expression can reference other columns from the same table
* Useful for derived metrics, concatenations, or transformations
SQL expression that defines the calculated value for a custom column. **Required when** `isCustomColumn` is `true`. The expression can reference other columns from the same table.
* Simple calculation: `quantity * unit_price`
* Date extraction: `EXTRACT(YEAR FROM order_date)`
* String concatenation: `CONCAT(first_name, ' ', last_name)`
* Case statement: `CASE WHEN status = 'active' THEN 1 ELSE 0 END`
Optional flag to indicate if this column should be treated as an aggregate column. When `true`, the column is marked as `AGGREGATE` drop type for metric calculations.
* Aggregate columns are used for pre-aggregated metrics
* Affects how the column behaves in metric calculations and drag-drop operations
* Common for SUM, COUNT, AVG type pre-calculated values
Optional flag to enable default aggregation for the column. When `true`, Databrain uses the value set in `defaultAggregation` when the column is added as a measure.
Optional field to define the default aggregation applied to the column when used as a measure.
```json theme={"dark"}
{
"allowAggregate": true,
"defaultAggregation": "COUNT_DISTINCT"
}
```
Optional flag to enable timezone conversion for this column. When `true`, the column's datetime values are converted using the timezone passed as `params.timezone` in the guest token at query execution time.
This field has no effect unless `params.timezone` is set in the guest token. See [Timezone Handling in Guest Token](/developer-docs/solutions-alchemy/guest-token-timezone) for the full setup guide.
* Apply to datetime or timestamp columns that store values in UTC or a fixed timezone
* The timezone is sourced from `params.timezone` in the guest token — not a user or workspace setting
* Supported datasources: Postgres, CockroachDB, Trino, Athena, BigQuery, MSSQL, OpenSearch, Databricks, Clickhouse, Redshift, Snowflake
* Has no effect on non-datetime column types
Optional default sort direction for the column. Supported values are `ASC` and `DESC`. The value is propagated to data-app embed access settings and used as the initial sort direction when this column is selected during metric creation.
Pass an empty string (`""`) or `null`, or omit this field on a submitted column, to clear its default sort. Values are case-sensitive; lowercase values such as `"asc"` fail validation.
Multi-tenant configuration for the datamart. Optional - if not provided, existing tenancy settings remain unchanged.
* **TABLE level**: Uses a dedicated table to map client identifiers
* **DATABASE level**: Each client has a separate database
* **MULTI\_DATABASE level**: Supports multi-database tenancy with optional primary database routing
* All fields are optional; omitted fields retain their existing values
The level at which tenant isolation occurs. Must be one of: `TABLE`, `DATABASE`, or `MULTI_DATABASE`.
* `TABLE`: Client mapping is stored in a specific table (most common)
* `DATABASE`: Each client has a separate database instance
* `MULTI_DATABASE`: Tenancy spans multiple databases with optional default routing via `primaryDatabase`
**Optional:** If not provided, existing tenancy level is retained.
Data type of the client identifier column. Must be either `NUMBER` or `STRING`.
**Required when** `tenancySettings.tenancyLevel` is set to `TABLE` in the request.
Optional primary database name used for `DATABASE` and `MULTI_DATABASE` tenancy levels.
* If `tenancyLevel` is `DATABASE` or `MULTI_DATABASE`, this value is stored (or `null` when omitted).
* In update requests, if `tenancySettings` is sent without `tenancyLevel`, backend logic clears `primaryDatabase` to `null`.
* If `tenancyLevel` is `TABLE`, backend logic also clears `primaryDatabase` to `null`.
To avoid accidental clearing, include `tenancySettings.tenancyLevel` whenever you send `tenancySettings`.
Schema name where the client mapping table is located.
**Required when** `tenancySettings.tenancyLevel` is set to `TABLE` in the request.
Name of the table that contains client mapping information.
**Required when** `tenancySettings.tenancyLevel` is set to `TABLE` in the request.
Column name in the mapping table that stores the client identifier.
**Required when** `tenancySettings.tenancyLevel` is set to `TABLE` in the request.
Primary key column of the client mapping table.
**Required when** `tenancySettings.tenancyLevel` is set to `TABLE` in the request.
Optional array of table relationships to define how tables in the datamart are connected. Relationships enable joins between tables for more complex queries.
**Replaces all existing relationships:** When provided, the relationships array completely replaces all existing relationships. Include all relationships you want to keep. If omitted entirely, existing relationships remain unchanged.
* Define how tables relate to each other (e.g., orders.customer\_id → customers.id)
* Supports different join types and cardinalities
* Useful for creating metrics that span multiple tables
* Optional - omit this field to keep existing relationships unchanged
Name of the parent table in the relationship.
Column name in the parent table that participates in the relationship.
Name of the child table in the relationship.
Column name in the child table that participates in the relationship.
A descriptive name for the relationship (e.g., "orders\_to\_customers").
The cardinality of the relationship. Must be one of: `ManyToMany`, `ManyToOne`, `OneToMany`, `OneToOne`.
**Optional:** Can be omitted or set to `null` if not specified.
The type of SQL join to use. Must be one of: `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN`.
**Optional:** Can be omitted or set to `null` if not specified.
## Response
The name of the updated datamart (same as the input datamartName) on success.
Error object returned only when the request fails. Not included in successful responses.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Update Tables Only theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "demo-sales-default-1",
"tableList": [
{
"schemaName": "databrain_dev2",
"name": "demo_sales",
"clientColumn": "client id",
"isHide": false,
"columns": [
{
"name": "client id",
"alias": "id",
"isHide": true
},
{
"name": "client name",
"alias": "name",
"isHide": true,
"defaultSort": "ASC"
},
{
"name": "profit",
"alias": "profit",
"allowAggregate": true,
"defaultAggregation": "SUM"
}
]
}
]
}'
```
```bash cURL - Update Tenancy Settings Only theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "clients",
"tableClientNameColumn": "client_name",
"tablePrimaryKeyColumn": "id"
}
}'
```
```bash cURL - Update to Multi-Database Tenancy theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tenancySettings": {
"tenancyLevel": "MULTI_DATABASE",
"primaryDatabase": "core_analytics"
}
}'
```
```bash cURL - Update Both Tables and Tenancy theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"clientColumn": "tenant_id",
"isHide": false,
"columns": [
{"name": "order_id", "alias": "id", "isHide": false},
{"name": "customer_id", "isHide": false}
]
}
],
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "NUMBER",
"schemaName": "public",
"tableName": "client_mapping",
"tableClientNameColumn": "client_id",
"tablePrimaryKeyColumn": "id"
},
"relationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}'
```
```bash cURL - Update Relationships Only theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"relationships": [
{
"parentTableName": "orders",
"parentColumnName": "customer_id",
"childTableName": "customers",
"childColumnName": "id",
"relationshipName": "orders_to_customers",
"cardinality": "ManyToOne",
"join": "LEFT JOIN"
}
]
}'
```
```bash cURL - Add Custom Columns theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Customer Orders",
"columns": [
{
"name": "order_id",
"alias": "id",
"label": "Order ID"
},
{
"name": "quantity",
"label": "Quantity"
},
{
"name": "unit_price",
"alias": "total_revenue",
"label": "Total Revenue",
"isCustomColumn": true,
"sql": "quantity * unit_price"
},
{
"name": "order_date",
"alias": "order_year",
"label": "Order Year",
"isCustomColumn": true,
"sql": "EXTRACT(YEAR FROM order_date)"
},
{
"name": "created_at",
"label": "Created At",
"isApplyTimezone": true
}
]
}
]
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tableList: [
{
schemaName: 'public',
name: 'orders',
label: 'Customer Orders',
clientColumn: 'tenant_id',
columns: [
{ name: 'order_id', alias: 'id', label: 'Order ID' },
{ name: 'customer_id', label: 'Customer' },
{ name: 'order_date', alias: 'date', label: 'Order Date' }
]
}
]
})
});
const result = await response.json();
if (result.error) {
console.error('Update failed:', result.error.message);
} else {
console.log('Datamart updated:', result.id);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.put(
'https://api.usedatabrain.com/api/v2/data-app/datamarts',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tableList': [
{
'schemaName': 'public',
'name': 'orders',
'label': 'Customer Orders',
'clientColumn': 'tenant_id',
'columns': [
{'name': 'order_id', 'alias': 'id', 'label': 'Order ID'},
{'name': 'customer_id', 'label': 'Customer'}
]
}
],
'tenancySettings': {
'tenancyLevel': 'TABLE',
'clientColumnType': 'STRING',
'schemaName': 'public',
'tableName': 'client_mapping',
'tableClientNameColumn': 'client_id',
'tablePrimaryKeyColumn': 'id'
},
'relationships': [
{
'parentTableName': 'orders',
'parentColumnName': 'customer_id',
'childTableName': 'customers',
'childColumnName': 'id',
'relationshipName': 'orders_to_customers',
'cardinality': 'ManyToOne',
'join': 'LEFT JOIN'
}
]
}
)
result = response.json()
if result.get('error'):
print(f"Update failed: {result['error']['message']}")
else:
print(f"Datamart updated: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tableList: [
{
schemaName: 'public',
name: 'orders',
label: 'Customer Orders',
columns: [
{ name: 'order_id', alias: 'id', label: 'Order ID' },
{ name: 'customer_id', label: 'Customer' }
]
}
]
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
if result['error']
puts "Update failed: #{result['error']['message']}"
else
puts "Datamart updated: #{result['id']}"
end
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type UpdateDatamartRequest struct {
DatamartName string `json:"datamartName"`
TableList []TableInfo `json:"tableList,omitempty"`
TenancySettings *TenancySettings `json:"tenancySettings,omitempty"`
}
type TableInfo struct {
SchemaName string `json:"schemaName,omitempty"`
Name string `json:"name"`
Label string `json:"label,omitempty"`
Columns []ColumnInfo `json:"columns"`
}
type ColumnInfo struct {
Name string `json:"name"`
Alias string `json:"alias,omitempty"`
Label string `json:"label,omitempty"`
IsHide bool `json:"isHide,omitempty"`
}
type TenancySettings struct {
TenancyLevel string `json:"tenancyLevel,omitempty"`
ClientColumnType string `json:"clientColumnType,omitempty"`
SchemaName string `json:"schemaName,omitempty"`
TableName string `json:"tableName,omitempty"`
TableClientNameColumn string `json:"tableClientNameColumn,omitempty"`
TablePrimaryKeyColumn string `json:"tablePrimaryKeyColumn,omitempty"`
}
func main() {
reqData := UpdateDatamartRequest{
DatamartName: "sales-analytics",
TableList: []TableInfo{
{
SchemaName: "public",
Name: "orders",
Label: "Customer Orders",
Columns: []ColumnInfo{
{Name: "order_id", Alias: "id", Label: "Order ID"},
{Name: "customer_id", Label: "Customer"},
},
},
},
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("PUT",
"https://api.usedatabrain.com/api/v2/data-app/datamarts",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Datamart updated successfully")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics',
'tableList' => [
[
'schemaName' => 'public',
'name' => 'orders',
'label' => 'Customer Orders',
'columns' => [
[
'name' => 'order_id',
'alias' => 'id',
'label' => 'Order ID'
],
[
'name' => 'customer_id',
'label' => 'Customer'
]
]
]
]
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'PUT',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
if (isset($result['error'])) {
echo "Update failed: " . $result['error']['message'];
} else {
echo "Datamart ID: " . $result['id'];
}
?>
```
```json 200 - Success theme={"dark"}
{
"id": "sales-analytics"
}
```
```json 400 - Datamart Not Found theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART",
"message": "invalid datamart name."
}
}
```
```json 400 - Invalid Table Structure theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid table or column structure"
}
}
```
```json 400 - Invalid Schema or Table theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid schema or table name"
}
}
```
```json 400 - Invalid Column Names theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid column names in table"
}
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Datamart updated successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ----------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid parameters |
| `INVALID_DATAMART` | 400 | Datamart not found |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
Retrieve the existing datamart configuration before making changes:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts?isPagination=false' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Save this response in case you need to rollback your changes.
Determine what you want to update:
* **Tables/Columns**: Prepare the complete new tableList (replaces existing)
* **Tenancy**: Prepare updated tenancySettings (optional)
* **Both**: You can update both in a single request
If only updating tenancy, omit the tableList field to keep existing tables intact.
Make the update request:
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tableList": [
{
"schemaName": "public",
"name": "orders",
"label": "Customer Orders",
"clientColumn": "tenant_id",
"columns": [
{"name": "order_id", "alias": "id"},
{"name": "customer_id"}
]
}
]
}'
```
Successful response returns the datamart name.
Test that the datamart works correctly:
* Load metrics that use this datamart
* Check that all expected tables and columns are accessible
* Verify tenancy is working if you updated those settings
* Monitor for any errors in your dashboards
If metrics break, you can update again with your saved previous configuration to rollback.
## Next Steps
Create a new datamart from scratch
View all datamarts in your organization
Remove datamarts you no longer need
Learn more about datamarts
# Update Datasource
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-datasource
PUT https://api.usedatabrain.com/api/v2/datasource
Update the credentials and configuration of an existing datasource. The API validates and tests the new credentials before applying changes.
Update an existing datasource's credentials or configuration. The API validates the new credentials, tests the connection, and automatically refreshes the cached schema.
You can only update datasources that already exist in your organization. The datasource is identified by the `name` field in the credentials. After updating, the schema will be automatically re-cached.
## Endpoint
```
PUT https://api.usedatabrain.com/api/v2/datasource
```
## Self-hosted Databrain Endpoint
```
PUT /api/v2/datasource
```
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
```bash Authentication theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json'
```
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The type of datasource. Must match the existing datasource type. See [Create Datasource](/developer-docs/helpers/api-reference/create-datasource) for supported types.
Updated connection credentials for the datasource. Must include the `name` field matching the existing datasource name.
The `credentials.name` field must match the exact name of the existing datasource you want to update. This name is used to identify which datasource to update.
The name of the existing datasource to update. Must match exactly as it was created.
* Use the [List Datasources API](/developer-docs/helpers/api-reference/list-datasources) to see all datasource names
* Check the response from datasource creation
* Available in the DataBrain dashboard when viewing datasources
Multi-tenant configuration for the datasource. Defines how data is isolated between different tenants/clients. Optional - if not provided, existing tenancy settings will remain unchanged.
* **TABLE level**: Uses a dedicated table to map client identifiers
* **DATABASE level**: Each client has a separate database
* If the datasource doesn't have existing tenancy settings, new settings will be created
* If tenancy settings already exist, they will be updated with the new values
The level at which tenant isolation occurs. Must be one of: `TABLE` or `DATABASE`.
* `TABLE`: Client mapping is stored in a specific table (most common)
* `DATABASE`: Each client has a separate database instance
**Required when** `tenancySettings` is provided. If `tenancySettings` is omitted, this field is not needed.
Data type of the client identifier column. Must be either `NUMBER` or `STRING`.
**Required when** `tenancyLevel` is `TABLE`.
Schema name where the client mapping table is located.
**Required when** `tenancyLevel` is `TABLE`.
Name of the table that contains client mapping information.
**Required when** `tenancyLevel` is `TABLE`.
Column name in the mapping table that stores the client identifier.
**Required when** `tenancyLevel` is `TABLE`.
Primary key column of the client mapping table.
**Required when** `tenancyLevel` is `TABLE`.
### Datasource-Specific Credentials
You must provide all required fields for the datasource type, even if only some values are changing. Partial updates are not supported.
When updating credentials, provide the complete credential structure for the datasource type. Partial updates are not supported.
Datasource-specific credential fields. The required fields depend on the `datasourceType`.
Snowflake account hostname (e.g., `your-account.snowflakecomputing.com`)
Snowflake username
Snowflake role to use
Snowflake warehouse name
Snowflake database name
Snowflake schema name
Authentication method: `"username/password"` or `"Key-pair authentication"`
Password (required if credentials is `"username/password"`)
Private key (required if credentials is `"Key-pair authentication"`)
Passphrase for the private key (optional)
Database hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Schema name
Enable SSL mode (optional)
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH server hostname (required if sshTunnel is `"enable"`)
SSH server port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
CockroachDB hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Schema name
Enable SSL mode (optional)
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH server hostname (required if sshTunnel is `"enable"`)
SSH server port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
JSON string containing Google Cloud service account credentials
Google Cloud project ID
BigQuery dataset location (e.g., `"US"`, `"EU"`)
BigQuery dataset ID (optional)
Database hostname or IP address
Database port number (1-65535)
Database username. Note: Uses `user` not `username` for these datasource types.
Database password
SQL Server hostname or IP address. Note: Uses `server` not `host` for MSSQL.
Database port number (1-65535)
Database username. Note: Uses `user` not `username` for MSSQL.
Database password
Database name (optional)
Disable database selection (optional)
Optional MSSQL read-only routing hint. When `true`, Databrain connects with read-only intent for MSSQL workloads.
Database hostname or IP address
Database port number (1-65535)
Database username
Database password
Database name
Databricks server hostname
Databricks HTTP path
Databricks access token
Server type: `"elastic-cloud"`, `"open-cloud"`, or `"self-managed"`
Cloud ID (required if server\_type is `"elastic-cloud"` or `"open-cloud"`)
Server URL (required if server\_type is `"self-managed"`)
Username (required unless `disableAuth` is `true`)
Password (required unless `disableAuth` is `true`)
Disable authentication (optional, default `false`). Only valid when server\_type is `"self-managed"`.
Ignore certificate verification (optional)
Ignore SSL (optional)
Server type: `"elastic-cloud"`, `"open-cloud"`, or `"self-managed"`
Cloud ID (required if server\_type is `"elastic-cloud"` or `"open-cloud"`)
Server URL (required if server\_type is `"self-managed"`)
Username (required unless `disableAuth` is `true`)
Password (required unless `disableAuth` is `true`)
Disable authentication (optional, default `false`). Only valid when server\_type is `"self-managed"`.
Ignore certificate verification (optional)
Ignore SSL (optional)
Firebolt client ID
Firebolt client secret
Firebolt account name
Database name
Engine name
Schema name (optional)
Athena database name
S3 output bucket for query results
AWS access key ID
AWS region
AWS secret access key
Datasource ID (optional)
Trino hostname or IP address
Database port number (1-65535)
Trino catalog name
Schema name
Username
Password
SSH tunnel setting: `"enable"` or `"disable"` (optional)
SSH host (required if sshTunnel is `"enable"`)
SSH port (required if sshTunnel is `"enable"`)
SSH username (required if sshTunnel is `"enable"`)
SSH private key (required if sshTunnel is `"enable"`)
Name for the CSV datasource
S3 bucket name
Path within the bucket (optional, can be empty string)
AWS region (e.g., `"us-east-1"`)
Table level: `"File"` or `"Folder"` (optional)
AWS access key ID
AWS secret access key
## Response
The name of the updated datasource (same as credentials.name).
Error field, null when successful. Not included in successful responses.
## Examples
```bash cURL - PostgreSQL Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "postgres",
"credentials": {
"name": "production-postgres",
"host": "new-db.example.com",
"port": 5432,
"username": "dbuser",
"password": "newpassword",
"database": "analytics",
"schema": "public"
}
}'
```
```bash cURL - Snowflake Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "snowflake",
"credentials": {
"name": "analytics-snowflake",
"host": "account.snowflakecomputing.com",
"username": "user@example.com",
"role": "ANALYST",
"warehouse": "COMPUTE_WH",
"database": "ANALYTICS",
"schema": "PUBLIC",
"credentials": "username/password",
"password": "updatedpassword"
}
}'
```
```bash cURL - MSSQL Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "mssql",
"credentials": {
"name": "production-mssql",
"server": "sqlserver.example.com",
"port": 1433,
"user": "sqluser",
"password": "updatedpassword",
"database": "analytics",
"readOnlyIntent": true
}
}'
```
```bash cURL - CockroachDB Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "cockroachdb",
"credentials": {
"name": "production-cockroachdb",
"host": "cockroach.example.com",
"port": 26257,
"username": "dbuser",
"password": "updatedpassword",
"database": "analytics",
"schema": "public"
}
}'
```
```bash cURL - OpenSearch Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "opensearch",
"credentials": {
"name": "production-opensearch",
"server_type": "self-managed",
"server_url": "https://opensearch.example.com:9200",
"username": "admin",
"password": "updatedpassword"
}
}'
```
```bash cURL - Elasticsearch Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "elasticsearch",
"credentials": {
"name": "production-elasticsearch",
"server_type": "elastic-cloud",
"cloud_id": "my-deployment:dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyQ...",
"username": "elastic",
"password": "updatedpassword"
}
}'
```
```bash cURL - Trino Example theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "trino",
"credentials": {
"name": "production-trino",
"host": "trino.example.com",
"port": 8080,
"catalog": "hive",
"schema": "analytics",
"username": "trinouser",
"password": "updatedpassword"
}
}'
```
```bash cURL - Update With Tenancy Settings theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datasource \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datasourceType": "postgres",
"credentials": {
"name": "production-postgres",
"host": "db.example.com",
"port": 5432,
"username": "dbuser",
"password": "newpassword",
"database": "analytics",
"schema": "public"
},
"tenancySettings": {
"tenancyLevel": "TABLE",
"clientColumnType": "STRING",
"schemaName": "public",
"tableName": "clients",
"tableClientNameColumn": "client_name",
"tablePrimaryKeyColumn": "client_id"
}
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/datasource', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datasourceType: 'postgres',
credentials: {
name: 'production-postgres',
host: 'new-db.example.com',
port: 5432,
username: 'dbuser',
password: 'newpassword',
database: 'analytics',
schema: 'public'
}
})
});
const data = await response.json();
if (data.error) {
console.error('Error:', data.error);
} else {
console.log('Datasource updated:', data.name);
}
```
```python Python theme={"dark"}
import requests
response = requests.put(
'https://api.usedatabrain.com/api/v2/datasource',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datasourceType': 'postgres',
'credentials': {
'name': 'production-postgres',
'host': 'new-db.example.com',
'port': 5432,
'username': 'dbuser',
'password': 'newpassword',
'database': 'analytics',
'schema': 'public'
}
}
)
data = response.json()
if data.get('error'):
print('Error:', data['error'])
else:
print('Datasource updated:', data['name'])
```
```json 200 - Success theme={"dark"}
{
"name": "production-postgres"
}
```
```json 400 - Bad Request theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid credentials for postgres: \"host\" is required",
"status": 400
}
}
```
```json 400 - Datasource Not Found theme={"dark"}
{
"error": {
"code": "DATASOURCE_NAME_ERROR",
"message": "Invalid datasource name",
"status": 400
}
}
```
```json 400 - Connection Test Failed theme={"dark"}
{
"error": {
"code": "CREDENTIAL_TEST_FAILED",
"message": "Failed to connect to datasource",
"status": 400
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "AUTHENTICATION_ERROR",
"status": 401
}
}
```
```json 500 - Tenancy Settings Failed theme={"dark"}
{
"error": {
"code": "TENANCY_SETTINGS_UPDATE_FAILED",
"message": "Failed to update tenancy settings",
"status": 500
}
}
```
## Error Codes
| Error Code | HTTP Status | Description |
| -------------------------------- | ----------- | ------------------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing required fields or invalid credential structure |
| `DATASOURCE_NAME_ERROR` | 400 | Datasource not found |
| `CREDENTIAL_TEST_FAILED` | 400 | Connection test failed |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing service token |
| `SCHEMA_CACHE_FAILED` | 500 | Schema caching failed |
| `DATASOURCE_NOT_FOUND` | 404 | The specified datasource does not exist |
| `TENANCY_SETTINGS_CREATE_FAILED` | 500 | Failed to create tenancy settings for the datasource |
| `TENANCY_SETTINGS_UPDATE_FAILED` | 500 | Failed to update existing tenancy settings |
| `INTERNAL_SERVER_ERROR` | 500 | Server error occurred |
## Next Steps
View all datasources to verify the update
Manually sync the datasource schema if needed
Create a new datasource instead of updating
Remove a datasource you no longer need
# Update an Embed
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-embed
PUT https://api.usedatabrain.com/api/v2/data-app/embeds
Update an existing embed to modify access settings, permissions, and datamart associations.
Modify existing embeds to update access settings, change permissions, or associate with different datamarts. This allows you to evolve your embedded analytics without recreating configurations.
**Endpoint Migration Notice:** We're transitioning to kebab-case endpoints. The new endpoint is `/api/v2/data-app/embeds`. The old endpoint `/api/v2/dataApp/embeds` will be deprecated soon. Please update your integrations to use the new endpoint format.
Updates to embed configurations take effect immediately for all active embedded dashboards and metrics using this configuration.
## Endpoint Formats
```
PUT https://api.usedatabrain.com/api/v2/data-app/embeds
```
**Use this endpoint** for all new integrations. This is the recommended endpoint format.
```
POST https://api.usedatabrain.com/api/v2/dataApp/embed/update
Content-Type: application/json
{
"embedId": "embed_abc123def456",
"accessSettings": { ... }
}
```
This endpoint still works but will be deprecated. Uses POST method with JSON body.
## Authentication
All API requests must include your API key in the Authorization header. Get your API token when creating a data app - see our [data app creation guide](/guides/datasources/create-a-data-app) for details.
**Finding your API token:** For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
```bash Authentication theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_...' \
--header 'Content-Type: application/json'
```
## Headers
Bearer token for API authentication. Use your API key from the data app.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
The unique identifier of the embed configuration to update. Get this from the create embed response or list embeds API.
* Use the List All Embeds API to get embed IDs
* Check the response from embed creation
* Available in the DataBrain dashboard when viewing embed configurations
Updated access control settings for the embedded view. Only provided fields will be updated.
Change the datamart used by this embed configuration.
Update AI Pilot permission.
Update email reports permission.
Update metrics management permission.
Update metric creation permission.
Update metric deletion permission.
Update metric layout change permission.
Update metric modification permission.
Update underlying data access permission.
Update dashboard view creation permission.
Optional. Enable or disable end-user dashboard filter interactions.
Optional allowlist for dashboard filterable columns. Each item must include `tableName` and `columns`.
Fully qualified table name used in dashboard filters.
Column names allowed for dashboard filter evaluation for the specified table.
Optional. Enable or disable end-user metric filter interactions.
Optional allowlist for columns that end users can use in metric filters. Each item must include `tableName` and `columns`.
Fully qualified table name used in metric filters.
Column names allowed for metric filter evaluation for the specified table.
Recommended join strategy for table relationships.
* `single`: single worksheet mode (tables are pre-joined into one worksheet)
* `multi`: multi-sheet mode (joins are resolved dynamically based on fields used in each chart)
Legacy join strategy flag. Prefer using `accessSettings.joinModel` instead.
Update the metric creation mode.
Update multi-tenant table access configuration.
Table name for tenancy configuration.
Column name for client-level filtering.
## Response
The ID of the updated embed configuration.
Error object if the request failed, otherwise `null` for successful requests.
## Examples
```bash cURL theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_abc123def456",
"accessSettings": {
"isAllowMetricCreation": false,
"isAllowUnderlyingData": true,
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"joinModel": "multi",
"tableTenancySettings": [
{
"name": "updated_sales_data",
"clientColumn": "customer_id"
}
]
}
}'
```
```javascript Node.js theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/embeds', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
embedId: 'embed_abc123def456',
accessSettings: {
isAllowMetricCreation: false,
isAllowUnderlyingData: true,
isAllowEndUserDashboardFilter: true,
dashboardFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['customer_id', 'region', 'order_date']
}
],
isAllowEndUserMetricFilter: true,
metricFilterColumns: [
{
tableName: 'public.sales_data',
columns: ['region', 'order_date']
}
],
joinModel: 'multi',
tableTenancySettings: [
{
name: 'updated_sales_data',
clientColumn: 'customer_id'
}
]
}
})
});
const data = await response.json();
console.log('Updated embed ID:', data.id);
```
```python Python theme={"dark"}
import requests
import json
url = "https://api.usedatabrain.com/api/v2/data-app/embeds"
headers = {
"Authorization": "Bearer dbn_live_abc123...",
"Content-Type": "application/json"
}
payload = {
"embedId": "embed_abc123def456",
"accessSettings": {
"isAllowMetricCreation": False,
"isAllowUnderlyingData": True,
"isAllowEndUserDashboardFilter": True,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region", "order_date"]
}
],
"isAllowEndUserMetricFilter": True,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"joinModel": "multi",
"tableTenancySettings": [
{
"name": "updated_sales_data",
"clientColumn": "customer_id"
}
]
}
}
response = requests.put(url, headers=headers, data=json.dumps(payload))
data = response.json()
print(f"Updated embed ID: {data['id']}")
```
```json Success Response theme={"dark"}
{
"id": "embed_abc123def456",
"error": null
}
```
```json Error Response (404) theme={"dark"}
{
"error": {
"code": "EMBED_NOT_FOUND",
"message": "Embed configuration not found",
"status": 404,
"details": {
"embedId": "embed_invalid",
"workspace": "analytics-workspace"
}
}
}
```
```json Error Response (400) theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART",
"message": "Specified datamart does not exist in workspace",
"status": 400,
"details": {
"datamartName": "invalid-datamart",
"workspace": "analytics-workspace"
}
}
}
```
## Error Codes
**Embed configuration not found** - The specified embed ID doesn't exist in the workspace
**Workspace not found** - The specified workspace doesn't exist or you don't have access
**Invalid datamart** - The specified datamart doesn't exist in the workspace
**Insufficient permissions** - You don't have permission to update this embed configuration
**Invalid API key** - Check your API key in dashboard settings
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ----------------------------------------------------------- |
| `200` | **OK** - Embed configuration updated successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `403` | **Forbidden** - Insufficient permissions to update |
| `404` | **Not Found** - Embed configuration not found |
| `409` | **Conflict** - Update conflicts with existing configuration |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ------------------------------------- |
| `EMBED_NOT_FOUND` | 404 | Embed configuration not found |
| `INVALID_WORKSPACE_NAME` | 404 | Workspace not found |
| `INVALID_DATAMART` | 404 | Datamart not found |
| `INSUFFICIENT_PERMISSIONS` | 403 | No permission to update |
| `AUTHENTICATION_ERR` | 401 | Invalid API key |
| `INVALID_ACCESS_SETTINGS` | 400 | Invalid access settings |
| `CONFLICTING_UPDATE` | 409 | Update conflicts with existing config |
| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Update Strategies
Gradually increase permissions based on user needs:
```javascript theme={"dark"}
// Enable metric creation for power users
await updateEmbed({
embedId: 'embed_123',
accessSettings: {
isAllowMetricCreation: true,
metricCreationMode: 'CHAT'
}
});
```
Move embed to a different datamart:
```javascript theme={"dark"}
await updateEmbed({
embedId: 'embed_123',
accessSettings: {
datamartName: 'new-datamart'
}
});
```
Reduce permissions when needed:
```javascript theme={"dark"}
await updateEmbed({
embedId: 'embed_123',
accessSettings: {
isAllowMetricDeletion: false,
isAllowUnderlyingData: false
}
});
```
## Common Update Scenarios
### Enable Advanced Features
```javascript theme={"dark"}
// Upgrade basic embed to include AI features
await updateEmbed({
embedId: 'embed_basic',
accessSettings: {
isAllowEmailReports: true,
metricCreationMode: 'CHAT'
}
});
```
### Migrate to New Datamart
```javascript theme={"dark"}
// Move embed to updated datamart
await updateEmbed({
embedId: 'embed_old',
accessSettings: {
datamartName: 'updated-sales-data',
tableTenancySettings: [
{
name: 'new_customer_table',
clientColumn: 'tenant_id'
}
]
}
});
```
### Temporary Permission Reduction
```javascript theme={"dark"}
// Temporarily reduce permissions during maintenance
await updateEmbed({
embedId: 'embed_maintenance',
accessSettings: {
isAllowMetricCreation: false,
isAllowMetricUpdate: false,
isAllowMetricDeletion: false
}
});
```
## Best Practices
* Document all configuration changes
* Test updates in staging first
* Notify stakeholders of permission changes
* Maintain change history and rollback plans
* Follow principle of least privilege
* Regular permission audits
* Monitor for unauthorized changes
* Validate datamart access before updates
* Batch multiple updates when possible
* Monitor embed performance after changes
* Test with production data volumes
* Update during low-usage periods
* Communicate feature changes to users
* Provide training for new capabilities
* Gradual rollout of new permissions
* Collect feedback on configuration changes
## Advanced Configuration
### Dynamic Permission Updates
```javascript theme={"dark"}
// Update permissions based on user tier
const updatePermissionsForTier = async (embedId, userTier) => {
const permissions = {
basic: {
isAllowMetricCreation: false,
isAllowUnderlyingData: false
},
premium: {
isAllowMetricCreation: true,
isAllowUnderlyingData: true,
metricCreationMode: 'CHAT'
}
};
await updateEmbed({
embedId,
accessSettings: permissions[userTier]
});
};
```
### Bulk Updates
```javascript theme={"dark"}
// Update multiple embeds with same settings
const bulkUpdateEmbeds = async (embedIds, updates) => {
const promises = embedIds.map(embedId =>
updateEmbed({
embedId,
accessSettings: updates
})
);
const results = await Promise.all(promises);
return results;
};
```
## Quick Start Guide
List your existing embed configurations to find the one you want to update:
```bash theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Update only the settings you want to change. For example, to enable End User Metric Creation:
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_abc123def456",
"accessSettings": {
"isAllowMetricCreation": true
}
}'
```
Change the datamart associated with your embed:
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/embeds \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"embedId": "embed_abc123def456",
"accessSettings": {
"datamartName": "new-datamart-name"
}
}'
```
The API will return the embed ID on success:
```javascript theme={"dark"}
const updateResult = await updateEmbed({
embedId: 'embed_123',
accessSettings: { isAllowMetricCreation: true }
});
console.log('Updated embed ID:', updateResult.id);
console.log('Success:', !updateResult.error);
```
## Next Steps
Remove embed configurations you no longer need
View all embed configurations in your workspace
Create tokens for your updated embed configurations
Learn the basics of embedding DataBrain
# Update Embedded Filter Alias
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-filter-alias
Rename dashboard and metric filter labels for an embedded end user.
Update the label shown for an existing dashboard or metric filter in an embedded experience. These are end-user plugin APIs: authenticate with a guest token in `X-Plugin-Token`, not with a Data App API key.
Enable the matching rename permission in `params.accessPermissions` when you mint the guest token: `isAllowDashboardFilterNameChange` for dashboard filters or `isAllowMetricFilterNameChange` for metric filters.
## Endpoints
### Cloud Databrain
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/dashboard/updateDashboardFilterAlias
POST https://api.usedatabrain.com/api/v2/dashboard/updateMetricFilterAlias
```
### Self-hosted Databrain
```http theme={"dark"}
POST /api/v2/dashboard/updateDashboardFilterAlias
POST /api/v2/dashboard/updateMetricFilterAlias
```
## Authentication
Guest token generated by the [Guest Token API](/developer-docs/helpers/api-reference/token). The token determines the dashboard, metric, workspace, and client scope for the request.
Must be set to `application/json`.
## Update a dashboard filter alias
Dashboard identifier. The API accepts the dashboard's internal UUID or its external dashboard ID.
Case-insensitive dashboard filter key in the form `tableName.columnName`, for example `public.sales_data.region`. The filter must already exist and must not be a client-created dashboard filter.
New label for the filter. Leading and trailing whitespace is removed and the trimmed value can be at most 100 characters. Send an empty string to clear the alias.
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/dashboard/updateDashboardFilterAlias \
--header 'X-Plugin-Token: ' \
--header 'Content-Type: application/json' \
--data '{
"externalDashboard": "dashboard-uuid-or-external-id",
"filterKey": "public.sales_data.region",
"alias": "Sales region"
}'
```
## Update a metric filter alias
Metric identifier. The API accepts the metric's internal UUID or metric ID.
Case-insensitive metric filter key in the form `tableName.columnName`, for example `public.sales_data.region`. The filter must already exist.
New label for the filter. Leading and trailing whitespace is removed and the trimmed value can be at most 100 characters. Send an empty string to clear the alias.
```bash cURL theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/dashboard/updateMetricFilterAlias \
--header 'X-Plugin-Token: ' \
--header 'Content-Type: application/json' \
--data '{
"externalMetricId": "metric-uuid-or-id",
"filterKey": "public.sales_data.region",
"alias": "Sales region"
}'
```
## Response
Both endpoints return the updated alias in the `data` object:
```json theme={"dark"}
{
"data": {
"id": "alias_abc123",
"filterKey": "public.sales_data.region",
"alias": "Sales region"
}
}
```
When `alias` is an empty string, the endpoint removes the stored alias and returns:
```json theme={"dark"}
{
"data": {
"filterKey": "public.sales_data.region",
"alias": ""
}
}
```
## Status codes
| Status | Description |
| ------ | ----------------------------------------------------------------------------------------------------------------------- |
| `200` | Alias updated or cleared successfully. |
| `400` | Missing or invalid body fields, an unknown filter, or an alias longer than 100 characters. |
| `403` | The guest token is not authorized for the requested dashboard or metric, or the matching rename permission is disabled. |
| `404` | The dashboard or metric was not found in the guest token's authorized scope. |
| `500` | The alias could not be persisted or an unexpected server error occurred. |
# Update Semantic Layer
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-semantic-layer
PUT https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer
Update the semantic layer for a datamart by modifying table descriptions, column metadata, or feedback.
Modify the semantic layer metadata for an existing datamart. You can update table descriptions, column metadata, and feedback in a single request. Only the fields you include are updated — omitted tables and columns retain their existing values.
The datamart must already have a semantic layer. If no semantic data exists, this endpoint returns `404 SEMANTIC_LAYER_NOT_FOUND`. Use [POST](/developer-docs/helpers/api-reference/create-semantic-layer) to create a semantic layer first.
## Authentication
This endpoint requires a **service token** in the Authorization header. Data app API tokens are not permitted and will be rejected with a `403` error.
To access your service token:
1. Go to your Databrain dashboard and open **Settings**.
2. Navigate to **Settings**.
3. Find the **Service Tokens** section.
4. Click the **"Generate Token"** button to generate a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the existing datamart to update. Must match exactly (case-sensitive).
Array of table objects with updated semantic metadata. Only tables and columns included in the request are modified — others remain unchanged.
Table name from the datamart. Must match an existing table.
Updated description for the table. Maximum 500 characters.
Updated synonyms for the table. Maximum 10 synonyms, each up to 100 characters. Must be unique (case-insensitive).
Updated additional context. Maximum 1000 characters.
Array of column objects to update. Only listed columns are modified.
Column name from the table. Must match an existing column.
Updated description. Maximum 500 characters.
Updated synonyms. Maximum 10 synonyms, each up to 100 characters.
Updated additional context. Maximum 1000 characters.
Updated semantic column type. Must be one of: `String`, `Long String`, `String (Custom)`, `ENUM`, `Mapper`, `Range`, `Expression`, `Identifier`, `Number`, `JSON`. Must be compatible with the column's underlying datatype.
Updated configuration for the column type. Same shapes as [create](/developer-docs/helpers/api-reference/create-semantic-layer): object map for `String` / `String (Custom)` / `ENUM` / `Mapper`; `{ lowerLimit, upperLimit }` (numbers) for `Range`; string for `Expression` and `JSON`; `null` or omit for `Identifier`, `Number`, and `Long String`.
Updated identifier flag.
Updated indexing exclusion flag.
Updated global feedback text. Maximum 2000 characters. When provided, replaces the existing feedback.
## Response
On success, the response body contains only the datamart name. There is no `error` field in the JSON body when the request succeeds.
The name of the updated datamart (same as the input `datamartName`).
## Examples
```bash cURL - Update Tables & Feedback theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Updated: Customer purchase orders with status tracking",
"columns": [
{
"name": "status",
"description": "Order lifecycle status",
"synonyms": ["order status", "state", "order state"]
}
]
}
],
"feedback": "Updated context: All amounts in USD. Fiscal year starts April 1."
}'
```
```bash cURL - Update Feedback Only theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"datamartName": "sales-analytics",
"feedback": "Updated: All amounts in USD. Customer IDs are numeric."
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Updated order descriptions',
columns: [
{
name: 'status',
description: 'Order lifecycle status',
synonyms: ['order status', 'state']
}
]
}
],
feedback: 'Updated feedback text.'
})
});
const result = await response.json();
if (result.error) {
console.error('Update failed:', result.error.message);
} else {
console.log('Semantic layer updated:', result.id);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.put(
'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'datamartName': 'sales-analytics',
'tables': [
{
'name': 'orders',
'description': 'Updated order descriptions',
'columns': [
{
'name': 'status',
'description': 'Order lifecycle status',
'synonyms': ['order status', 'state']
}
]
}
],
'feedback': 'Updated feedback text.'
}
)
result = response.json()
if result.get('error'):
print(f"Update failed: {result['error']['message']}")
else:
print(f"Semantic layer updated: {result['id']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
datamartName: 'sales-analytics',
tables: [
{
name: 'orders',
description: 'Updated order descriptions',
columns: [
{ name: 'status', description: 'Order lifecycle status' }
]
}
]
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
puts "Updated: #{result['id']}"
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class UpdateSemanticLayer {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"datamartName": "sales-analytics",
"tables": [
{
"name": "orders",
"description": "Updated order descriptions",
"columns": [
{
"name": "status",
"description": "Order lifecycle status"
}
]
}
],
"feedback": "Updated feedback text."
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body := map[string]interface{}{
"datamartName": "sales-analytics",
"tables": []map[string]interface{}{
{
"name": "orders",
"description": "Updated order descriptions",
"columns": []map[string]interface{}{
{
"name": "status",
"description": "Order lifecycle status",
},
},
},
},
"feedback": "Updated feedback text.",
}
jsonData, _ := json.Marshal(body)
req, _ := http.NewRequest("PUT",
"https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Semantic layer updated")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'sales-analytics',
'tables' => [
[
'name' => 'orders',
'description' => 'Updated order descriptions',
'columns' => [
[
'name' => 'status',
'description' => 'Order lifecycle status'
]
]
]
],
'feedback' => 'Updated feedback text.'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'PUT',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
echo "Updated: " . $result['id'];
?>
```
```json 200 - Success theme={"dark"}
{
"id": "sales-analytics"
}
```
```json 400 - Missing datamartName theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"datamartName\" is required"
}
}
```
```json 400 - No Section Provided theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"value\" must contain at least one of [tables, feedback]"
}
}
```
```json 400 - Invalid Table theme={"dark"}
{
"error": {
"code": "INVALID_TABLE",
"message": "Table 'nonexistent_table' not found in datamart 'sales-analytics'"
}
}
```
```json 404 - No Semantic Layer theme={"dark"}
{
"error": {
"code": "SEMANTIC_LAYER_NOT_FOUND",
"message": "No semantic layer found for datamart 'sales-analytics'. Use POST to create first."
}
}
```
```json 403 - Data App Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Semantic Layer API requires a service token, not a data app API token"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------------------ |
| `200` | **OK** — Semantic layer updated successfully |
| `400` | **Bad Request** — Validation failed (see error codes below) |
| `401` | **Unauthorized** — Invalid or missing API token |
| `403` | **Forbidden** — Data app token used instead of service token |
| `404` | **Not Found** — No semantic layer exists for this datamart |
| `500` | **Internal Server Error** — Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| ---------------------------- | ----------- | --------------------------------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing required fields or validation failure |
| `INVALID_DATAMART` | 400 | Datamart not found |
| `INVALID_TABLE` | 400 | Table name doesn't exist in the datamart |
| `INVALID_COLUMN` | 400 | Column name doesn't exist in the table |
| `INVALID_COLUMN_TYPE` | 400 | Column type incompatible with the column's datatype |
| `INVALID_COLUMN_TYPE_CONFIG` | 400 | Column type config has wrong shape |
| `DUPLICATE_SYNONYM` | 400 | Duplicate synonyms detected (case-insensitive) |
| `SEMANTIC_LAYER_NOT_FOUND` | 404 | No semantic layer exists — use POST to create first |
| `AUTHENTICATION_ERROR` | 403 | Data app token used instead of service token |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
## Quick Start Guide
Retrieve the existing semantic layer before making changes:
```bash theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer?datamartName=sales-analytics' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
Save this response in case you need to rollback your changes.
Determine what you want to update:
* **Tables/Columns**: Include only the tables and columns you want to change
* **Feedback**: Provide the new text (replaces existing)
Unlike the datamart update API, the semantic layer update is additive for tables and columns — only the ones you include are modified.
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/data-app/datamarts/semantic-layer \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{ "datamartName": "sales-analytics", "feedback": "Updated context." }'
```
Retrieve the semantic layer again to confirm changes and check the updated completion score.
## Next Steps
Retrieve and verify your changes
Create a semantic layer for a new datamart
Remove semantic layer metadata entirely
Configure the semantic layer in the Databrain UI
# Update Workspace
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-workspace
PUT https://api.usedatabrain.com/api/v2/workspace
Update an existing workspace's connection settings to change datasource, datamart, multi-datasource, or multi-datamart configuration.
Update the connection settings of an existing workspace. You can switch between datasource, datamart, multi-datasource, and multi-datamart configurations. Updating a workspace also updates all associated metrics to use the new connection.
**Important:** Updating a workspace connection will automatically update all metrics in that workspace to use the new datasource or datamart connection. Ensure the new connection has compatible table and column structures to avoid breaking existing metrics.
The workspace name is used to identify which workspace to update and cannot be changed through this endpoint. To rename a workspace, you'll need to create a new one and migrate your content.
## Authentication
This endpoint requires a service token in the Authorization header. Service tokens differ from data app API keys and provide organization-level permissions.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click the **"Generate Token"** button to create a new service token if you don't have one already.
Use this token as the Bearer value in your Authorization header.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json` for all requests.
```
Content-Type: application/json
```
## Request Body
Name of the existing workspace to update. Must match exactly (case-sensitive).
* Use the [List Workspaces API](/developer-docs/helpers/api-reference/list-workspaces) to get all workspace names
* Names are case-sensitive and must match exactly
* This field identifies which workspace to update
New connection type for the workspace. Must be one of: `DATASOURCE`, `DATAMART`, `MULTI_DATASOURCE`, or `MULTI_DATAMART`.
* **DATASOURCE**: Connect directly to a single datasource
* **DATAMART**: Connect to a pre-configured datamart
* **MULTI\_DATASOURCE**: Allow connections to multiple datasources within this workspace
* **MULTI\_DATAMART**: Allow switching between multiple datamarts within this workspace
**Note:** Changing connection type will update all metrics in this workspace. For `MULTI_DATASOURCE` or `MULTI_DATAMART`, `datasourceName` and `datamartName` are optional; the API clears prior single-datasource or single-datamart links and enables the selected multi mode. For `DATASOURCE` or `DATAMART`, `datasourceName` or `datamartName` is required (respectively), and multi-datasource / multi-datamart modes are turned off.
Name of the datasource to connect to this workspace.
**Required when** `connectionType` is `DATASOURCE`.
* Must be an existing datasource in your organization
* Use the exact name as stored in datasource credentials
* Names are case-sensitive
* All metrics will be updated to use this datasource
Name of the datamart to connect to this workspace.
**Required when** `connectionType` is `DATAMART`.
* Must be an existing datamart in your organization
* Use the [List Datamarts API](/developer-docs/helpers/api-reference/list-datamarts) to find available datamarts
* Names are case-sensitive
* All metrics will be updated to use this datamart's datasource
Optional primary LLM name for workspace-level AI features. Must match an existing LLM configured in your organization.
Optional list of LLM names available for AI Copilot in this workspace. Every value must match an existing organization LLM name.
Optional flag to enable or disable AI-powered metric suggestions for this workspace.
Optional flag to enable or disable AI-generated metric summaries for this workspace.
Summary mode used when metric summaries are enabled. Must be one of:
`technicalAndInsightSummary`, `forecastAndTrendAnalysis`, `comparativeAndAnomalyDetection`, `custom`.
**Required when** `isEnableMetricSummary` is `true`.
Custom summary instruction prompt for AI-generated summaries.
**Required when** `summaryType` is `custom`.
Optional workspace theme name. Must match an existing theme configured in your organization.
## Response
Contains the updated workspace information on success.
The name of the successfully updated workspace.
Error object if the request failed, otherwise `null` for successful requests.
Error code identifying the type of error.
Human-readable error message describing what went wrong.
## Examples
```bash cURL - Switch to Datasource theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "DATASOURCE",
"datasourceName": "postgres-production"
}'
```
```bash cURL - Switch to Datamart theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "DATAMART",
"datamartName": "sales-datamart"
}'
```
```bash cURL - Switch to Multi-Datasource theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "MULTI_DATASOURCE"
}'
```
```bash cURL - Switch to Multi-Datamart theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "MULTI_DATAMART"
}'
```
```bash cURL - Update AI + Theme Settings theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Analytics",
"connectionType": "DATAMART",
"datamartName": "sales-datamart",
"llmName": "gpt-4o",
"aiCopilotLlms": ["gpt-4o", "gpt-4.1-mini"],
"isEnableMetricSuggestions": true,
"isEnableMetricSummary": true,
"summaryType": "custom",
"customSummaryPrompt": "Summarize weekly KPI shifts with root-cause hypotheses.",
"themeName": "Executive Theme"
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Sales Analytics',
connectionType: 'DATASOURCE',
datasourceName: 'postgres-production'
})
});
const result = await response.json();
if (result.error) {
console.error('Update failed:', result.error.message);
} else {
console.log('Workspace updated:', result.data.name);
}
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.put(
'https://api.usedatabrain.com/api/v2/workspace',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'name': 'Sales Analytics',
'connectionType': 'DATASOURCE',
'datasourceName': 'postgres-production'
}
)
result = response.json()
if result.get('error'):
print(f"Update failed: {result['error']['message']}")
else:
print(f"Workspace updated: {result['data']['name']}")
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/workspace')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
name: 'Sales Analytics',
connectionType: 'DATASOURCE',
datasourceName: 'postgres-production'
}.to_json
response = http.request(request)
result = JSON.parse(response.body)
if result['error']
puts "Update failed: #{result['error']['message']}"
else
puts "Workspace updated: #{result['data']['name']}"
end
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class UpdateWorkspace {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody = """
{
"name": "Sales Analytics",
"connectionType": "DATASOURCE",
"datasourceName": "postgres-production"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/workspace"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type WorkspaceUpdateRequest struct {
Name string `json:"name"`
ConnectionType string `json:"connectionType"`
DatasourceName string `json:"datasourceName,omitempty"`
DatamartName string `json:"datamartName,omitempty"`
}
func main() {
reqData := WorkspaceUpdateRequest{
Name: "Sales Analytics",
ConnectionType: "DATASOURCE",
DatasourceName: "postgres-production",
}
jsonData, _ := json.Marshal(reqData)
req, _ := http.NewRequest("PUT",
"https://api.usedatabrain.com/api/v2/workspace",
bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Workspace updated successfully")
}
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'Sales Analytics',
'connectionType' => 'DATASOURCE',
'datasourceName' => 'postgres-production'
];
$options = [
'http' => [
'header' => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
'method' => 'PUT',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$result = json_decode($response, true);
if (isset($result['error'])) {
echo "Update failed: " . $result['error']['message'];
} else {
echo "Workspace updated: " . $result['data']['name'];
}
?>
```
```json 200 - Success theme={"dark"}
{
"data": {
"name": "Sales Analytics"
},
"error": null
}
```
```json 400 - Workspace Not Found theme={"dark"}
{
"error": {
"code": "WORKSPACE_DOES_NOT_EXIST",
"message": "Workspace does not exist"
}
}
```
```json 400 - Invalid Datasource theme={"dark"}
{
"error": {
"code": "INVALID_DATASOURCE_NAME",
"message": "Invalid datasource name provided"
}
}
```
```json 400 - Invalid Datamart theme={"dark"}
{
"error": {
"code": "INVALID_DATAMART_NAME",
"message": "Invalid datamart name provided"
}
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"connectionType\" is required"
}
}
```
```json 401 - Unauthorized theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
```json 500 - Server Error theme={"dark"}
{
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}
}
```
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Workspace updated successfully |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `500` | **Internal Server Error** - Server error occurred |
## Possible Errors
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ----------------------------- |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid parameters |
| `WORKSPACE_DOES_NOT_EXIST` | 400 | Workspace not found |
| `INVALID_DATASOURCE_NAME` | 400 | Datasource not found |
| `INVALID_DATAMART_NAME` | 400 | Datamart not found |
| `INVALID_LLM_NAME` | 400 | Invalid LLM name provided |
| `INVALID_AI_COPILOT_LLMS` | 400 | Invalid AI Copilot LLM list |
| `INVALID_THEME_NAME` | 400 | Invalid theme name provided |
| `INVALID_DATA_APP_API_KEY` | 401 | Invalid API key |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
# Update Workspace Dashboards
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/update-workspace-dashboards
PUT https://api.usedatabrain.com/api/v2/workspace/dashboards
Update filter mappings and dashboard gallery metrics for one or more dashboards inside a workspace.
Update dashboard filter-to-table mappings and incrementally add or remove metrics from dashboard galleries for dashboards that belong to a workspace.
**First-time workspace dashboard integration:** If you are wiring this flow for the first time, complete provisioning before calling this endpoint:
1. **Create an embed:** Set up embedding with [Create Embed](/developer-docs/helpers/api-reference/create-embed) or [Create Dashboard Embed](/developer-docs/helpers/api-reference/create-dashboard-embed).
2. **List embeds:** Use [List Embeds](/developer-docs/helpers/api-reference/list-embed) to verify metadata configurations and identify the created embed.
3. **Update:** Call [Update Workspace Dashboards](/developer-docs/helpers/api-reference/update-workspace-dashboards) with the dashboard ID and filter labels from the embed metadata.
Skipping these steps often leads to unknown dashboard IDs or filter names that do not match anything on the dashboard, in which case the request fails validation.
This endpoint updates existing dashboard filters by filter name. For each dashboard, DataBrain matches each input filter `name` against existing filter labels. Every requested filter name must match an existing filter label or the request fails validation.
Each dashboard entry must include at least one operation: `filters`, `appendMetrics`, or `removedMetrics`. The `dashboards` array and each dashboard's `dashboardId` are required. `filters` is optional, but each filter must include `applyOnTables`; `appendMetrics` and `removedMetrics` are also optional.
Metric gallery updates require a service token. A data app API token can be used for filter mapping updates, but requests containing `appendMetrics` or `removedMetrics` must use a service token.
## Authentication
This endpoint requires an authorized API token in the Authorization header. Use a service token for dashboard gallery metric updates; filter mapping updates can also use a data app API token.
To access your service token:
1. In **Settings** page, navigate to the **Service Tokens** section.
2. Click **Generate Token** to create a service token if you do not have one.
## Headers
Bearer token for API authentication. Use your service token.
```
Authorization: Bearer dbn_live_abc123...
```
Must be set to `application/json`.
```
Content-Type: application/json
```
## Request Body
Name of the workspace containing the dashboards to update.
List of dashboard update payloads. Dashboard IDs must be unique within this array.
External dashboard ID to update.
Optional list of filters to update for this dashboard.
Filter name to match against the existing dashboard filter label.
List of table/column targets where this filter should apply.
Datatype of the target column. This required string is passed through to the dashboard filter mapping.
Schema name of the target table.
Table name without schema.
Target column name.
Optional list of workspace metric IDs to add to this dashboard's gallery.
Workspace metric ID to add to the dashboard gallery. Each `metricId` may appear only once within `appendMetrics`.
Optional list of dashboard gallery metric IDs to remove from this dashboard. Each ID may appear only once.
Dashboard gallery metric ID to remove. A metric ID cannot be included in both `appendMetrics` and `removedMetrics` for the same dashboard.
Internally, DataBrain stores table references as `schemaName.tableName` while preserving the provided `columnName`.
When appending a workspace metric, DataBrain creates or reuses the dashboard-gallery copy for the dashboard's client. When removing a metric, only its association with the requested dashboard gallery is removed.
## Response
Success payload.
Returns `true` when all requested dashboard updates succeed.
Error object if the request fails, otherwise `null`.
## Examples
```bash cURL theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "sales-workspace",
"dashboards": [
{
"dashboardId": "db_12345",
"filters": [
{
"name": "Region",
"applyOnTables": [
{
"dataType": "string",
"schemaName": "public",
"tableName": "orders",
"columnName": "region"
}
]
}
]
},
{
"dashboardId": "db_67890",
"filters": [
{
"name": "Created Date",
"applyOnTables": [
{
"dataType": "date",
"schemaName": "analytics",
"tableName": "events",
"columnName": "created_at"
}
]
}
]
}
]
}'
```
```bash cURL - Update dashboard gallery metrics theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/workspace/dashboards \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"workspaceName": "sales-workspace",
"dashboards": [
{
"dashboardId": "db_12345",
"appendMetrics": [
{ "metricId": "metric_revenue" }
],
"removedMetrics": [
"metric_old_gallery_copy"
]
}
]
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/workspace/dashboards', {
method: 'PUT',
headers: {
Authorization: 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
workspaceName: 'sales-workspace',
dashboards: [
{
dashboardId: 'db_12345',
filters: [
{
name: 'Region',
applyOnTables: [
{
dataType: 'string',
schemaName: 'public',
tableName: 'orders',
columnName: 'region'
}
]
}
]
}
]
})
});
const result = await response.json();
console.log(result);
```
```json 200 - Success theme={"dark"}
{
"data": {
"success": true
},
"error": null
}
```
```json 400 - Validation Error theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "\"dashboards\" is required"
}
}
```
```json 400 - Invalid Dashboard theme={"dark"}
{
"error": {
"code": "INVALID_DASHBOARD_ID",
"message": "Dashboard with id db_12345 not found"
}
}
```
```json 400 - Unknown Filter theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Filter name(s) not found for dashboard db_12345: Region"
}
}
```
```json 403 - Gallery Metrics Require Service Token theme={"dark"}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Dashboard gallery metric updates require a service token, not a data app API token."
}
}
```
## Possible Errors
| Error Code | HTTP Status | Description |
| ----------------------- | ----------- | ------------------------------------------------------------------------------------------ |
| `INVALID_REQUEST_BODY` | 400 | Missing or invalid fields in request body |
| `INVALID_SERVICE_TOKEN` | 400 | Missing or invalid service token context |
| `WORKSPACE_ID_ERROR` | 400 | Workspace does not exist for the authenticated organization |
| `INVALID_DASHBOARD_ID` | 400 | Dashboard does not exist in the given workspace |
| `INVALID_METRIC_ID` | 400 | A metric to append or remove is not available in the requested dashboard gallery context |
| `AUTHENTICATION_ERROR` | 403 | Gallery metric updates were attempted with a data app API token instead of a service token |
| `INTERNAL_SERVER_ERROR` | 500 | Unexpected server error |
## HTTP Status Code Summary
| Status Code | Description |
| ----------- | ---------------------------------------------------------------------------------------- |
| `200` | **OK** - Requested dashboard filter and/or gallery metric updates completed successfully |
| `400` | **Bad Request** - Validation failure, invalid token context, or invalid dashboard |
| `403` | **Forbidden** - Gallery metric updates require a service token |
| `500` | **Internal Server Error** - Unexpected server error |
## Next Steps
Verify workspace names before update calls
Validate downstream metric behavior after dashboard filter updates
# Whitelist Domains
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-reference/whitelist-domains
GET https://api.usedatabrain.com/api/v2/data-app/whitelist-domains
Retrieve or update the account-wide list of domains allowed to embed your dashboards (GET to list, PUT to update).
Manage the domains that are allowed to load embedded dashboards and metrics. Use **GET** to retrieve the current list and **PUT** to update it.
Domain whitelisting is a security feature. Requests from non-whitelisted origins are rejected even with a valid API key or guest token. See [Domain Whitelisting](/developer-docs/security#domain-whitelisting) for more context.
The whitelist is stored **account-wide**: although this endpoint is authenticated with a Data App API key, it reads and writes the single list shared by **all** Data Apps in your account. A `PUT` replaces the whole account's whitelist — include every domain used by every Data App, not just the one whose key you're using.
## Endpoints
```
GET https://api.usedatabrain.com/api/v2/data-app/whitelist-domains
```
Returns the account-wide list of whitelisted domains (shared by all Data Apps).
```
PUT https://api.usedatabrain.com/api/v2/data-app/whitelist-domains
Content-Type: application/json
{ "domains": ["app.example.com", "*.customer.com"] }
```
Replaces the account-wide whitelist with the given array of domains. Supports domain names, wildcards (e.g. `*.example.com`), IPs with optional port, and `localhost` with optional port.
## Authentication
All requests must include your **data app API key** in the `Authorization` header. See the [data app creation guide](/guides/datasources/create-a-data-app) and the [API Token guide](/developer-docs/helpers/api-token).
## Headers
Bearer token for API authentication. Use your data app API key.
```
Authorization: Bearer dbn_live_abc123...
```
Required for PUT only. Must be `application/json`.
## GET – Query parameters
None.
## PUT – Request Body
Array of domain strings. Each entry must be one of:
* A valid domain with at least two labels (e.g. `app.example.com`)
* A wildcard subdomain (e.g. `*.example.com`)
* An IPv4 address with optional port (e.g. `192.168.1.1` or `192.168.1.1:3000`)
* `localhost` with optional port (e.g. `localhost` or `localhost:8080`)
Do **not** include `http://` or `https://`. Pass an empty array `[]` to clear all whitelisted domains.
## Response
### GET response
Array of whitelisted domain strings. Empty array if none are set.
### PUT response
The saved list of whitelisted domains.
## Examples
```bash cURL theme={"dark"}
curl --request GET \
--url 'https://api.usedatabrain.com/api/v2/data-app/whitelist-domains' \
--header 'Authorization: Bearer dbn_live_abc123...'
```
```bash cURL theme={"dark"}
curl --request PUT \
--url 'https://api.usedatabrain.com/api/v2/data-app/whitelist-domains' \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{"domains": ["app.example.com", "*.customer.com", "localhost:3000"]}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
// List
const listRes = await fetch('https://api.usedatabrain.com/api/v2/data-app/whitelist-domains', {
method: 'GET',
headers: { 'Authorization': 'Bearer dbn_live_abc123...' }
});
const { data: domains } = await listRes.json();
// Update
await fetch('https://api.usedatabrain.com/api/v2/data-app/whitelist-domains', {
method: 'PUT',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json',
},
body: JSON.stringify({ domains: ['app.example.com', '*.customer.com'] }),
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
headers = {"Authorization": "Bearer dbn_live_abc123..."}
# List
r = requests.get("https://api.usedatabrain.com/api/v2/data-app/whitelist-domains", headers=headers)
domains = r.json().get("data", [])
# Update
requests.put(
"https://api.usedatabrain.com/api/v2/data-app/whitelist-domains",
headers={**headers, "Content-Type": "application/json"},
json={"domains": ["app.example.com", "*.customer.com"]},
)
```
```json GET – Success theme={"dark"}
{
"data": ["app.example.com", "*.customer.com", "localhost:3000"]
}
```
```json PUT – Success theme={"dark"}
{
"data": {
"domains": ["app.example.com", "*.customer.com"]
}
}
```
```json Error – Invalid body (PUT) theme={"dark"}
{
"error": {
"code": "INVALID_REQUEST_BODY",
"message": "Invalid domain format. Please enter domain/IP without http:// or https://"
}
}
```
```json Error – Invalid API key theme={"dark"}
{
"error": {
"code": "INVALID_DATA_APP_API_KEY",
"message": "invalid or expired API KEY, data app not found"
}
}
```
## Error codes
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | ----------------------------------------------------------------------- |
| `INVALID_DATA_APP_API_KEY` | 400 | Missing or invalid data app API key |
| `INVALID_SERVICE_TOKEN` | 400 | Invalid or expired token; cannot resolve company context |
| `INVALID_REQUEST_BODY` | 400 | Invalid or malformed `domains` (e.g. protocol included, invalid format) |
| `INTERNAL_SERVER_ERROR` | 500 | Unexpected server error |
## Related
Security and whitelist behavior
Configure email (e.g. scheduled reports)
# API Token
Source: https://docs.usedatabrain.com/developer-docs/helpers/api-token
Generating API Token in DataBrain
Navigate to the **Data tab > Data Apps** and then click on **New Data App** button.
This modal will appear:
Provide a relevant name and select DataApp Type as **embedded** and click on save. You will be navigated to the below screen. Then, proceed to the **API Token tab** and click on **Generate Token**.
You'll be prompted to provide a **Name** and **Description** for your token. Once it's generated, you can conveniently copy the token for your use.
# Component Options Reference
Source: https://docs.usedatabrain.com/developer-docs/helpers/component-options-reference
Comprehensive reference guide for all available options and properties for Databrain web components
Try out the components with different options in DataBrain's playground
This reference guide provides detailed documentation for all available options and properties for Databrain's web components: `dbn-dashboard` and `dbn-metric`.
***
## Understanding the Configuration Layers
Databrain components have **four configuration layers** that are applied in a specific priority order. Understanding this hierarchy is essential for getting the behavior you expect.
Settings are resolved from **highest priority** (top) to **lowest priority** (bottom). A higher-priority layer always wins when the same setting exists in multiple layers.
| Priority | Layer | Scope | Prop | When to Use |
| ----------- | ------------------------- | ---------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| 1 (highest) | **Chart Appearance** | Per-metric (on `dbn-metric`) | `chart-appearance` | Fine-tune visual styling (margins, axis labels, legend position, tooltip fonts) for a single metric. |
| 2 | **Admin Theme Options** | Global (on `dbn-dashboard`) | `admin-theme-options` | Apply org-wide branding: fonts, card styles, color palettes, dashboard background. |
| 3 | **Custom Chart Settings** | Per-metric defaults (on `dbn-dashboard`) | `custom-chart-settings` | Set default chart behaviors (axis visibility, bar width, sort, zoom) and lock/unlock end-user editing via `canEdit`. |
| 4 (lowest) | **Saved Metric Settings** | Per-metric (stored in DB) | N/A | Settings saved by the metric creator in the Databrain admin UI. |
**`chart-appearance` vs `custom-chart-settings` field names differ.** These two layers evolved independently and use different keys for overlapping concepts. See the [Field Name Mapping](#field-name-mapping) table below for a cross-reference.
**`custom-chart-settings` only applies to newly created metrics.** If a metric already exists in the database with saved settings, the `custom-chart-settings` prop will **not** override those saved values. This is by design — `custom-chart-settings` provides defaults for metric creation, not runtime overrides. To override settings on existing metrics, use `chart-appearance` instead.
***
## Dashboard Component (`dbn-dashboard`)
The dashboard component displays a complete dashboard with multiple metrics and interactive features.
### Required Properties
Guest token for authentication. Must be generated from your backend using the Databrain API.
Unique identifier for the dashboard to display.
### Display & Layout Options
Hides the table preview in full screen view.
Hides chart settings in full screen view.
Disables the full screen option for the dashboard.
Enables fullscreen mode when the metric title is clicked. Provides an alternative way for users to enter fullscreen without using the fullscreen button.
Controls which options icon to display. Options: `kebab-menu-vertical` | `download`
Makes dashboard filters sticky at the top when scrolling.
Controls the visibility and configuration of the settings icon. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
name: 'random',
iconSvg: 'svg',
menuPosition: 'bottom-start', // optional; defaults to "bottom-start"
}
```
Custom label text for the settings button.
Custom SVG markup for the settings button icon.
Controls where the settings menu popup is anchored relative to the settings button. Options: `"auto"` | `"auto-start"` | `"auto-end"` | `"top"` | `"bottom"` | `"right"` | `"left"` | `"top-start"` | `"top-end"` | `"bottom-start"` | `"bottom-end"` | `"right-start"` | `"right-end"` | `"left-start"` | `"left-end"`
Enables CSV download option in metric card actions.
Enables email CSV option in metric card actions.
Disables PNG download option in full screen mode.
Enables download option for all metrics at once.
Enables PDF download option for all metrics at once.
### Advanced Configuration
The `options` prop accepts a JSON object with the following properties:
```javascript Basic Options theme={"dark"}
{
"disableDownloadDataNoFilters": false,
"disableDownloadUnderlyingDataNoFilters": false,
"isShowNoDataFoundScreen": false,
"disableMetricCreation": false,
"disableMetricUpdation": false,
"disableMetricCardBorder": false,
"disableMetricDeletion": false,
"disableLayoutCustomization": false,
"dashboardSpacing": {
"verticalGap": 30,
"horizontalGap": 30,
"hide": false,
},
"disableSaveLayout": false,
"disableScheduleEmailReports": false,
"disableManageMetrics": false,
"disableMainLoader": false,
"disableMetricLoader": false,
"hideDashboardName": false,
"allowedChartTypes": ["line", "bar", "stack", "row", "combo", "pie", "doughnut", "waterfall", "funnelV2", "gaugeV2", "singleValue", "table", "pivotV2", "rose", "horizontalStack", "treeMap", "progressBarV2"],
"hideMetricCardShadow": false,
"showDashboardActions": true,
"disableUnderlyingData": false,
"shouldFitFullScreen": false,
"isModifyUrl": false,
"exportMsgPosition": "bottom",
"dashboardPadding": "16px",
"ctaButtonCustomization": {
"primary": {
"styles": "background-color: #2563eb; color: #ffffff; border-radius: 8px;",
"hoverStyles": "background-color: #1d4ed8;",
"activeStyles": "background-color: #1e40af;",
"disabledStyles": "opacity: 0.5;"
},
"secondary": {
"styles": "background-color: #f1f5f9; color: #0f172a;"
},
"tertiary": {
"styles": "color: #2563eb;"
}
},
"showAllChartSettings": false,
"renameBoard": "workspace",
"enableDashboardMinimap": true
}
```
```javascript Chart Customization theme={"dark"}
{
"chartColors": ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4"],
"chartPaletteOptions": [
{
"name": "custom1",
"colors": ["...9 colors"]
},
{
"name": "custom2",
"colors": ["...9 colors"]
},
{
"name": "custom3",
"colors": ["...9 colors"]
}
],
"hideDatePickerOptions": ["this month", "yesterday"],
"chartAppearance": {
"chartTooltip": {
"labelStyle": {
"size": 14,
"family": "Inter",
"weight": 400,
"color": "#000000"
},
"valueStyle": {
"size": 14,
"family": "Inter",
"weight": 400,
"color": "#000000"
},
"tooltipHeader": {
"size": 14,
"family": "Inter",
"weight": 400,
"color": "#000000"
}
"tooltipCard": {
"bgColor": "#FFFFFF",
"borderColor": "#FFFFFF",
"borderRadius": 14,
"padding": 10,
},
},
"chartLabel": {
"position": "hidden",
"radialChartposition": "outside"
},
"chartMargin": {
"marginTop": 15,
"marginLeft": 15,
"marginRight": 15,
"marginBottom": 15
},
"chartLegend": {
"show": true,
"fixedPosition": "top-left",
"enableVariablePosition": false,
"top": 15,
"left": 15,
"disableLegendScrolling": true,
"legendAppearance": "horizontal",
"truncateLegend": 22,
"legendShape": "circle",
"fontSize": 14,
"fontWeight": 400,
"fontFamily": "Inter",
"color": "#000000"
},
"verticalAxis": {
"hideAxisLines": false,
"hideSplitLines": false,
"hideAxisLabels": false,
"hideAxisTicks": false,
"axisName": "axisName",
"axisNameOffset": 20,
"axisLabelMargin": 0,
"fontSize": 14,
"fontFamily": "Inter",
"fontWeight": 400,
"color": "#000000",
"axisColor": "#000000",
"axisNameFontConfig": {
"fontFamily": "Inter",
"fontSize": 14,
"fontWeight": 400
}
},
"horizontalAxis": {
"hideAxisLines": false,
"hideSplitLines": false,
"hideAxisLabels": false,
"hideAxisTicks": false,
"axisName": "axisName",
"axisNameOffset": 20,
"axisLabelMargin": 0,
"fontSize": 14,
"fontFamily": "Inter",
"fontWeight": 400,
"color": "#000000",
"axisColor": "#000000",
"axisNameFontConfig": {
"fontFamily": "Inter",
"fontSize": 14,
"fontWeight": 400
}
}
}
}
```
Prevents downloading data when no filters are applied.
Prevents downloading underlying data when no filters are applied.
Shows a custom screen when no data is available.
Disables the ability to create new metrics.
Disables the ability to update existing metrics.
Controls visibility of dashboard actions like create metric, customize layout.
Renames the dashboard "Board" view-filter UI text (tab label, dropdown label, Add/Save CTA, and modal copy). If the value contains multiple words, only the first word is used.
Enables the dashboard minimap and progress header in an embedded dashboard. The minimap is disabled by default in embeds; set this option to `true` inside the dashboard `options` object to enable it. This option applies to `dbn-dashboard` and does not change the UI Theming setting used by dashboards in the app.
Makes full screen modal take up space equivalent to the dashboard component.
When enabled, the component appends state information (such as the active metric) to the browser URL. Useful for deep-linking into a specific view.
Controls the position of the "Exporting Dashboard" prompt that appears while a dashboard export is in progress. Set to `"hidden"` to suppress the message entirely. Options: `"bottom"` | `"bottom-left"` | `"bottom-right"` | `"center"` | `"top"` | `"top-left"` | `"top-right"` | `"hidden"`
Controls the horizontal and vertical spacing between the metrics on the grid. Optional `hide` field hides the **Adjust Spacing** button from **Customize Layout**.
```javascript theme={"dark"}
"dashboardSpacing": {
"verticalGap": 30,
"horizontalGap": 30,
"hide": true,
}
```
* When omitted, default layout spacing applies.
* Applying either of the **verticalGap** or **horizontalGap** sets the other to a default of **10**, unless configured here.
* This controls the spacing **between** metrics on the grid. For setting outer wrapper padding around the embedded dashboard use **`dashboardPadding`** inside the same `options` object.
Optional CSS value for the main dashboard embed wrapper padding. Uses the same rules as the standard CSS `padding` shorthand (for example `"16px"`, `"12px 24px"`, `"8px 12px 16px"`). Applied as an inline style on the embed dashboard container.
* When omitted, default layout padding from stylesheets applies.
* This controls outer wrapper padding around the embedded dashboard. For spacing **between** metrics on the grid, use **`dashboardSpacing`** inside the same `options` object.
Optional styling overrides for dashboard CTA buttons (primary, secondary, and tertiary variants). Injected styles target `.cta-primary`, `.cta-secondary`, and `.cta-tertiary`, so they apply anywhere those classes are used in the embedded experience (for example dashboard action buttons and full-screen metric controls).
Each variant supports optional string fields — pass fragments of CSS declarations (semicolon-separated), similar to inline style text:
* **`styles`** — base state
* **`hoverStyles`** — `:hover:enabled`
* **`activeStyles`** — `:active`
* **`disabledStyles`** — `:disabled`
```typescript theme={"dark"}
{
primary?: {
styles?: string;
hoverStyles?: string;
activeStyles?: string;
disabledStyles?: string;
};
secondary?: { /* same fields */ };
tertiary?: { /* same fields */ };
}
```
* **`background-color`** and **`color`** rules you provide are enforced with `!important` so they win over theme defaults.
* If **`styles`** includes a **`height:`** declaration, a companion height helper class may be generated for layout alignment (implementation detail).
* This is separate from **`admin-theme-options.dashboard.ctaColor`** / **`ctaTextColor`**, which set broad theme defaults; **`ctaButtonCustomization`** targets granular CSS per variant and state.
Array of color strings for chart styling. Defaults to Recharts default colors.
```javascript theme={"dark"}
["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FECA57"]
```
Array of custom color palette options that users can select from. Each palette should contain a name and an array of 9 colors for comprehensive chart coverage.
```javascript theme={"dark"}
[
{
name: "Ocean Blues",
colors: ["#003f5c", "#2f4b7c", "#665191", "#a05195", "#d45087", "#f95d6a", "#ff7c43", "#ffa600", "#ffd700"]
},
{
name: "Forest Greens",
colors: ["#004d00", "#006600", "#008000", "#009900", "#00b300", "#00cc00", "#00e600", "#00ff00", "#66ff66"]
},
{
name: "Sunset Warmth",
colors: ["#8b0000", "#a52a2a", "#cd5c5c", "#dc143c", "#ff6347", "#ff7f50", "#ffa500", "#ffd700", "#ffffe0"]
}
]
```
Detailed chart styling configuration for tooltips, labels, margins, legends, and axes.
```jsx theme={"dark"}
{
chartTooltip?: {
labelStyle?: {
size?: number,
family?: string,
weight?: number,
color?: string,
},
valueStyle?: {
size?: number,
family?: string,
weight?: number,
color?: string,
},
tooltipHeader?: {
size?: number,
family?: string,
weight?: number,
color?: string,
},
tooltipCard?: {
bgColor?: string,
borderColor?: string,
borderRadius?: number,
padding?: number,
},
},
chartLabel?: {
position?: "hidden" | "top" | "left" | "right" | "bottom" | "inside",
radialChartposition?: "outside" | "inside",
},
chartMargin?: {
marginTop?: number,
marginLeft?: number,
marginRight?: number,
marginBottom?: number,
},
chartLegend?: {
show?: boolean,
fixedPosition?: "top-left" | "top-center" | "top-right" | "left-center" | "right-center" | "bottom-left" | "bottom-center" | "bottom-right",
enableVariablePosition?: boolean,
top?: number,
left?: number,
disableLegendScrolling?: boolean,
legendAppearance?: "horizontal" | "vertical",
truncateLegend?: number,
legendShape?: "circle" | "rect" | "roundRect" | "triangle" | "diamond" | "arrow" | "none",
fontSize?: number,
fontWeight?: number,
fontFamily?: string,
color?: string,
},
verticalAxis?: {
hideAxisLines?: boolean,
hideSplitLines?: boolean,
hideAxisLabels?: boolean,
hideAxisTicks?: boolean,
axisName?: string,
axisNameOffset?: number,
axisLabelMargin?: number,
fontSize?: number,
fontFamily?: string,
fontWeight?: number,
color?: string,
axisColor?: string,
axisNameFontConfig?: {
fontFamily?: string,
fontSize?: number,
fontWeight?: number,
},
},
horizontalAxis?: {
hideAxisLines?: boolean,
hideSplitLines?: boolean,
hideAxisLabels?: boolean,
hideAxisTicks?: boolean,
axisName?: string,
axisNameOffset?: number,
axisLabelMargin?: number,
fontSize?: number,
fontFamily?: string,
fontWeight?: number,
color?: string,
axisColor?: string,
axisNameFontConfig?: {
fontFamily?: string,
fontSize?: number,
fontWeight?: number,
},
},
}
```
Configure global filters for the dashboard:
```javascript String Filter theme={"dark"}
{
"Filter name for a string datatype": {
"options": [
{ "value": "James Smith", "label": "James" },
{ "value": "Olivia Johnson", "label": "Olivia" },
{ "value": "Emma Brown", "label": "Emma" }
],
"defaultOption": "James Smith"
}
}
```
```javascript Number Filter theme={"dark"}
{
"Filter name for a number datatype": {
"defaultOption": {"min": 100, "max": 900}
}
}
```
```javascript Date Filter theme={"dark"}
{
"Filter name for a date datatype": {
"defaultOption": {"startDate": "2024-01-01", "endDate": "2024-12-31"},
"datePresetOptions": [
{
"type": "this",
"interval": 1,
"timeGrain": "month",
"label": "this month",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}
]
}
}
```
Custom theme configuration for component styling.
```javascript theme={"dark"}
{
"button": {
"primaryText": "white",
"primary": "#007bff",
"secondaryText": "black",
"secondary": "white"
},
"checkbox": {
"checked": "#007bff",
"unChecked": "#6c757d"
},
"switch": {
"enabled": "#28a745",
"disabled": "#6c757d"
},
"drillBreadCrumbs": {
"fontFamily": "Inter",
"fontColor": "black",
"activeColor": "#007bff"
},
"multiSelectFilterDropdown": {
"badgeColor": "#007bff",
"badgeTextColor": "white"
}
}
```
Name of a predefined theme from app settings UI theming.
Advanced UI theming configuration for the dashboard. Controls fonts, backgrounds, CTA colors, card styling, and chart palettes. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
"general": {
"name": "My Theme",
"fontFamily": "Inter",
"datePickerFormat": "DD-MM-YYYY"
},
"dashboard": {
"backgroundColor": "#FFFFFF",
"ctaColor": "#007bff",
"ctaTextColor": "#FFFFFF",
"selectBoxSize": "medium",
"selectBoxVariant": "floating",
"selectBoxBorderRadius": "8px",
"selectBoxTextColor": "#333333",
"metricCardColor": "#FFFFFF"
},
"cardTitle": {
"fontSize": "16px",
"fontWeight": "600",
"color": "#000000",
"elementColor": "#1e293b"
},
"cardDescription": {
"fontSize": "12px",
"fontWeight": "400",
"color": "#666666",
"elementColor": "#64748b"
},
"chart": {
"palettes": [
{
"name": "Custom Palette",
"colors": ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FECA57"]
}
],
"paletteOptions": ["Custom Palette"],
"selected": "Custom Palette",
"fontFamily": "Roboto",
"fontColor": "#333333",
"letterSpacing": "0.5px",
"tooltip": {
"header": {
"fontFamily": "Roboto",
"fontSize": "14px",
"fontWeight": "bold",
"fontColor": "#000000"
},
"label": {
"fontFamily": "Roboto",
"fontSize": "12px",
"fontWeight": "normal",
"fontColor": "#333333"
},
"value": {
"fontFamily": "Roboto",
"fontSize": "12px",
"fontWeight": "bold",
"fontColor": "#000000"
}
}
},
"cardCustomization": {
"padding": "16px",
"borderRadius": "8px",
"shadow": "0 2px 8px rgba(0,0,0,0.1)",
"disableShadowOnHover": false,
"disableStroke": false,
"metricStrokeColor": "#E0E0E0"
}
}
```
Name of the theme.
Global font family applied to the dashboard.
Date format string for date pickers (e.g. `"DD-MM-YYYY"`, `"MM-DD-YYYY"`, `"YYYY-MM-DD"`).
Background color of the dashboard container.
Primary call-to-action button color.
Text color for call-to-action buttons.
Size of filter select boxes. Options: `"small"` | `"medium"` | `"large"`
Style variant for filter select boxes. Options: `"floating"` | `"static"`
Border radius for filter select boxes (e.g. `"8px"`).
Text color for filter select boxes.
Background color of individual metric cards.
Font size of metric card titles (e.g. `"16px"`).
Font weight of metric card titles (e.g. `"600"`).
Text color of standard metric card titles (`.dbn-metric-card-title`).
Text color for **element** metric titles — titles rendered in the element layout (`.dbn-metric-element-title`). Use when element metrics should differ from `cardTitle.color`. Applied with `!important` when set.
* **`color`** styles the default card chrome title.
* **`elementColor`** styles only element-mode titles. Omit either field to fall back to product defaults for that surface.
Font size of metric card descriptions.
Font weight of metric card descriptions.
Text color of standard metric card descriptions (`.dbn-metric-card-description`).
Text color for **element** metric descriptions (`.dbn-metric-element-description`). Separate from `cardDescription.color`; applied with `!important` when set.
Array of custom chart color palettes. Each palette has a `name` and an array of `colors`.
Array of palette name strings available for selection.
Name of the currently selected palette.
Font family applied to chart axis labels, legend text, and chart titles (e.g. `"Roboto"`).
Default text color for chart axis labels, legend text, and chart titles (e.g. `"#333333"`).
Letter spacing applied to chart text elements (e.g. `"0.5px"`).
Global tooltip font configuration with nested `header`, `label`, and `value` objects. Each accepts `fontFamily`, `fontSize`, `fontWeight`, and `fontColor`.
**Known limitation:** The chart-level font fields (`chart.fontFamily`, `chart.fontColor`, `chart.letterSpacing`, `chart.tooltip`) are currently only applied from **saved admin themes** (configured via the Databrain admin UI or the `theme-name` prop). Passing them directly via the `admin-theme-options` prop will **not** affect chart rendering. Other `admin-theme-options` fields (dashboard colors, card styling, palettes, `datePickerFormat`) work correctly via the prop.
Inner padding of metric cards (e.g. `"16px"`).
Border radius of metric cards (e.g. `"8px"`).
Box shadow of metric cards (e.g. `"0 2px 8px rgba(0,0,0,0.1)"`).
Disables the shadow effect when hovering over metric cards.
Disables the border stroke around metric cards.
Border stroke color for metric cards when stroke is enabled (e.g. `"#E0E0E0"`).
### Additional Dashboard Properties
Controls the appearance of metric long-description tooltips. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
"width": "300px",
"fontColor": "#333333"
}
```
Restricts which columns are available to end users for each metric. Each entry targets a specific metric. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
[
{
"metricId": "metric-1",
"isEnabled": true,
"dimensions": ["region", "category"],
"measures": ["revenue", "profit"]
}
]
```
### Per-Metric Chart Settings
Per-metric chart settings that allow you to set default values and control whether end users can edit each setting. Must be passed as `JSON.stringify(...)`. Refer to the [Custom Chart Settings Reference](#custom-chart-settings-reference) section below for the complete schema.
```javascript Example theme={"dark"}
{
labelSettings: {
XAxisStyle: {
size: { defaultValue: 12, canEdit: true }
}
},
legendSettings: {
show: { defaultValue: true, canEdit: false }
}
}
```
```html Component Usage theme={"dark"}
```
***
### Internationalization
Language code for component localization (e.g., "fr", "es", "de").
Custom translation dictionary for component text.
```javascript theme={"dark"}
{
"total sales": {
"en": "total sales",
"fr": "ventes totales",
"es": "ventas totales",
"de": "Gesamtumsatz"
}
}
```
Calendar system to use. Options: `default` | `ind`
### Event Handling
Name of a global function to handle server events. Define the function in the global scope.
```javascript Function Definition theme={"dark"}
// Define globally accessible function
window.myServerEventHandler = (event) => {
console.log('Server event:', event);
// Handle the event
};
```
```html Component Usage theme={"dark"}
```
### Custom Chart Click Action
Name of a global function to call when a user clicks on a chart data point. Define the function in the global scope.
```javascript Function Definition theme={"dark"}
// Define globally accessible function
window.myChartClickHandler = (data) => {
console.log('Chart clicked:', data);
// Handle the click data
};
```
```html Component Usage theme={"dark"}
```
The shape of the `data` parameter depends on the chart type:
| Chart Type | Data Shape | Example |
| ---------------- | -------------------------------------------------- | ---------------------------------------------------- |
| Table | `{ columnName: value, ... }` | `{ "product name": "Product A1", "price": 4.444 }` |
| Tree Map, Sankey | `{ name: xVal, value: yVal }` | `{ name: "Category A", value: 1200 }` |
| All other charts | `{ name: xVal, value: yVal, columnName: colName }` | `{ name: "Jan", value: 500, columnName: "revenue" }` |
When Pass Complete Data is not enabled, the clicked value is directly passed instead of the data object.
### Custom Messages
Custom messages for various component states.
```javascript theme={"dark"}
{
"tokenExpiry": "Your session has expired. Please refresh the page.",
"tokenAbsent": "Authentication token is missing. Please log in again."
}
```
***
## Custom Chart Settings Reference
The `custom-chart-settings` prop allows you to configure default values and control end-user editability for individual chart settings on each metric card. Every field follows the shape `{ defaultValue: , canEdit: true | false }`.
`custom-chart-settings` defaults are only applied when a metric is **first created**. They do not override settings already saved on existing metrics. See [Understanding the Configuration Layers](#understanding-the-configuration-layers).
### Field Name Mapping
The `chart-appearance` prop (Priority 1) and `custom-chart-settings` prop (Priority 3) use **different field names** for overlapping concepts. Use this table to find the equivalent field when switching between layers.
| Concept | `chart-appearance` field | `custom-chart-settings` field |
| ------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| Legend visibility | `chartLegend.show` | `legendSettings.show` |
| Legend orientation | `chartLegend.legendAppearance` (`"horizontal"` / `"vertical"`) | `legendSettings.position` (`"horizontal"` / `"vertical"`) |
| Legend position | `chartLegend.fixedPosition` (e.g. `"bottom-center"`) | `legendSettings.fixedPosition` |
| Legend shape | `chartLegend.legendShape` | `legendSettings.legendShape` |
| Legend scrolling | `chartLegend.disableLegendScrolling` | `legendSettings.disableScroll` |
| Legend truncation | `chartLegend.truncateLegend` | `legendSettings.truncateLegendValue` |
| Legend font | `chartLegend.fontSize` / `fontWeight` / `fontFamily` / `color` | `legendSettings.fontSize` / `fontWeight` / `fontFamily` / `color` |
| Tooltip label font | `chartTooltip.labelStyle.{size,family,weight,color}` | `tooltipSettings.labelStyle.{size,family,weight,color}` |
| Tooltip value font | `chartTooltip.valueStyle.{size,family,weight,color}` | `tooltipSettings.valueStyle.{size,family,weight,color}` |
| Tooltip header font | `chartTooltip.tooltipHeader.{size,family,weight,color}` | `tooltipSettings.tooltipHeader.{size,family,weight,color}` |
| Label position | `chartLabel.position` | `labelSettings.position` |
| Margins | `chartMargin.{marginTop,marginLeft,marginRight,marginBottom}` | `margins.{marginTop,marginLeft,marginRight,marginBottom}` |
| X-axis label font | `horizontalAxis.{fontSize,fontFamily,fontWeight,color}` | `labelSettings.XAxisStyle.{size,family,weight,color}` |
| Y-axis label font | `verticalAxis.{fontSize,fontFamily,fontWeight,color}` | `labelSettings.YAxisStyle.{size,family,weight,color}` |
| Hide axis lines | `verticalAxis.hideAxisLines` / `horizontalAxis.hideAxisLines` | `customSettings.hideXAxisLines` / `customSettings.hideYAxisLines` |
| Hide split lines | `verticalAxis.hideSplitLines` / `horizontalAxis.hideSplitLines` | `customSettings.hideXSplitLines` / `customSettings.hideYSplitLines` |
| Axis label margin | `verticalAxis.axisLabelMargin` / `horizontalAxis.axisLabelMargin` | `labelSettings.XAxisStyle.axisMargin` / `labelSettings.YAxisStyle.axisMargin` |
```javascript theme={"dark"}
margins: {
marginTop: { defaultValue: 20, canEdit: true | false },
marginBottom: { defaultValue: 5, canEdit: true | false },
marginLeft: { defaultValue: 5, canEdit: true | false },
marginRight: { defaultValue: 5, canEdit: true | false },
}
```
```javascript theme={"dark"}
chartColors: { defaultValue: ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#4B0082', '#8B00FF', '#FF1493', '#00FFFF'], canEdit: true | false }
```
```javascript theme={"dark"}
legendSettings: {
show: { defaultValue: true | false, canEdit: true | false },
top: { defaultValue: 0, canEdit: true | false },
left: { defaultValue: 0, canEdit: true | false },
position: { defaultValue: 'horizontal' | 'vertical', canEdit: true | false },
truncateLegendValue: { defaultValue: 20, canEdit: true | false },
legendShape: { defaultValue: 'roundRect' | 'diamond' | 'triangle' | 'circle' | 'arrow', canEdit: true | false },
customise: { defaultValue: true | false, canEdit: true | false },
fixedPosition: { defaultValue: 'bottom-center', canEdit: true | false },
disableScroll: { defaultValue: true | false, canEdit: true | false },
fontSize: { defaultValue: 12, canEdit: true | false },
fontFamily: { defaultValue: 'Inter', canEdit: true | false },
fontWeight: { defaultValue: 400, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
}
```
```javascript theme={"dark"}
labelSettings: {
position: { defaultValue: 'left' | 'right' | 'top' | 'bottom' | 'inside' | 'outside' | 'hidden', canEdit: true | false },
truncateLabel: { defaultValue: true | false, canEdit: true | false },
truncateLabelValue: { defaultValue: 10, canEdit: true | false },
showLabelLine: { defaultValue: true | false, canEdit: true | false },
isEnableValueSummation: { defaultValue: false, canEdit: true | false },
showDimension: { defaultValue: true | false, canEdit: true | false },
isDynamicPosition: { defaultValue: true | false, canEdit: true | false },
showActualValue: { defaultValue: true | false, canEdit: true | false },
XAxisStyle: {
size: { defaultValue: 12, canEdit: true | false },
family: { defaultValue: 'Inter', canEdit: true | false },
weight: { defaultValue: 400, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
axisName: { defaultValue: '', canEdit: true | false },
axisPadding: { defaultValue: 0, canEdit: true | false },
axisMargin: { defaultValue: 0, canEdit: true | false },
axisNameFontConfig: {
fontFamily: { defaultValue: 'Inter', canEdit: true | false },
fontSize: { defaultValue: 12, canEdit: true | false },
fontWeight: { defaultValue: 400, canEdit: true | false },
},
},
YAxisStyle: {
size: { defaultValue: 12, canEdit: true | false },
family: { defaultValue: 'Inter', canEdit: true | false },
weight: { defaultValue: 400, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
axisName: { defaultValue: '', canEdit: true | false },
axisPadding: { defaultValue: 0, canEdit: true | false },
axisMargin: { defaultValue: 0, canEdit: true | false },
axisNameFontConfig: {
fontFamily: { defaultValue: 'Inter', canEdit: true | false },
fontSize: { defaultValue: 12, canEdit: true | false },
fontWeight: { defaultValue: 400, canEdit: true | false },
},
},
}
```
```javascript theme={"dark"}
tooltipSettings: {
labelStyle: {
size: { defaultValue: 12, canEdit: true | false },
family: { defaultValue: 'Inter', canEdit: true | false },
weight: { defaultValue: 400, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
},
valueStyle: {
size: { defaultValue: 12, canEdit: true | false },
family: { defaultValue: 'Inter', canEdit: true | false },
weight: { defaultValue: 400, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
},
tooltipHeader: {
size: { defaultValue: 14, canEdit: true | false },
family: { defaultValue: 'Inter', canEdit: true | false },
weight: { defaultValue: 600, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
},
tooltipCard: {
bgColor: {defaultValue: '#FFFFFF', canEdit: true | false },
borderColor: {defaultValue: '#FFFFFF', canEdit: true | false },
}
}
```
```javascript theme={"dark"}
axisSettings: {
axis: { defaultValue: 'left' | 'right', canEdit: true | false },
}
```
```javascript theme={"dark"}
customSettings: {
isEnableCustomLimits: { defaultValue: true | false, canEdit: true | false },
isEnableDynamicLimits: { defaultValue: true | false, canEdit: true | false },
isEnableLogScale: { defaultValue: true | false, canEdit: true | false },
customUpperLimit: { defaultValue: 0, canEdit: true | false },
customLowerLimit: { defaultValue: 0, canEdit: true | false },
hideXSplitLines: { defaultValue: true | false, canEdit: true | false },
hideYSplitLines: { defaultValue: true | false, canEdit: true | false },
hideXAxisLines: { defaultValue: true | false, canEdit: true | false },
hideYAxisLines: { defaultValue: true | false, canEdit: true | false },
hideYAxisTicks: { defaultValue: true | false, canEdit: true | false },
hideXAxisTicks: { defaultValue: true | false, canEdit: true | false },
hideXAxisLabels: { defaultValue: true | false, canEdit: true | false },
hideYAxisLabels: { defaultValue: true | false, canEdit: true | false },
}
```
```javascript theme={"dark"}
customSettings: {
numberFormatter: { defaultValue: '', canEdit: true | false },
isEnableLabelFormatting: { defaultValue: true | false, canEdit: true | false },
isEnableTimezoneFormatting: { defaultValue: true | false, canEdit: true | false },
isEnableBgColor: { defaultValue: true | false, canEdit: true | false },
timeFormatter: { defaultValue: '', canEdit: true | false },
labelPrefix: { defaultValue: '', canEdit: true | false },
labelSuffix: { defaultValue: '', canEdit: true | false },
isEnableLabelTooltip: { defaultValue: true | false, canEdit: true | false },
YaxislabelFormatters: {
defaultValue: [{ upperLimit: 1000, lowerLimit: 0, label: 'Low', color: '#00FF00' }],
canEdit: true | false,
},
}
```
```javascript theme={"dark"}
customSettings: {
enableTitleDesc: { defaultValue: true | false, canEdit: true | false },
chartTitle: { defaultValue: '', canEdit: true | false },
chartDesc: { defaultValue: '', canEdit: true | false },
titlePosition: { defaultValue: 'top', canEdit: true | false },
subHeaderShow: { defaultValue: true | false, canEdit: true | false },
displayText: { defaultValue: '', canEdit: true | false },
subHeaderAlignment: { defaultValue: 'center', canEdit: true | false },
}
```
```javascript theme={"dark"}
customSettings: {
singleValConditionalFormatter: {
defaultValue: [{ type: 'range', min: 0, max: 100, color: '#00FF00' }],
canEdit: true | false,
},
}
```
```javascript theme={"dark"}
customSettings: {
barWidth: { defaultValue: 20, canEdit: true | false },
barRadius: { defaultValue: [0, 0, 0, 0], canEdit: true | false },
cumulativeBar: { defaultValue: true | false, canEdit: true | false },
showFullStacked: { defaultValue: true | false, canEdit: true | false },
}
```
```javascript theme={"dark"}
customSettings: {
comboAxisSettings: {
defaultValue: [{ axis: 'left', measures: ['revenue'], chartTypes: [{ axis: 'left', type: 'bar' }] }],
canEdit: true | false,
},
}
```
```javascript theme={"dark"}
customSettings: {
isEnableMeasureMode: { defaultValue: true | false, canEdit: true | false },
chartZoom: {
isZoomEnabled: { defaultValue: true | false, canEdit: true | false },
zoomAxis: { defaultValue: 'x', canEdit: true | false },
},
}
```
```javascript theme={"dark"}
customSettings: {
markers: {
isEnableMax: { defaultValue: true | false, canEdit: true | false },
isEnableMin: { defaultValue: true | false, canEdit: true | false },
isEnableAvg: { defaultValue: true | false, canEdit: true | false },
maxColor: { defaultValue: '#008000', canEdit: true | false },
minColor: { defaultValue: '#FF0000', canEdit: true | false },
},
}
```
```javascript theme={"dark"}
customSettings: {
linearGaugeV2: {
upperLimit: {
isEnable: { defaultValue: true | false, canEdit: true | false },
limit: { defaultValue: 100, canEdit: true | false },
color: { defaultValue: '#000000', canEdit: true | false },
message: { defaultValue: '', canEdit: true | false },
messageSize: { defaultValue: 12, canEdit: true | false },
},
lowerLimit: {
isEnable: { defaultValue: true | false, canEdit: true | false },
limit: { defaultValue: 0, canEdit: true | false },
message: { defaultValue: '', canEdit: true | false },
messageSize: { defaultValue: 12, canEdit: true | false },
},
},
}
```
```javascript theme={"dark"}
tableSettings: {
conditionalFormatting: {
defaultValue: [{ columnName: 'status', rules: [{ operator: '=', value: 'Active', styles: { backgroundColor: '#00FF00', color: '#000000', isApplyBgColor: true } }] }],
canEdit: true | false,
},
}
```
```javascript theme={"dark"}
tableSettings: {
isEnableNumberFormatting: { defaultValue: true | false, canEdit: true | false },
tableNumberFormatter: {
defaultValue: [{ columns: ['revenue'], formatter: '#,##0.00', suffix: 'K', prefix: '$' }],
canEdit: true,
},
isEnableTimezoneFormatting: { defaultValue: true | false, canEdit: true | false },
timeFormatter: { defaultValue: 'original' | 'yyyy-MM-dd' | 'yyyy/MM/dd' | 'dd-MM-yyyy' | 'dd/MM/yyyy' | 'dd MMM yyyy' | 'dd MMMM yyyy' | 'yyyy MMMM dd' | 'MMMM dd, yyyy' | 'yyyy-MM-dd, h:mm:ss a' | 'h:mm a', canEdit: true | false },
}
```
***
## Metric Component (`dbn-metric`)
The metric component displays a single metric with customizable appearance and interactions.
### Required Properties
Guest token for authentication.
Unique identifier for the metric to display.
### Display Properties
Width of the metric component in pixels.
Height of the metric component in pixels.
Display variant. Options: `card` | `fullscreen`
Chart rendering method. Options: `svg` | `canvas`
### Behavior Options
Enables CSV download in metric card actions.
Enables email CSV option in metric card actions.
Disables PNG download in full screen mode.
Disables the full screen button.
Hides table preview in full screen view.
Hides chart settings in full screen view.
Disables access to underlying data.
Removes border from metric card.
Removes shadow from metric card.
Hides the metric card title.
Enables fullscreen mode when the metric title is clicked.
Controls which options icon to display. Options: `kebab-menu-vertical` | `download`
Prevents downloading underlying data when no filters are applied.
Prevents downloading data when no filters are applied.
### Filter Configuration
Allows multiple metric filters.
Position of metric filters. Options: `inside` | `outside`
Configuration for metric-specific filters.
```javascript theme={"dark"}
{
"Filter name for a string datatype": {
"options": [
{ "value": "James Smith", "label": "James" },
{ "value": "Olivia Johnson", "label": "Olivia" }
],
"defaultOption": "James Smith"
},
"Filter name for a number datatype": {
"options": [
{ "value": 1, "label": "Option 1" },
{ "value": 2, "label": "Option 2" }
],
"defaultOption": 1
},
"Filter name for a date datatype": {
"options": [
{
"range": "Last",
"time": "Year",
"name": "Last 10 Years",
"count": 10,
"fromDate": "2023-01-01",
"toDate": "2023-12-31"
}
],
"defaultOption": "Last 10 Years"
}
}
```
### Chart Appearance
Detailed chart styling configuration.
```javascript theme={"dark"}
{
chartTooltip?: {
labelStyle?: {
size?: number;
family?: string;
weight?: number;
color?: string;
};
valueStyle?: {
size?: number;
family?: string;
weight?: number;
color?: string;
};
tooltipHeader?: {
size?: number;
family?: string;
weight?: number;
color?: string;
};
};
chartLabel?: {
position?: 'hidden' | 'top' | 'left' | 'right' | 'bottom' | 'inside';
radialChartposition?: 'outside' | 'inside';
};
chartMargin?: {
marginTop?: number;
marginLeft?: number;
marginRight?: number;
marginBottom?: number;
};
chartLegend?: {
show?: boolean;
fixedPosition?:
| 'top-left'
| 'top-center'
| 'top-right'
| 'left-center'
| 'right-center'
| 'bottom-left'
| 'bottom-center'
| 'bottom-right';
enableVariablePosition?: boolean;
top?: number;
left?: number;
disableLegendScrolling?: boolean;
legendAppearance?: 'horizontal' | 'vertical';
truncateLegend?: number;
legendShape?:
| 'circle'
| 'rect'
| 'roundRect'
| 'triangle'
| 'diamond'
| 'arrow'
| 'none';
fontSize?: number;
fontWeight?: number;
fontFamily?: string;
color?: string;
};
verticalAxis?: {
hideAxisLines?: boolean;
hideSplitLines?: boolean;
hideAxisLabels?: boolean;
hideAxisTicks?: boolean;
axisName?: string;
axisNameOffset?: number;
axisLabelMargin?: number;
fontSize?: number;
fontFamily?: string;
fontWeight?: number;
color?: string;
axisColor?: string;
axisNameFontConfig?: {
fontFamily?: string;
fontSize?: number;
fontWeight?: number;
};
};
horizontalAxis?: {
hideAxisLines?: boolean;
hideSplitLines?: boolean;
hideAxisLabels?: boolean;
hideAxisTicks?: boolean;
axisName?: string;
axisNameOffset?: number;
axisLabelMargin?: number;
fontSize?: number;
fontFamily?: string;
fontWeight?: number;
color?: string;
axisColor?: string;
axisNameFontConfig?: {
fontFamily?: string;
fontSize?: number;
fontWeight?: number;
};
};
};
```
Interactive appearance options for the metric.
```javascript theme={"dark"}
{
"appearanceOptionsPosition": "top-right",
"dynamicBehaviour": {
"isEnabled": true,
"label": "Dynamic"
},
"cumulativeBar": {
"isEnabled": true,
"label": "Cumulative"
},
"stackedBars": {
"isEnabled": true,
"label": "Stacked"
}
}
```
### Internationalization & Configuration
Language code for component localization (e.g., `"fr"`, `"es"`, `"de"`).
Custom translation dictionary for metric text. Must be passed as `JSON.stringify(...)`. See the dashboard [Internationalization](#internationalization) section for the full schema.
Calendar system to use. Options: `default` | `ind`
Name of a predefined theme from app settings UI theming.
Custom messages for component states. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
"tokenExpiry": "Your session has expired. Please refresh the page.",
"tokenAbsent": "Authentication token is missing. Please log in again."
}
```
Pre-configured filter values for the metric. Must be passed as `JSON.stringify(...)`. See the dashboard [Global Filter Options](#global-filter-options) section for the full schema.
Controls the appearance of metric long-description tooltips. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
"width": "300px",
"fontColor": "#333333"
}
```
Restricts which columns are available to end users for this metric. Must be passed as `JSON.stringify(...)`.
```javascript theme={"dark"}
{
"isEnabled": true,
"dimensions": ["region", "category"],
"measures": ["revenue", "profit"]
}
```
### Event Callbacks
Name of global function to call when metric is minimized.
```javascript Function Definition theme={"dark"}
window.handleMetricMinimize = (metricId) => {
console.log('Metric minimized:', metricId);
};
```
```html Component Usage theme={"dark"}
```
***
## Common Properties
These properties are available for both dashboard and metric components:
### Styling & Customization
Inline CSS styles for the component.
CSS class name for custom styling.
Array of colors for chart elements.
```javascript Example Colors theme={"dark"}
["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FECA57"]
```
### No Data Handling
SVG code as string to display when no data is available.
SVG code as string to display when no data is found in dashboard.
### Date Picker Configuration
Array of date picker option labels to hide.
```javascript Example theme={"dark"}
["this month", "yesterday", "last week"]
```
***
## Usage Examples
```html theme={"dark"}
```
```html theme={"dark"}
```
```html theme={"dark"}
```
```html theme={"dark"}
```
***
## Frequently Asked Questions
Web components don't automatically re-render when properties change. Here are several approaches:
**Method 1: Force Re-render with Key**
```javascript theme={"dark"}
const [componentKey, setComponentKey] = useState(0);
const [token, setToken] = useState(initialToken);
// When updating props
const updateProps = (newToken) => {
setToken(newToken);
setComponentKey(prev => prev + 1); // Force re-render
};
return (
);
```
**Method 2: Loading State Approach**
```javascript theme={"dark"}
const [isLoading, setIsLoading] = useState(false);
const [token, setToken] = useState(initialToken);
const updateToken = async (newToken) => {
setIsLoading(true);
// Brief delay to ensure component unmounts
await new Promise(resolve => setTimeout(resolve, 100));
setToken(newToken);
setIsLoading(false);
};
return (
<>
{isLoading ? (
);
}
return this.props.children;
}
}
// Usage
```
**Advanced Tooltip Customization:**
```javascript theme={"dark"}
const tooltipConfig = {
chartTooltip: {
labelStyle: {
size: 16,
family: "Arial, sans-serif",
weight: 600,
color: "#2c3e50"
},
valueStyle: {
size: 14,
family: "Arial, sans-serif",
weight: 400,
color: "#34495e"
}
}
};
```
**Legend Positioning:**
```javascript theme={"dark"}
const legendConfig = {
chartLegend: {
show: true,
fixedPosition: "bottom-center", // or use enableVariablePosition
enableVariablePosition: false,
legendAppearance: "horizontal",
truncateLegend: 30,
legendShape: "roundRect",
fontSize: 12,
fontWeight: 500,
fontFamily: "Inter, sans-serif",
color: "#2c3e50",
disableLegendScrolling: false
}
};
```
**Complete Chart Appearance:**
```html theme={"dark"}
```
***
## Migration & Updates
When updating from older versions, note that some property names may have changed. Always refer to this reference for the latest property names and structures.
For dynamic property updates, web components don't automatically re-render. Consider using a loading state and temporarily hiding/showing the component when updating properties.
## Troubleshooting Quick Reference
* ✅ Check if `@databrainhq/plugin/web` is imported
* ✅ Verify token is valid and not expired
* ✅ Confirm dashboard-id/metric-id exists
* ✅ Check browser console for errors
* ✅ Ensure CORS is properly configured
* ✅ Use `JSON.stringify()` for object props
* ✅ Check CSS specificity conflicts
* ✅ Verify color format (use hex codes)
* ✅ Test with `!important` to identify overrides
* ✅ Enable canvas rendering for large datasets
* ✅ Disable unnecessary features (loaders, underlying data)
* ✅ Implement lazy loading for multiple components
* ✅ Use `shouldFitFullScreen` for better performance
Check our comprehensive troubleshooting guide for additional solutions
# Dashboard App Filter
Source: https://docs.usedatabrain.com/developer-docs/helpers/dashboard-app-filter
Dashboard App Filter: Instruction Manual
* In your dashboard, create a new filter.
* In the "Apply On" section, enable the *App Filter* option.
### Method 1: Passing from Component
* Use the parameter `"global-filter-options"` to pass values directly from a component to the dashboard filter.
* Configuration changes based on the Filter Type and the Data Type.
1. **Single-Select Filter:**
* For *string-based* filters, pass just the value:
```javascript theme={"dark"}
global-filter-options={
JSON.stringify({
"Filter name for a string datatype": {
defaultOption: 'James Smith'
},
"Filter name for a number datatype": {
defaultOption: {min: 100, max: 900}, // number range
},
"Filter name for a date datatype": {
defaultOption: {startDate: '2024-01-01', endDate: '2024-12-31'}, // date range
},
})
}
```
2. **Multi-Select Filter:**
* For *string-based* filters, pass an array of values:
```javascript theme={"dark"}
global-filter-options={
JSON.stringify({
"Filter name for a string datatype": {
options: [
{ value: 'James Smith', label: 'James' },
{ value: 'Olivia Johnson', label: 'Olivia' },
{ value: 'Emma Brown', label: 'Emma' },
], // in case you want the drop down.
defaultOption: ['James Smith', 'Emma Brown'], // selected values
},
"Filter name for a number datatype": {
defaultOption: {min: 100, max: 900}, // number range
},
"Filter name for a date datatype": {
defaultOption: {startDate: '2024-01-01', endDate: '2024-12-31'}, // date range
},
})
}
```
Refer the below "Options" document for further queries.
***
### Method 2: Passing from Guest Token
* You can link a guest token here to pass the filter values dynamically.\
Refer the below document to generate a guest token.
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
// single string
"name": "Eric",
// multi select
"country": ["USA", "CANADA"] || "USA", // based on filter variant(select or multi-select)
// date-picker
"timePeriod": { "startDate": "2024-01-01", "endDate": "2024-3-23" },
// range
"price": { "min": 1000, "max": 5000 }
},
"isShowOnUrl": true // true/false
}
]
}
}
```
***
### Method 3: Handling Large Selections with SQL Integration
Filters with a large number of options (e.g., over 500), manually passing all values becomes inefficient. With SQL integration, you can dynamically fetch options from your database, simplifying the process.
The SQL query specified under the `"sql"` key dynamically fetches the latest values from the specified database table.
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
// single string
"name": "Eric",
"country": {
"sql": "SELECT \\\"name\\\" FROM \\\"public\\\".\\\"countries\\\" WHERE isEnabled=true",
"columnName": "name"
},
// date-picker
"timePeriod": { "startDate": "2024-01-01", "endDate": "2024-3-23" },
// range
"price": { "min": 1000, "max": 5000 }
},
"isShowOnUrl": true // true/false
}
]
}
}
```
#### Key Benefits:
1. **Dynamic Updates**: The SQL query retrieves only the latest relevant options from your database.
* Example: `SELECT "name" FROM "public"."countries" WHERE isEnabled=true` fetches active country names.
2. **Efficiency**: Eliminates the need to manually manage large datasets in the configuration.
3. **Flexibility**: The `columnName` specifies the field in the query result to use as filter values.
4. **Scalability**: Handles thousands of options seamlessly, reducing payload size and improving performance.
This approach is ideal for keeping filters updated with minimal effort, ensuring they remain efficient and user-friendly.
# Dashboard id
Source: https://docs.usedatabrain.com/developer-docs/helpers/dashboard-id
Accessing Dashboard ID
In the Data App that you created (see API Token to know more about how to create a data app), click on Embed Info > Add New Embed. Provide the workspace name, select embed type as dashboard, provide the dashboard to get the dashboard id.
The Embed ID is the dashboard id that you can use.
# Embed Functions
Source: https://docs.usedatabrain.com/developer-docs/helpers/embed-functions
You can add your own buttons with embed functions.
To integrate and make use of specific **embed functions** within the `dbn-dashboard` component, you first need to locate the component with `dbn-dashboard` className on the webpage.
```ts theme={"dark"}
const dbnDashboard = document.querySelector(
'dbn-dashboard'
)?.shadowRoot?.querySelector('.dbn-dashboard') as HTMLElement & {
onClickCreateMetric?: () => void;
onClickManageMetrics?: () => void;
onClickScheduleReports?: () => void;
onClickCustomizeLayout?: () => void;
};
```
Now you can add the buttons on your screen with these specific functions in the **onClick** event of those buttons, here's an example:
```tsx theme={"dark"}
```
### Embed Functions Overview
There are four functions provided by the embed:
```ts theme={"dark"}
onClickCreateMetric(): It will open the create metric modal.
```
```ts theme={"dark"}
onClickManageMetrics(): It will open the manage metrics modal.
```
```ts theme={"dark"}
onClickScheduleReports(): It will open the schedule reports modal.
```
```ts theme={"dark"}
onClickCustomizeLayout(): It will enable the customize layout mode.
```
> ⚠️ **Note:** The functions will work only if you haven't disabled the respective operations. Also, you need to disable `showDashboardActions` in `options` in `dbn-dashboard` component, if you don't want to see the buttons provided by it that perform these actions and want to customize the buttons yourself.
# End User Dashboard Creation
Source: https://docs.usedatabrain.com/developer-docs/helpers/end-user-dashboard-creation
Description of your new file.
1. **Create a Datamart**
Create a Datamart in "Data Studio" page. Kindly refer the below link on how to create datamarts:
2. **Create a Workspace with Datamart connection**
For more details, kindly refer the below link:
3. \*\*Create a Dashboard \*\*
For more details, kindly refer the below link:
4. **Create a DataApp**
For more details, kindly refer the below link:
5. **Generate API Token**
* Navigate to the Data App.
* In the "API Token" section, generate the API token by specifying the name of company and description (optional)
**API Methods**
**Cloud Databrain:**
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/dataApp/embed/{method_path}
```
**Self-hosted Databrain:**
```http theme={"dark"}
POST /api/v2/dataApp/embed/{method_path}
```
6. **Create a Dashboard**
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/dataApp/dashboardEmbed/create
```
```http theme={"dark"}
POST /api/v2/dataApp/dashboardEmbed/create
```
```json theme={"dark"}
{
"dashboardId": "id",
"clientId": "102",
"templateDashboardId": "demo-sales-test-dashboard", // dashboard id to clone filters
"metadata": {"created_at": "2025-09-25", "name":"lyman's dashboard", "descriptions":"created for 102 client id, it's end user dashboard embed"}, // metadata of dashboard
"workspaceName": "Demo Sales API",
"accessSettings": {
"datamartName": "Demo Sales API Test Datamart",
"isAllowAiPilot": true,
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": true,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": false,
"isAllowCreateDashboardView": false,
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"clientColumn": "client id",
"name": "demo_sales"
}
]
}
}
// database tenancy don't require table list
```
* `dashboardId` – Unique external dashboard ID (must not already exist).
* `workspaceName` – Must match a valid workspace linked to the API token's company.
* `clientId` – Identifier of the client for which the dashboard is being created.
* `templateId` – Optional. External dashboard ID of a template to clone.
* `accessSettings` – Required. Defines permissions and feature access for the embed.
7. **Create Guest token by passing Client ID and DataApp Name**
When you need a guest token that you want to use across dashboards and metrics. All you have to do is pass `clientId`, `dataAppName`. If `expiryTime` is not passed, the token will not expire.
## Generating GUEST TOKEN for your Dashboard
### Headers
| Name | Type | Description |
| :-------------- | :----- | :----------------- |
| Authorization\* | String | Bearer (API Token) |
### Request Body
| Name | Type | Description |
| :------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------- |
| dataAppName\* | String | Your Data App Name |
| clientId\* | String | Client ID for whom this guest token is generated. (`"clientId": "None"` if no tenancy is selected for connected datasource/datamart) |
| params | Object | Additional Params: `dashboard`, `appFilters` |
| expiryTime | Number | In milliseconds |
| datasourceName | String | Datasource name from Data Studio (\*important and supported in multi-datasource connection in workspace) |
**Example Response: 200 OK "token": "..."**
```json theme={"dark"}
when the response is successful it returns a token that you can pass to the frontend.
```
When the response is successful it returns a token that you can pass to the frontend.
### Simple Request Body
```json theme={"dark"}
{
"clientId": "102",
"dataAppName": "Demo Sales API"
}
```
Once you acquire the guest token, you can seamlessly pass it to your frontend application, where it can be integrated with the web component
* The created dashboard will mimic the filter behavior of the cloned dashboard if a Template ID is provided.
* Once the dashboard is created, users can start building metrics.
```json theme={"dark"}
{
"embedId": "id",
"accessSettings": {
"datamartName": "Demo Sales API Test Datamart",
"isAllowAiPilot": true,
"isAllowEmailReports": false,
"isAllowManageMetrics": true,
"isAllowMetricCreation": true,
"isAllowMetricDeletion": true,
"isAllowMetricLayoutChange": true,
"isAllowMetricUpdate": true,
"isAllowUnderlyingData": true,
"isAllowCreateDashboardView": false,
"metricCreationMode": "DRAG_DROP",
"tableTenancySettings": [
{
"clientColumn": "client id",
"name": "demo-sales"
}
]
}
}
```
```json theme={"dark"}
{
"embedId": "id"
}
```
# End User Metric Creation
Source: https://docs.usedatabrain.com/developer-docs/helpers/end-user-metric-creation
1. **Create a Datamart**
Create a Datamart in "Data Studio" page. Kindly refer the below link on how to create datamarts:
2. **Create a Workspace with Datamart connection**
For more details, kindly refer the below link:
3. **Create a Dashboard with few defined metrics**
For more details, kindly refer the below link:
4. **Create a DataApp**
For more details, kindly refer the below link:
5. **Create an Embed Type using either dashboard or metric**
* Navigate to the Data App.
* In the "Embed Info" section, create an embed type using workspace name, embed type: dashboard or metric, name of dashboard or metric.
6. **Generate API Token**
In the "API Token" section, generate the API token by specifying the name of company and description (optional)
7. **Configure options in Access control section**
* Navigate to the Data App.
* In the "Access Control" section, enable **Metric Creation** for the embed.
Metric creation is controlled at three levels, in priority order:
1. **Guest token** — if the token sets `permissions.isDisableMetricCreation: true`, metric creation is off no matter what else is configured.
2. **Data App Access Control** — the server-side setting you enable in this step.
3. **Embed component** — `options.disableMetricCreation` on `dbn-dashboard` hides the UI client-side.
There is no `isAllowMetricCreation` embed prop — the component option is `disableMetricCreation`.
8. **Create Guest token by passing Client ID and DataApp Name**
When you need a guest token that you want to use across dashboards and metrics. All you have to do is pass `clientId`, `dataAppName`. If `expiryTime` is not passed, the token will not expire.
**Cloud Databrain:**
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
**Self-hosted Databrain:**
```http theme={"dark"}
POST /api/v2/guest-token/create
```
## Generating GUEST TOKEN for your Dashboard/Metric Component
### Headers
| Name | Type | Description |
| --------------- | ------ | ------------------ |
| Authorization\* | String | Bearer (API Token) |
### Request Body
| Name | Type | Description |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| dataAppName\* | String | Your Data App Name |
| clientId\* | String | Client ID for whom this guest token is generated. (`"clientId": "None"` if no tenancy is selected for connected datasource/datamart) |
| params | Object | Additional Params: `appFilters`, `rlsSettings`, `userIdentifier`, `allowedEmbeds` — see [Token Body](/developer-docs/helpers/token-body) |
| expiryTime | Number | In milliseconds. If omitted, the token never expires |
| datasourceName | String | Datasource name from Data Studio (\*important and supported in multi-datasource connection in workspace) |
**Example Response: 200 OK "token": "..."**
```json theme={"dark"}
when the response is successful it returns a token that you can pass to the frontend.
```
When the response is successful it returns a token that you can pass to the frontend.
### Simple Request Body
```json theme={"dark"}
{
"clientId": "Vaccine",
"dataAppName": "Procurement App"
}
```
Once you acquire the guest token, you can seamlessly pass it to your frontend application, where it can be integrated with the web component.
9. **End User Metric Creation / Updation**
**Metric Creation**
* Click on the "+Create Metric" button near the settings icon
* Drag and drop necessary dimensions and measures to create the metric
* Then, click on "Save" icon at the top right corner and specify metric details to save the metric to dashboard
**Metric Updation**
* View the metric in full screen and click on the "Edit Metric" button
* Update the metric according to your requirements and save it to dashboard
# LLM Architecture
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-architecture
Architecture of flow of information.
# LLM Connectors
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors
Getting Started with Configuring Popular LLMs with DataBrain
Databrain makes it easy to unlock the full potential of Large Language Models (LLMs) within your analytics environment. Whether you're looking to enhance dashboards with intelligent summaries, generate insights on demand, or enable conversational data exploration — LLM integration is your gateway to smarter, faster decision-making.
Below, we explore some of the most popular LLM integrations available in DataBrain and how they can enhance your analytics strategy.
Each section provides a comprehensive, step-by-step guide to help you configure and integrate your preferred LLM—enhancing the accessibility, interpretability, and intelligence of your data workflows.
# Azure Open AI
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/azure-open-ai
## Step 1: Configure Azure Open AI
Navigate to the **LLMs** section on settings page and click on **+LLM**
Choose **Azure Open AI** from the list.
In the **Configure Azure Open AI** panel:
* **Name**: Enter a descriptive name (e.g., `Azure GPT Assistant`)
* **Base URL**: Use your Azure Open AI endpoint URL in the format: `https://.openai.azure.com/`
* **API Key**: Paste your valid Azure Open AI API Key
* **Deployment Name**: Enter the deployment name of your model (e.g., `deploy-gpt-35`)
Click **Authenticate** to activate the integration.
## Step 2: Connect LLM to Workspace
Navigate to your desired workspace and click on ⚙️ **settings icon** next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom
* From the **LLM** dropdown, choose the Azure Open AI model you just configured
Optionally enable **Metric Summary** and choose the summary **Type** from the following options:\
Technical and Insight Summary, Forecast and Trend Analysis, Comparative and Anomaly Detection, Custom.
Click **Save** to apply changes.
You’ve successfully connected Azure Open AI with your Databrain workspace!\
Your integration is now live — enabling advanced Azure-powered LLM capabilities for intelligent insights, contextual summaries, and seamless data exploration across your dashboards.
# Claude AI
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/claude-ai
## Step 1: Configure Claude AI
Navigate to the **LLMs** section on settings page and click on **+LLM**
Choose Claude AI from the list.
In the **Configure Claude AI** panel:
* **Name**: Enter a descriptive name (e.g., `Claude Assistant`)
* **API Key**: Paste your valid Claude AI API Key
Click **Authenticate** to activate the integration.
***
## Step 2: Connect LLM to Workspace
Navigate to your desired workspace and click on ⚙️ **settings icon** next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom
* From the **LLM** dropdown, choose the Claude AI model you just configured
Optionally enable **Metric Summary** and choose the summary **Type** from the following options: Technical and Insight Summary, Forecast and Trend Analysis, Comparative and Anomaly Detection, Custom.
Click **Save** to apply changes.
You’ve successfully connected Claude AI with your Databrain workspace!\
Your integration is now live — enabling intelligent summaries, contextual analysis, and seamless natural language interactions with your data.
# Gemini
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/gemini
### Step 1: Configure Gemini
Navigate to the **LLMs** section on the **Settings** page and click on **+LLM**.
Choose **Gemini** from the list.
In the **Configure Gemini** panel:
* **Name**: Enter a descriptive name (e.g., `Gemini Workspace Assistant`).
* **API Key**: Paste your valid **Gemini API Key**.
* **Model**: Enter the **Gemini model name** you want to use (e.g., `gemini-1.5-pro`).
Click **Authenticate** to activate the integration.
***
### Step 2: Connect LLM to Workspace
Navigate to your desired **workspace** and click on the ⚙️ **settings icon** next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom.
* From the **LLM dropdown**, choose the **Gemini model** you just configured.
Optionally enable **Metric Summary** and choose the summary **Type** from the following options:
* *Technical and Insight Summary*
* *Forecast and Trend Analysis*
* *Comparative and Anomaly Detection*
* *Custom*
Click **Save** to apply changes.
You’ve successfully connected Gemini with your Databrain workspace!\
Your integration is now active — empowering you to leverage Gemini’s LLM capabilities for advanced metric summaries, contextual insights, and intelligent data exploration within your dashboards.
# Llama
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/llama
### Step 1: Configure Llama
1. Navigate to the **LLMs** section on settings page and click on **+LLM**
2. Choose Azure Open AI from the list.
3. In the **Configure Llama** panel:
* **Name**: Enter a descriptive name (e.g., `LLaMA Workspace Assistant`).
* **Base URL**: Provide the endpoint URL from your provider in the format: `https://.ai/v1`
* **API Key**: Paste your valid API Key provided by the LLaMA service provider.
* **Model Name**: Enter the model identifier (e.g., `meta-llama/Llama-3-**`).
4. Click **Authenticate** to complete the integration.
### Step 2: Connect LLM to Workspace
Navigate to your desired workspace and click on `settings icon` next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom
* From the **LLM** dropdown, choose the Llama model you just configured
Optionally enable **Metric Summary** and choose the summary **Type** from the following options: Technical and Insight Summary, Forecast and Trend Analysis, Comparative and Anomaly Detection, Custom.
Click **Save** to apply changes.
You’ve successfully connected Llama with your Databrain workspace!\
Your integration is now active — enabling Llama-powered metric summaries, contextual insights, and intelligent natural language interactions across your dashboards.
# Mixtral
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/mixtral
## Step 1: Configure Mixtral
Navigate to the `LLMs` section on the **Settings** page and click on **+LLM**.
Choose **Mixtral** from the list.
In the **Configure Mixtral** panel:
* **Name**: Enter a descriptive name (e.g., *Mixtral AI Assistant*).
* **Base URL**: Provide the endpoint URL from your provider in the format: `https://.ai/v1`
* **API Key**: Paste your valid API Key provided by the Mixtral service provider.
* **Model Name**: Enter the full model name (e.g., *mistralai/Mixtral-*\*\*)
Click **Authenticate** to activate the integration.
***
## Step 2: Connect LLM to Workspace
Navigate to your desired workspace and click on `settings icon` next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom
* From the **LLM** dropdown, choose the Mixtral model you just configured
Optionally enable **Metric Summary** and choose the summary **Type** from the following options:\
Technical and Insight Summary, Forecast and Trend Analysis, Comparative and Anomaly Detection, Custom.
Click **Save** to apply changes.
You’ve successfully connected Mixtral with your Databrain workspace!\
Your integration is now active — enabling Mixtral-powered LLM capabilities for intelligent insights, automated metric summaries, and seamless data interaction across your dashboards.
# Open AI
Source: https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors/open-ai
### Step 1: Configure Open AI
Navigate to the **LLMs** section on the settings page and click on **+LLM**.
Choose Open AI from the list.
In the **Configure Open AI** panel:
* **Name**: Enter a descriptive name (e.g., `GPT Workspace Assistant`).
* **API Key**: Paste your valid Open AI API Key.
Click **Authenticate** to activate the integration.
### Step 2: Connect LLM to Workspace
Navigate to your desired workspace and click on the **⚙️ settings icon** next to the workspace name.
Under the **General** tab:
* Scroll to the **LLM** section near the bottom
* From the **LLM** dropdown, choose the Open AI model you just configured
Optionally enable **Metric Summary** and choose the summary **Type** from the following options:\
Technical and Insight Summary, Forecast and Trend Analysis, Comparative and Anomaly Detection, Custom.
Click **Save** to apply changes.
You’ve successfully connected Open AI with your Databrain workspace!\
Your LLM integration is now active — enabling automated metric summaries, insights, and intelligent data exploration across your dashboards.
# Metric App Filter
Source: https://docs.usedatabrain.com/developer-docs/helpers/metric-app-filter
Metric App Filter: Instruction Manual
Using the App Filter in Metric:
* In your Metric, create a new filter
* In the "Apply On" section, enable the "App Filter" option
### Method 1: Passing from Component
* Use the parameter `"metric-filter-options"` to pass values directly from a component to the metric filter.
* Configuration changes based on the Filter Type and the Data Type.
1. **Single-Select Filter:**
* For *string-based* filters, pass just the value:
```javascript theme={"dark"}
metric-filter-options={JSON.stringify({ // note that invalid options will be filtered out
"Filter name for a string datatype": {
options: [
{ value: 'James Smith', label: 'James' },
{ value: 'Olivia Johnson', label: 'Olivia' },
{ value: 'Emma Brown', label: 'Emma' },
] // should have unique elements
defaultOption: 'James Smith', // value of the selected option
},
"Filter name for a number datatype": {
options: [{ value: 1, label: 'user_1' }, { value: 2, label: 'user_2' }], // should have unique elements
defaultOption: 1, // value of the selected option
},
```
2. **Multi-Select Filter:**
* For *string-based* filters, pass an array of values:
```javascript theme={"dark"}
metric-filter-options={JSON.stringify({ // note that invalid options will be filtered out
"Filter name for a string datatype": {
options: [
{ value: 'James Smith', label: 'James' },
{ value: 'Olivia Johnson', label: 'Olivia' },
{ value: 'Emma Brown', label: 'Emma' },
] // should have unique elements
defaultOption: ['James Smith', 'Olivia Johnson' ], // value of the selected option
},
"Filter name for a number datatype": {
options: [{ value: 1, label: 'user_1' }, { value: 2, label: 'user_2' }], // should have unique elements
defaultOption: 1, // value of the selected option
},
```
Refer the below “Options” document for further queries.
***
### Method 2: Passing from Guest Token
* You can link a guest token here to pass the filter values dynamically.\
Refer the below document to generate a guest token.
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params" : {
"appFilters": [{
“metricId”: “The id of the metric you want to have app filters”,
“values”: {
“paid_orders”: true,
“amount”: 500,
“country”: ["USA", "CANADA"] || "USA" // based on filter variant(select or multi select)
}
}]
}
}
```
***
### Method 3: Handling Large Selections with SQL Integration
Filters with a large number of options (e.g., over 500), manually passing all values becomes inefficient. With SQL integration, you can dynamically fetch options from your database, simplifying the process.
The SQL query specified under the `"sql"` key dynamically fetches the latest values from the specified database table.
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"appFilters": [
{
"metricId": "The id of the metric you want to have app filters",
"values": {
"paid_orders": true,
"amount": 500,
"country": {
"sql": "SELECT \"name\" FROM \"public\".\"countries\" WHERE isEnabled=true",
"columnName": "name"
}
}
}
]
}
}
```
#### Key Benefits:
1. **Dynamic Updates:** The SQL query retrieves only the latest relevant options from your database.
* Example: `SELECT "name" FROM "public"."countries" WHERE isEnabled=true` fetches active country names.
2. **Efficiency:** Eliminates the need to manually manage large datasets in the configuration.
3. **Flexibility:** The `columnName` specifies the field in the query result to use as filter values.
4. **Scalability:** Handles thousands of options seamlessly, reducing payload size and improving performance.
This approach is ideal for keeping filters updated with minimal effort, ensuring they remain efficient and user-friendly.
# Metric ID
Source: https://docs.usedatabrain.com/developer-docs/helpers/metric-id
Accessing the Metric ID
In the Data App that you created (see API Token to know more about how to create a data app), click on Embed Info > Add New Embed. Provide the **workspace name**, select embed type as **metric**, provide the **dashboard** which includes that metric and then metric to get the metric id.
The Embed ID is the metric id that you can use.
# Options
Source: https://docs.usedatabrain.com/developer-docs/helpers/options
The extra options/parameters that you can pass for your Web Component.
This page contains raw component examples. For a comprehensive, organized reference with detailed explanations, see our [Component Options Reference](/developer-docs/helpers/component-options-reference).
StackBlitz
View the comprehensive, organized reference guide with detailed explanations, examples, and best practices for all component options.
### Dashboard Component
```jsx theme={"dark"}
{
return
For the
metric-filter-options
prop, invalid options will be filtered out.
Server Event
.
### FAQs
As a web component, it does not automatically re-render upon prop changes. A common approach to address this is to force a re-render by displaying a loader and temporarily hiding the web component during prop updates. Instead of directly changing the props, you can set a temporary state to display the loader or hide the metric, then update the prop after a brief delay.
```javascript theme={"dark"}
// React example
const [isLoading, setIsLoading] = useState(false);
const [dashboardProps, setDashboardProps] = useState(initialProps);
const updateProps = async (newProps) => {
setIsLoading(true);
await new Promise(resolve => setTimeout(resolve, 100));
setDashboardProps(newProps);
setIsLoading(false);
};
return isLoading ?
Loading...
: ;
```
* `chart-colors` is a direct attribute on the component
* `chartColors` is a property within the `options` object
* Both serve the same purpose but `chartColors` in options takes precedence
```html theme={"dark"}
```
Use the various disable/hide options available:
```javascript theme={"dark"}
const minimalDashboard = {
hideDashboardName: true,
hideMetricCardShadow: true,
disableMetricCreation: true,
disableLayoutCustomization: true,
disableManageMetrics: true,
showDashboardActions: false
};
```
For metric components:
```jsx theme={"dark"}
```
Common issues with JSON.stringify:
1. **Undefined values are omitted:**
```javascript theme={"dark"}
// ❌ This will omit undefined properties
const options = { color: undefined, size: 12 };
JSON.stringify(options); // {"size":12}
// ✅ Use null or default values instead
const options = { color: null, size: 12 };
```
2. **Functions are omitted:**
```javascript theme={"dark"}
// ❌ Functions are not serialized
const options = { onClick: () => {}, size: 12 };
// ✅ Use string references for callbacks
const options = { onClickHandler: "myGlobalFunction", size: 12 };
```
3. **Circular references cause errors:**
```javascript theme={"dark"}
// ❌ This will throw an error
const obj = {};
obj.self = obj;
JSON.stringify(obj); // TypeError: Converting circular structure to JSON
```
**Enable Debug Mode:**
```javascript theme={"dark"}
// Add to your global scope
window.databrainDebug = true;
// Check browser console for detailed logs
```
**Common Debugging Steps:**
1. Open browser DevTools → Console
2. Look for error messages starting with "Databrain:"
3. Check Network tab for failed API requests
4. Verify token validity in Application → Local Storage
5. Test with minimal component configuration
**Component Health Check:**
```javascript theme={"dark"}
// Add this to test basic functionality
const testComponent = () => {
const testElement = document.querySelector('dbn-dashboard');
console.log('Component found:', !!testElement);
console.log('Token present:', !!testElement?.getAttribute('token'));
console.log('Dashboard ID:', testElement?.getAttribute('dashboard-id'));
};
```
**High Performance Impact:**
* `disableMainLoader: false` - Shows loading animations
* `disableUnderlyingData: false` - Loads additional data
* `chart-renderer-type: "svg"` - More CPU intensive than canvas
* Complex `chartAppearance` configurations
**Optimization Recommendations:**
```javascript theme={"dark"}
const performanceOptimized = {
disableMainLoader: true,
disableMetricLoader: true,
disableUnderlyingData: true,
shouldFitFullScreen: true
};
```
**For Large Datasets:**
```html theme={"dark"}
```
**Memory Usage:**
* Limit simultaneous dashboard instances
* Use lazy loading for multiple components
* Consider component cleanup on unmount
# Custom Fiscal Year filter setup in DataBrain
Source: https://docs.usedatabrain.com/developer-docs/helpers/options/custom-fiscal-year-filter-setup-in-databrain
Step-by-step guide to set up an Indian Fiscal Year filter in DataBrain for region-specific data analysis.
## 1. Configure the Date filter
* Navigate to the **dashboard** where you want to set up the **Fiscal Year filter**.
* Then, add a **Date filter** and select **preset options: Last Year** and **This Year**.
* In the **"Apply On"** section, choose the date column, then click **"Save"** to apply the filter to your dashboard.
## 2. View the changes in Dashboard
By default, the **"Last Year"** filter displays data from **January 1, 2024 to December 31, 2024**, and the **"This Year"** filter shows data from **January 1, 2025 to December 31, 2025**.
## 3. Configure the Date filter
To enable the **Indian Fiscal Year**, add the following option to the embed settings:
calendar-type='ind'
Refer to the documentation for more details:
## 4. View the changes in dashboard
After enabling the Indian Fiscal Year filter, the date ranges adjust as follows:
* **"Last Year"** now displays data from **April 1, 2023 to March 31, 2024**.
* **"This Year"** now displays data from **April 1, 2024 to March 31, 2025**.
**Yearly and quarterly time-series charts** will automatically follow the **Indian Fiscal Year (April to March)**
# Override Language
Source: https://docs.usedatabrain.com/developer-docs/helpers/override-language
The `@databrainhq/plugin` package allows you to customize the language of your embedded components by passing a translation dictionary and specifying the desired language.
### Overview
**Parameters:**
* `translation-dictionary`: A JSON object that maps keys (e.g., metric names, description, table columns, chart legends & label...etc) to their translations in multiple languages.
* `language`: A string representing the language code (e.g., `"en"`, `"fr"`, `"es"`) you want to use for the component's content.
When both parameters are used, the component will display the content in the specified language, falling back to the key if a translation for the selected language is unavailable.
### Usage Example
````tsx theme={"dark"}
```tsx
In this example, the label "total sales" will be displayed in French as "ventes totales."
### Fallback Mechanism
* If the `language` prop is set to a language code not available in the dictionary, the component will display the default key value (e.g., `"total sales"`).
* Ensure all required keys and translations are included in your dictionary to provide a seamless user experience.
````
# Server Event
Source: https://docs.usedatabrain.com/developer-docs/helpers/server-event
It is a function prop that detects and retrieves error or loading occurring within dashboard component, facilitating timely resolution and enabling various automated tasks to be triggered in response.
To make use of `handle-server-event` in dbn-dashboard, you first need to define the function that you want to pass to this prop in the global object, here's an example:
```js theme={"dark"}
window.databrainServerEvent = (code: string) => {
if (code) {
// do something
}
}
```
To implement it in dbn-dashboard component:
```html theme={"dark"}
```
This will attatch the funtion to the dbn-dashboard component, fetching the error or loading status which you can handle in your app.
Below is the list of all the codes that you can get from dbn-dashboard:
* TOKEN\_EXPIRED
* UNAUTHORIZED\_ORIGIN
* INVALID\_TOKEN
* INVALID\_DASHBOARD\_ID
* IS\_LOADING
* DATA\_LOADED
* ENTER\_FULL\_SCREEN\_MODE
* EXIT\_FULL\_SCREEN\_MODE
* ENTER\_SCHEDULED\_REPORT\_MODE
* SAVE\_SCHEDULED\_REPORT
* EXIT\_SCHEDULED\_REPORT\_MODE
* ENTER\_CUSTOMIZE\_LAYOUT\_MODE
* EXIT\_CUSTOMIZE\_LAYOUT\_MODE
* SAVE\_LAYOUT
* ENTER\_MANAGE\_METRICS\_MODE
* ENTER\_METRICS\_GALLERY\_MODE
* EXIT\_MANAGE\_METRICS\_MODE
* EXIT\_METRICS\_GALLERY\_MODE
* SAVE\_MANAGE\_METRICS
* SAVE\_CLIENT\_GALLERY\_METRICS
* ARCHIVE\_METRIC
* DOWNLOAD\_METRIC
* DOWNLOAD\_METRIC\_WITHOUT\_FILTERS
* SAVE\_METRIC\_PNG
* METRIC\_FILTER\_APPLIED
* DASHBOARD\_FILTER\_APPLIED
* CREATE\_METRIC
* UPDATE\_METRIC
* ENTER\_CREATE\_METRIC
* ENTER\_EDIT\_METRIC
* DATASET\_SEARCH\_FOCUSED
* DATASET\_TABLE\_SELECTED
* COLUMN\_DRAGGED\_TO\_DIMENSIONS
* COLUMN\_DRAGGED\_TO\_MEASURES
* COLUMN\_AGGREGATE\_CHANGED
* CHART\_TYPE\_CHANGED
* START\_DOWNLOAD\_ALL\_METRICS
* DOWNLOAD\_ALL\_METRICS
* START\_DASHBOARD\_PDF
* EXPORT\_DASHBOARD\_PDF
***NOTE***: If you get error like `Property 'functionName' does not exist on type 'Window & typeof globalThis'`, add the type of window as any.
# Token Body
Source: https://docs.usedatabrain.com/developer-docs/helpers/token-body
Here you will see what are the fields to pass in the body while creating a guest token.
JSON body -
* dataAppName (required string) - The name of the data app for which you are creating the guest token.
* clientId (required string) - The primary key of the client/organization in the workspace for which you are creating the guest token.
* params (optional JSON object) - Optional token parameters (filters, embed allowlisting, end-user identity, timezone).
* permissions (optional JSON object) - Dashboard permission toggles. Boolean keys: `isEnableArchiveMetrics`, `isEnableManageMetrics`, `isEnableCreateDashboardView`, `isEnableMetricUpdation`, `isEnableCustomizeLayout`, `isEnableUnderlyingData`, `isEnableDownloadMetrics`, `isShowSideBar`, `isShowDashboardName`, `isDisableMetricCreation`. No other keys exist (there is no `permissions.dashboards`).
* expiryTime (optional number, milliseconds) - How long the token stays valid, measured from the moment it is created. If omitted, the token never expires.
* datasourceName(required string with multi data source connection) - The data source name to be used as data connection. (not applicable for datasource or datamart connection).
* datamartName (optional string) - Scope the token to a specific Datamart.
The body is validated strictly: any field not listed here is rejected with `INVALID_REQUEST_BODY`. `dataAppId`, `client_id`, and `tenant_id` are not valid fields — use `dataAppName` and `clientId`.
body -> params (optional JSON object) -
* rlsSettings (optional array of JSON object) - if you want to apply any rls settings then here you can pass the "metricId" for which you want to apply the filter and "values" which is an object of filter name and filter value.
* appFilters (optional array of JSON object) - if you want to apply metric-level filters with the app filter variant then here you can pass the "metricId" for which you want to apply the filter and "values" which is an object of filter name and value.
* dashboardAppFilters (optional array of JSON object) - dashboard-level filters to apply on a specific embedded dashboard.
* allowedEmbeds (optional array of strings) - allowlist of IDs this token is allowed to load. Each entry must match the ID passed to the embed component (`dashboardId` attribute); embed IDs and dashboard IDs both resolve. Loading any other ID fails with `UNAUTHORIZED`.
* userIdentifier (optional string) - unique identifier for the end-user to enable private/publish metrics in embeds.
* timezone (optional string) - IANA timezone (e.g. `"America/New_York"`) for timezone-aware queries and date formatting.
* accessPermissions (optional JSON object) - end-user filter controls: `isAllowEndUserDashboardFilter`, `isAllowEndUserMetricFilter`, `isAllowDashboardFilterNameChange`, and `isAllowMetricFilterNameChange` (booleans), plus optional `dashboardFilterColumns` and `metricFilterColumns` arrays of `{ tableName, columns }`.
params -> rlsSettings (optional array of JSON object) -
* metricId (required string) - the id of the metric you want to apply the rls filters which you can find on the metric page in the header below the metric name.
* values (required JSON object) - the filters name and value pairs that you want to apply.
params -> appFilters (optional array of JSON object) -
* metricId (required string) - the id of the metric you want to apply the rls filters which you can find on the metric page in the header below the metric name.
* values (required JSON object) - the filters name and value pairs that you want to apply.
params -> hideDashboardFilters(optional array of strings) -
* array of name of filters
# Translate
Source: https://docs.usedatabrain.com/developer-docs/helpers/translate
The plugin components support multilingual translations using the language and translationDictionary props. This allows you to render metric titles, descriptions, and labels in the end user
```html theme={"dark"}
```
### `translation-dictionary` Format
The `translation-dictionary` is a simple object where:
* Each **key** matches the exact text you want to translate (e.g., metric title, subtitle, label).
* Each **value** is an object with translations in various language codes (`en`, `fr`, `es`, etc.).
* **Longer and more descriptive keys should be placed first** to ensure they're matched before shorter or nested ones.
Example:
```javascript theme={"dark"}
const translationDictionary = {
"Total Sales and Total Profit by Category": {
en: "Total Sales and Total Profit by Category",
fr: "Ventes totales et bénéfices totaux par catégorie",
de: "Gesamtumsatz und Gesamtgewinn nach Kategorie",
// ...
},
"This metric provides a breakdown of financial outcomes across different groupings...": {
en: "This metric provides a breakdown of financial outcomes across different groupings...",
fr: "Cette mesure fournit une répartition des résultats financiers...",
// ...
},
"Note: Values represent aggregated figures...": {
en: "Note: Values represent aggregated figures...",
fr: "Remarque : Les valeurs représentent des chiffres agrégés...",
// ...
},
"Total Sales": {
en: "Total Sales",
fr: "Ventes Totales",
// ...
},
"Sum of Profit": {
en: "Sum of Profit",
fr: "Somme du bénéfice",
// ...
},
"Category": {
en: "Category",
fr: "Catégorie",
// ...
},
"Sales": {
en: "Sales",
fr: "Ventes",
// ...
},
"Product": {
en: "Product",
fr: "Produit",
// ...
}
};
```
Important Guidelines
* 🔑 **Keys must match exactly**: The keys in `translation-dictionary` must exactly match the text in your dashboard configuration (e.g., metric titles, chart subtitles, dynamic labels).
* 🧠 **Prefer longer keys first**: If multiple keys are substrings of each other, always define and check the longer, more descriptive one first.
* 🌐 **Add all relevant labels**: Include all chart titles, subtitle blocks, footnotes, and section labels that might appear in a rendered dashboard.
Fallback Behavior
If a translation is **missing** for a given key/language:
* The system will **fall back** to the original key.
# Workspace name
Source: https://docs.usedatabrain.com/developer-docs/helpers/workspace-name
Accessing and Editing Workspace Name
On the Home page, navigate to the Workspaces section to view the list of Shared and Private workspaces.
To edit a workspace name, click the Workspace Settings icon, update the name as desired, and click 'Save'.
# How to embed?
Source: https://docs.usedatabrain.com/developer-docs/how-to-embed
Learn how to create a data app, generate API tokens, and create guest tokens for embedding Databrain dashboards in your application.
* Navigate to the "Data" section in your app.
* Look for the "Data Apps" option and select it.
* Click on "**New Data App**" button. Provide the required information including naming it and configuring basic settings.
Refer to "[**Dashboard ID**](https://docs.usedatabrain.com/developer-docs/helpers/dashboard-id)" for generating embed ID and refer "[**API TOKEN**](https://docs.usedatabrain.com/developer-docs/helpers/api-token)" for generating api token that will be used to generate "**guest token**" later.
Once API Token is generated, create "**guest token**" with "**client ID**", which is a unique identifier for the client or user you're creating the token for and the **data app name** that you created above in the body.
* Guest tokens are used for allowing temporary, limited access to your Data App.
* Go to postman or any other API platform.
* Set the URL as [**https://api.usedatabrain.com/api/v2/guest-token/create.**](https://api.usedatabrain.com/api/v2/guest-token/create)
* In the Authorization tab, select type as "**Bearer Token**" and in token field add the "**API token**" that you created in your data app.
* You'll need to specify a **Client ID**.
* Click on "**Send**". The generated guest token will be associated with the provided Client ID and data app.
Use the guest token and the embed ID to test your embed.
# License Key Validation for Self-Hosted App
Source: https://docs.usedatabrain.com/developer-docs/license-key-validation-for-self-hosted-app
This guide is essential for self-hosted app users, detailing the process of license key validation and renewal.
### For Logged-In Users:
1. **Free Trial Period**
* Upon starting the app, **a temporary license key** will be issued, providing access for a **15-day free trial period**.
* During this trial, you will have full access to all features of the app.
2. **Post-Trial Access**
At the end of the 15-day trial period, the temporary license key will automatically **expire**, and access to the app will be restricted.
3. **Requesting a New License Key**
* To continue using the app beyond the trial period, a **new license key** is required.
* Please share the app key with **our support team** in order to initiate the renewal process.
4. **License Key Renewal Process**
* Upon receiving the expired key, **our team** will generate and provide a new license key.
* This key will enable continued access to the app under the purchased plan.
5. **Re-authentication**
* Once the new license key is received, kindly proceed to **re-authenticate** the app using the updated key.
* Successful authentication will restore full access and ensure uninterrupted usage.
### For New Sign-Ins:
1. **Initial Login:** Upon your first login, you will be prompted to enter the license key.
2. **Enter License Key:** Paste your license key in the designated field and click 'Submit'.
3. **Re-authentication:** After submission, you will need to sign in again to activate your license.
### License Validity and Renewal
* **Activation:** Your instance will remain active for the duration of your license key’s validity.
* **Renewal Reminder:** Please note that the license key is valid until the specified expiry date. You will need to repeat these steps to update the license key upon expiration.
# Client Setup
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/client-setup
Detailed configuration instructions for each AI client
This guide covers full configuration for each supported AI client, including file paths, restart steps, self-hosted setup, and optional API-token-only configuration.
***
## Configuration by Client
### Add via CLI
```bash theme={"dark"}
codex mcp add databrain --env DATABRAIN_SERVICE_TOKEN=YOUR_SERVICE_TOKEN -- npx @databrainhq/mcp-server
```
Replace `YOUR_SERVICE_TOKEN` with your Databrain service token.
### Self-Hosted
For a self-hosted Databrain instance, include the API URL:
```bash theme={"dark"}
codex mcp add databrain \
--env DATABRAIN_SERVICE_TOKEN=YOUR_SERVICE_TOKEN \
--env DATABRAIN_API_URL=https://api.your-databrain.example.com \
--env DATABRAIN_DEMO_DOMAIN=https://demo.your-databrain.example.com \
-- npx @databrainhq/mcp-server
```
### Verify
```bash theme={"dark"}
codex mcp list
```
Start a new Codex session after adding or updating the server.
### Config File Location
* **Project-level:** `.cursor/mcp.json` in your project root
* **Global:** `~/.cursor/mcp.json`
Project-level config takes precedence when both exist.
### Configuration
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
### Restart
After saving the config file, restart Cursor or reload the window (**Cmd+Shift+P** -> "Reload Window") to pick up the new MCP server.
### Config File Location
* **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
* **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
### Configuration
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
### Restart
Fully quit Claude Desktop and reopen it. On macOS, use **Cmd+Q** to quit.
### Add via CLI
```bash theme={"dark"}
claude mcp add databrain -- npx @databrainhq/mcp-server
```
### Set Environment Variable
Add to your shell profile (`.bashrc`, `.zshrc`, etc.):
```bash theme={"dark"}
export DATABRAIN_SERVICE_TOKEN=""
```
Then reload your shell:
```bash theme={"dark"}
source ~/.zshrc
```
### Verify
```bash theme={"dark"}
claude mcp list
```
You should see `databrain` in the list of configured servers.
### Config File Location
`~/.codeium/windsurf/mcp_config.json`
### Configuration
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
### Restart
Restart Windsurf after saving the config file.
### Direct Execution
The server uses stdio transport and works with any MCP-compatible client.
```bash theme={"dark"}
export DATABRAIN_SERVICE_TOKEN=""
npx @databrainhq/mcp-server
```
### Programmatic Usage
If your client accepts a command and arguments:
* **Command:** `npx`
* **Args:** `["@databrainhq/mcp-server"]`
* **Env:** `{ "DATABRAIN_SERVICE_TOKEN": "" }`
***
## Self-Hosted Databrain
If you're running a self-hosted Databrain instance, set `DATABRAIN_API_URL` to the API origin for that instance.
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": "",
"DATABRAIN_API_URL": "https://api.your-databrain.example.com",
"DATABRAIN_DEMO_DOMAIN": "https://demo.your-databrain.example.com"
}
}
}
}
```
Checklist:
* `DATABRAIN_API_URL` must be the API origin, not the dashboard URL.
* The token must be minted from that same self-hosted instance. Tokens are not portable across instances.
* The MCP client process must be able to reach the URL through your VPN, firewall, or certificate setup.
* Set `DATABRAIN_DEMO_DOMAIN` if `get_demo_link` should use a custom preview host.
***
## API-Token-Only Mode
By default, use a service token. It lets the MCP server discover resources, manage data apps, create API tokens, and run semantic-layer workflows.
If you only need operations inside one existing data app, you can configure an API token instead:
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_API_TOKEN": ""
}
}
}
}
```
API-token-only mode is scoped to one data app. It supports embed, guest token, widget, demo link, and scheduled report metadata operations, but org-level discovery and setup tools require `DATABRAIN_SERVICE_TOKEN`.
You can also provide both tokens:
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": "",
"DATABRAIN_API_TOKEN": ""
}
}
}
}
```
***
## Environment Variables Reference
| Variable | Required | Default | Description |
| ------------------------- | ------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------- |
| `DATABRAIN_SERVICE_TOKEN` | One of two | - | Org-level token from **Settings -> Service Tokens** |
| `DATABRAIN_API_TOKEN` | One of two | - | Per-data-app token used for embed, widget, guest token, demo link, and report metadata operations |
| `DATABRAIN_API_URL` | Required for self-hosted | `https://api.usedatabrain.com` | API base URL |
| `DATABRAIN_DEMO_DOMAIN` | No | `https://demo.usedatabrain.com` | Hosted preview base URL for `get_demo_link` |
At least one of `DATABRAIN_SERVICE_TOKEN` or `DATABRAIN_API_TOKEN` must be set. If both are set, service-token mode is used for org-level operations.
***
## Verifying the Connection
After configuring your client, try asking your AI assistant:
> **"Who am I authenticated as in Databrain?"**
This calls `whoami` and confirms whether the server is running in service-token or API-token mode.
Then ask:
> **"List my Databrain data apps"**
If you get a missing-token configuration error, double-check that the token is set in the `env` block of your MCP config and restart your client.
See the [Troubleshooting guide](/developer-docs/mcp-server/troubleshooting) for common issues and solutions.
# MCP Server
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/overview
Add embedded analytics to your app using natural language. Connect the Databrain MCP server to any AI assistant and describe what you want.
`@databrainhq/mcp-server` is available on [npm](https://www.npmjs.com/package/@databrainhq/mcp-server) and requires Node.js 18+.
The Databrain MCP server lets you manage embedded analytics through your AI assistant. Instead of navigating the Databrain UI or calling REST APIs directly, describe what you want in plain English and the assistant handles the setup steps for you.
```
"Embed my sales dashboard in my React app"
"Find valid client IDs for my workspace"
"Add a widget to a customer's dashboard"
"Dry-run this SQL as a Databrain metric"
"Enable self-serve metric creation on this embed"
"What was total revenue last month?"
```
The server implements the [Model Context Protocol](https://modelcontextprotocol.io) (MCP), an open standard that connects AI assistants to external tools and data sources.
***
## How It Works
Tell your AI assistant what you need: embed a dashboard, find valid tenants, query data, customize theming, add customer-specific widgets, migrate SQL into a metric, enable self-serve analytics, or review scheduled report configuration.
The server maps your request to the right Databrain actions, manages authentication, validates inputs, and applies production safeguards for writes.
Your data apps, dashboards, embeds, tenants, widgets, workspace metrics, semantic layer, and scheduled report metadata are accessed through the Databrain API. Results flow back through the server to your assistant.
***
## MCP Server vs NPM Plugin
Databrain offers two integration paths. Choose based on your workflow:
| | MCP Server | NPM Plugin (`@databrainhq/plugin`) |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| **Best for** | Setting up and configuring embeds via AI assistant | Rendering embeds in your frontend |
| **How it works** | Natural language in Codex, Cursor, Claude, Windsurf, or any MCP client | Web components (``, ``) |
| **What it does** | Creates embeds, discovers tenants, manages tokens, configures themes/filters, queries data, edits widgets, enables self-serve analytics, generates frontend code | Renders dashboards and metrics in the browser |
| **When you use it** | During development, setup, and ongoing embed maintenance | At runtime in your application |
They're complementary, not competing. Use the MCP server to set up and maintain your embeds, then use the NPM plugin to render them in your app. The MCP server can generate plugin code via `generate_embed_code`.
***
## Key Capabilities
Discover data apps, select dashboards, create embeds, and generate framework-specific frontend code through conversation.
List valid `clientId` values from your tenancy database before creating guest tokens or editing customer dashboards.
Ask questions in natural language. The AI converts them to SQL, runs the query, and returns results with chart suggestions.
List, add, update, remove, or generate widgets for a specific customer's dashboard without changing other customers.
Validate warehouse-tested SQL, dry-run Databrain metric writes, and apply only after explicit production confirmation.
Create unpublished, unattached workspace-level metrics from validated SQL before deciding where to publish them.
Customize colors, fonts, chart styles, responsive breakpoints, card styling, and access presets.
Enable drag-and-drop or chat metric creation, configure filters, localize embeds, and lock down permissions.
Populate, maintain, and auto-generate table/column descriptions to improve natural language query accuracy.
***
## Supported AI Clients
The server uses stdio transport and works with any MCP-compatible client:
* **Codex** - OpenAI's coding agent CLI
* **Cursor** - IDE with built-in MCP support
* **Claude Desktop** - Anthropic's desktop app
* **Claude Code** - CLI tool for developers
* **Windsurf** - Codeium's AI IDE
* **Any MCP client** - Any tool that supports the Model Context Protocol
***
## What's Included
The server ships with **36 tools**, **8 guided prompts**, and **11 built-in knowledge resources**.
| Component | Count | Purpose |
| ------------------------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------ |
| [Tools](/developer-docs/mcp-server/tools-reference) | 36 | API operations for discovery, tenants, embeds, widgets, workspace metrics, semantic layer, metric migration, and reports |
| [Prompts](/developer-docs/mcp-server/prompts-reference) | 8 | Guided workflows for common setup and production-safe maintenance tasks |
| Knowledge Resources | 11 | Built-in references the AI consults automatically |
Datasource and workspace setup still happen in the Databrain UI. Datamarts can be planned with `create_datamart` in `dry_run` mode and created only with `confirm: "APPLY_TO_PRODUCTION"`. Workspace-level metrics can be planned with `create_workspace_metric` in `dry_run` mode and created or updated only after the same explicit confirmation. Re-applying with the same `metricId` updates the metric in place and re-hydrates Dimensions/Measures from the new SQL. The semantic layer is populated and maintained via MCP tools.
### Built-in Knowledge Resources
The server bundles reference documentation that your AI assistant reads automatically when needed.
| Resource | Content |
| ----------------------- | ----------------------------------------------------------------------------------------- |
| Getting Started | Entity model, onboarding checklist, token types |
| API Reference | Key Databrain API endpoints and examples |
| Embedding Guide | Framework-specific code for React, Next.js, Vue, Angular, Svelte, SolidJS, and vanilla JS |
| Theme Reference | Admin theme, component theme, and chart appearance schemas |
| Web Component Reference | `` and `` attributes |
| Filter Reference | Filter types, operators, runtime filters, and dashboard filters |
| Self-Serve Reference | Permission flags and metric creation modes |
| Semantic Layer Guide | Semantic layer setup for AI-powered querying |
| Multi-Tenancy Guide | Row-level security, `clientId` patterns, and tenant isolation |
| Use Case Guides | Tool sequences and decision guidance for common flows |
| Permission Schema | Embed `accessSettings`, guest token permissions, precedence rules, and limitations |
***
## Environment Variables
At least one credential is required. Use a service token for full setup and management flows; use an API token only when you are operating inside one data app.
| Variable | Required | Default | Description |
| ------------------------- | ------------------------ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DATABRAIN_SERVICE_TOKEN` | One of two | - | Org-level token from **Settings -> Service Tokens**. Powers discovery, tenant lookup, setup, data app management, semantic layer, and production-safe datamart and workspace-metric operations. |
| `DATABRAIN_API_TOKEN` | One of two | - | Per-data-app token. Created automatically during setup via `create_api_token`, or provided manually for a single data app. |
| `DATABRAIN_API_URL` | Required for self-hosted | `https://api.usedatabrain.com` | API origin for cloud or self-hosted Databrain. |
| `DATABRAIN_DEMO_DOMAIN` | No | `https://demo.usedatabrain.com` | Base URL used by `get_demo_link` for hosted dashboard previews. |
***
## Authentication Model
Databrain uses two token types:
**Service Token** - org-level, set once in your MCP config. Used for datasource/datamart/workspace discovery, tenant lookup, data app and API token management, dashboard listing, semantic layer operations, natural language querying, `create_datamart`, and `create_workspace_metric`.
**API Token** - scoped to a single data app. Used for embed operations, guest token generation, widget operations, data-app-scoped dashboard listing, and scheduled report metadata. The MCP server can create and activate API tokens via `create_api_token` when a service token is configured.
Production write tools default to dry-run where supported and require explicit confirmation before applying changes.
***
## Get Started
Set up in 2 minutes
Common use cases
All 36 tools
# Prompts Reference
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/prompts-reference
All 8 guided prompts available in the Databrain MCP server
Prompts are guided workflows that your AI assistant can follow. They encode best practices, safe sequencing, and the correct tool order for common tasks. You can trigger a prompt by asking naturally or by referencing the prompt name directly.
## At a Glance
| Prompt | Category | What It Does |
| ------------------------------ | -------------------- | ----------------------------------------------------------------------------------------------------------- |
| `embed-existing-dashboard` | Setup | Embed a dashboard that already exists in the Databrain UI |
| `embed-blank-dashboard` | Setup | Create per-client dashboard embeds for multi-tenant apps |
| `brand-my-embed` | Customization | Customize colors, fonts, cards, charts, responsive layout, and access presets |
| `query-data` | Data exploration | Query a datamart with natural language and use the semantic layer |
| `populate-semantic-layer` | Data setup | Generate and save table/column descriptions, synonyms, and examples |
| `customize-customer-dashboard` | Dashboard updates | Add, update, remove, or generate widgets for one customer's dashboard |
| `sql-to-metric-migration` | Production migration | Validate SQL, dry-run metric creation/update on a customer dashboard, then apply with explicit confirmation |
| `sql-to-workspace-metric` | Internal analytics | Create or update an unpublished workspace metric from SQL (no clientId / not attached to a dashboard) |
***
## Setup Prompts
**Embed a dashboard you've already built in the Databrain UI.**
The most common starting point. Walks through data app selection, API token creation, workspace and dashboard selection, embed creation or reuse, guest token generation, and frontend code generation.
**Example asks:**
* "Embed my sales dashboard in my React app"
* "Set up a Databrain embed for my dashboard"
* "I want to embed the revenue overview dashboard"
**Tools used:** `list_data_apps` -> `list_api_tokens` / `create_api_token` -> `list_workspaces` -> `list_dashboards` -> `list_embeds` -> `create_embed` -> `get_embed_details` -> `generate_guest_token` -> `generate_embed_code`
[See full workflow ->](/developer-docs/mcp-server/workflows#embed-an-existing-dashboard)
**Multi-tenant setup where each client gets their own dashboard.**
Creates per-client dashboard embeds using `clientId` for customer-specific dashboard copies. This is the right flow when customers need different layouts, self-serve metrics, or per-client dashboard isolation.
**Example asks:**
* "Create per-client dashboard embeds for my SaaS app"
* "Set up multi-tenant embeds with separate dashboards per customer"
* "I need each client to have their own dashboard copy"
**Tools used:** `list_data_apps` -> `list_api_tokens` / `create_api_token` -> `list_dashboards` -> `list_datamarts` -> `create_embed` per client -> `generate_guest_token` -> `generate_embed_code`
[See full workflow ->](/developer-docs/mcp-server/workflows#multi-tenant--per-client-embeds)
***
## Data Prompts
**Query your data with natural language and manage semantic context.**
Ask questions about your data without setting up dashboards. The assistant verifies the datamart and semantic layer before calling `ask_question`.
**Example asks:**
* "What was total revenue last month?"
* "Compare sales across regions for Q1"
* "Show me the top 10 products by revenue"
**Tools used:** `list_datamarts` -> `get_semantic_layer` -> `update_semantic_layer` or `start_semantic_layer_generation` if needed -> `ask_question`
[See full workflow ->](/developer-docs/mcp-server/workflows#query-data-with-natural-language)
**Generate and save table/column descriptions to improve natural language querying.**
Bootstraps the semantic layer by generating business-friendly descriptions, synonyms, and example questions, then pushes them to Databrain.
**Example asks:**
* "Set up the semantic layer for my orders datamart"
* "Add descriptions to all my tables and columns"
* "Improve the semantic layer quality for better query accuracy"
**Tools used:** `list_datamarts` -> `get_semantic_layer` -> `update_semantic_layer` -> `get_semantic_layer` -> `ask_question`
[See full workflow ->](/developer-docs/mcp-server/workflows#populate-the-semantic-layer)
***
## Embed Customization Prompt
**Customize colors, fonts, chart styles, responsive layout, cards, and access presets.**
Applies visual theming to match your product's branding. Supports theme presets, custom colors, font family, card styling, chart appearance, responsive breakpoints, and access presets.
**Example asks:**
* "Make my embed match our brand: primary color #4F46E5, dark mode"
* "Apply the corporate theme and use Inter font"
* "Customize chart colors to use our brand palette"
**Tools used:** `list_embeds` -> `get_embed_details` -> `customize_embed_theme` -> `update_embed` when advanced patching is needed
[See full workflow ->](/developer-docs/mcp-server/workflows#brand-and-theme-an-embed)
***
## Customer Dashboard Prompts
**Add, modify, remove, or generate widgets for one customer's dashboard.**
This flow is designed for customer-specific dashboard updates. The assistant asks for `clientId` and `dashboardName`, resolves the required resources automatically, and keeps every change scoped to one customer.
**Example asks:**
* "Add the Calls per Day widget to Acme's dashboard"
* "Remove the billing widget for one client only"
* "Generate a widget showing disqualification reasons for this customer"
* "Give me a demo link so I can see what this client sees"
**Tools used:** `list_tenants` when `clientId` is unknown -> `list_widgets` -> `generate_widget` or `add_widget` -> `update_widget` / `remove_widget` -> `list_widgets` -> `get_demo_link`
[See full workflow ->](/developer-docs/mcp-server/workflows#customize-a-customer-dashboard)
**Production-safe SQL-to-metric migration on a customer dashboard.**
Converts validated warehouse SQL into a Databrain metric/widget with an explicit validation, dry-run, review, apply, and verification sequence. Use this when the metric should appear on a customer's embedded dashboard (`clientId` required).
**Example asks:**
* "Validate this SQL as a new metric on my operations dashboard"
* "Dry-run creating this converted query as a metric, then show me the plan"
* "Apply the approved metric migration"
**Tools used:** `list_workspaces` -> `list_dashboards` -> `list_widgets` -> `validate_metric_spec` -> `create_or_update_metric_from_query` in `dry_run` -> `create_or_update_metric_from_query` in `apply` with `confirm: "APPLY_TO_PRODUCTION"` -> `list_widgets` -> `get_demo_link`
[See full workflow ->](/developer-docs/mcp-server/workflows#sql-to-metric-migration)
**Create or update an unpublished workspace metric from SQL (internal analytics).**
Turns validated warehouse SQL into a workspace-scoped metric using the org service token. No `clientId`, and the metric is not attached to a dashboard. Pass an existing `metricId` to update in place — the query and Dimensions/Measures are re-hydrated; omit `metricId` to create.
**Example asks:**
* "I have this SQL — make it a metric in Databrain, but don't attach it to a dashboard"
* "Update the SQL on my existing workspace metric and refresh Dimensions/Measures"
* "Dry-run an unpublished Revenue by Region workspace metric"
**Tools used:** `list_workspaces` -> `discover_datasource_schema` -> `create_workspace_metric` in `dry_run` -> `create_workspace_metric` in `apply` with `confirm: "APPLY_TO_PRODUCTION"`
[See full workflow ->](/developer-docs/mcp-server/workflows#create-an-unattached-workspace-metric)
***
## Prompt Behavior
* Prompt flows are interactive. The assistant presents results and waits for user input before the next mutating step.
* Token and resource details stay in your MCP configuration and Databrain workspace. The assistant does not need service tokens, API tokens, data app IDs, datasource IDs, or embed IDs unless you provide them proactively.
* Use `list_tenants` to discover valid `clientId` values from the workspace tenancy database before guest-token, demo-link, scheduled-report, or customer-dashboard widget work.
* Use `externalMetricId`, not `metricId`, for `update_widget` and `remove_widget`.
* `create_datamart`, `create_workspace_metric`, and `create_or_update_metric_from_query` apply operations require `confirm: "APPLY_TO_PRODUCTION"`.
***
## Related
See these prompts in action with end-to-end walkthroughs
Detailed docs for every tool
# Quickstart
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/quickstart
Get the Databrain MCP server running in 2 minutes
You'll need a Databrain account, Node.js 18+, and an MCP-compatible AI client. A service token is recommended because it unlocks the full setup flow.
## Prerequisites
* **Node.js 18+** - check with `node --version`
* **A Databrain account** - [sign up here](https://app.usedatabrain.com/users/sign-up) if you don't have one
* **An AI client** - Codex, Cursor, Claude Desktop, Claude Code, Windsurf, or another MCP-compatible client
* **A Databrain credential** - preferably `DATABRAIN_SERVICE_TOKEN`
***
1. Log in to [Databrain](https://app.usedatabrain.com)
2. Go to **Settings -> Service Tokens**
3. Create a new token and copy it
Keep your service token secure. It provides org-level access to Databrain resources.
Add the MCP server configuration to your client. Pick your client below:
Add the MCP server with your service token:
```bash theme={"dark"}
codex mcp add databrain --env DATABRAIN_SERVICE_TOKEN=YOUR_SERVICE_TOKEN -- npx @databrainhq/mcp-server
```
Verify the server is configured:
```bash theme={"dark"}
codex mcp list
```
Start a new Codex session after adding the server.
Add to `.cursor/mcp.json` (project-level) or `~/.cursor/mcp.json` (global):
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
```bash theme={"dark"}
claude mcp add databrain -- npx @databrainhq/mcp-server
```
Set your token in the shell that launches Claude Code:
```bash theme={"dark"}
export DATABRAIN_SERVICE_TOKEN=""
```
Add to `~/.codeium/windsurf/mcp_config.json`:
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
The server uses stdio transport. Set environment variables and run:
```bash theme={"dark"}
export DATABRAIN_SERVICE_TOKEN=""
npx @databrainhq/mcp-server
```
For detailed per-client instructions, API-token-only mode, restart steps, and self-hosted configuration, see the [Client Setup Guide](/developer-docs/mcp-server/client-setup).
Open your AI assistant and ask:
> **"Who am I authenticated as in Databrain?"**
This calls `whoami` and confirms whether the MCP server is running with a service token or API token.
Then ask:
> **"List my Databrain data apps"**
If everything is configured correctly, you'll see your available data apps.
If you see a configuration error saying that no token is set, double-check that the token is in the `env` block of your MCP config and restart your AI client. See [Troubleshooting](/developer-docs/mcp-server/troubleshooting) for more help.
Now try a real task:
> **"Set up a Databrain embed for my dashboard"**
The assistant walks you through each step interactively: picking your data app, selecting a workspace and dashboard, creating or reusing an embed, generating a guest token, and generating frontend code.
Other things to try:
> **"Add a widget to a customer's dashboard"**
> **"List tenants for my workspace so I can pick the right clientId"**
> **"Dry-run creating this SQL query as a Databrain metric"**
> **"Enable self-serve metric creation on this embed"**
> **"Brand my embed to match our company colors"**
That's it. The assistant handles the Databrain API so you can focus on building.
***
## Credential Modes
| Mode | When to use it | What works |
| ------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Service token | Recommended default | Full discovery, tenant lookup, setup, semantic layer, data app management, and production-safe datamart and workspace-metric operations |
| API token | Existing single-data-app embed work | Embed operations, guest tokens, widget operations, demo links, and scheduled report metadata for that data app |
If both tokens are configured, the MCP server prefers `DATABRAIN_SERVICE_TOKEN` for org-level operations and can activate per-data-app API tokens during setup.
***
## Next Steps
Step-by-step guides for common tasks
Detailed configuration per client
All 36 tools
# Tools Reference
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/tools-reference
All 36 tools available in the Databrain MCP server
The MCP server provides 36 tools organized by category. Your AI assistant picks the right tools automatically based on what you ask.
Datasource and workspace setup are completed in the Databrain UI. Datamarts can be planned with `create_datamart` in `dry_run` mode and created only with `confirm: "APPLY_TO_PRODUCTION"`.
***
## Auth Modes
| Auth | Used for |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Service Token | Org-level discovery, tenant lookup, data app and API token management, dashboard listing by workspace, semantic layer operations, natural language querying, datamart creation, and workspace-level metric creation |
| API Token | Embed operations, guest token generation, data-app-scoped dashboard listing, widget operations, demo links, and scheduled report metadata |
| No Databrain API call | Code generation or identity checks that do not call Databrain APIs |
Production write tools default to dry-run where supported and require explicit confirmation before applying changes.
***
## Session & Identity
| Tool | Description | Auth |
| -------- | ------------------------------------------------------- | --------------------- |
| `whoami` | Return the credential mode currently used for API calls | No Databrain API call |
Use `whoami` before mutating operations when you need to confirm whether the session is running with a service token or an API token.
***
## Infrastructure - Exploration and Setup
6 tools for discovering infrastructure and managing production-safe datamart setup.
| Tool | Description | Auth |
| ---------------------------- | ------------------------------------------------------------------------------ | ------------- |
| `list_datasources` | List active datasources in your organization | Service Token |
| `discover_datasource_schema` | Inspect tables and columns in a datasource | Service Token |
| `list_datamarts` | List datamarts with table counts and semantic layer scores | Service Token |
| `list_workspaces` | List workspaces with datamart and datasource connections | Service Token |
| `sync_datasource` | Trigger a datasource schema sync to refresh table and column metadata | Service Token |
| `create_datamart` | Dry-run or apply creation of a datamart from selected tables and relationships | Service Token |
### `create_datamart` Safety
`create_datamart` defaults to `mode: "dry_run"` and returns a preview of the datamart configuration. Applying the write requires:
```json theme={"dark"}
{
"mode": "apply",
"confirm": "APPLY_TO_PRODUCTION"
}
```
Key inputs include `name`, `datasourceName`, `tableList`, `relationships`, optional `tenancySettings`, or an advanced JSON configuration.
***
## Data Apps & Tokens
6 tools for managing data apps, tenants, and API tokens. These are usually handled automatically during embed setup.
| Tool | Description | Auth |
| ------------------ | --------------------------------------------------------------------- | ------------- |
| `list_data_apps` | List data apps in your organization, optionally filtered by workspace | Service Token |
| `list_tenants` | List available tenants/clients from the workspace tenancy database | Service Token |
| `create_data_app` | Create a new data app | Service Token |
| `list_api_tokens` | List API tokens for a data app; omit `dataAppName` to auto-resolve | Service Token |
| `create_api_token` | Create and activate an API token for the current MCP session | Service Token |
| `rotate_api_token` | Rotate an API token and activate the replacement for the session | Service Token |
API tokens are scoped to one data app. The MCP server can create or rotate them when `DATABRAIN_SERVICE_TOKEN` is configured, so users should not paste API tokens into chat. Use `list_tenants` to find authoritative `clientId` values before creating guest tokens or editing tenant-scoped dashboards.
***
## Embeds
6 tools for creating, configuring, previewing, and theming embedded dashboards.
| Tool | Description | Auth |
| ----------------------- | ------------------------------------------------------------------------------------------------- | --------- |
| `create_embed` | Create a standard embed or a multi-tenant dashboard embed with `clientId` | API Token |
| `list_embeds` | List embed configurations; use `list_tenants` for authoritative client discovery | API Token |
| `get_embed_details` | Get full embed configuration including access settings and theme | API Token |
| `update_embed` | Patch embed access settings, permissions, options, filters, localization, theme, or name | API Token |
| `customize_embed_theme` | Apply theme presets, colors, fonts, cards, chart appearance, responsive layout, or access presets | API Token |
| `get_demo_link` | Generate the hosted preview URL for a dashboard embed scoped to a `clientId` | API Token |
### Embed Creation Shape
For standard dashboard embeds, pass `dashboardId`, `workspaceName`, and `accessSettings: { datamartName }`.
For per-client dashboard embeds, also pass `clientId`. The tool fills required `isAllow*` access settings with secure defaults, so only pass the flags the user explicitly wants enabled.
### Theme and Advanced Config
Use `customize_embed_theme` for visual theming and access presets. Use `update_embed` for advanced embed changes such as filters, localization, permissions, or embed options.
### Demo Links
`get_demo_link` returns the same kind of hosted preview URL as the Databrain UI's "Share Demo Link" flow. It uses `DATABRAIN_DEMO_DOMAIN` when configured.
***
## Runtime Integration
2 tools for generating guest tokens and frontend integration code.
| Tool | Description | Auth |
| ---------------------- | -------------------------------------------------------------------------------- | --------------------- |
| `generate_guest_token` | Generate a server-side guest token for frontend embedding | API Token |
| `generate_embed_code` | Generate code for React, Next.js, Vue, Angular, Svelte, SolidJS, or vanilla HTML | No Databrain API call |
Guest tokens should be generated in your server-side application and passed to the frontend component. Never expose API tokens in browser code.
***
## Query & Semantic Layer
5 tools for natural language querying and data documentation.
| Tool | Description | Auth |
| -------------------------------------- | ---------------------------------------------------------------------------------- | ------------- |
| `ask_question` | Ask a natural language question; returns data, SQL reasoning, and chart suggestion | Service Token |
| `get_semantic_layer` | Inspect semantic layer metadata, synonyms, and completion score | Service Token |
| `update_semantic_layer` | Add or update table/column descriptions, synonyms, example questions, and context | Service Token |
| `start_semantic_layer_generation` | Start semantic-layer auto-generation for a datamart | Service Token |
| `get_semantic_layer_generation_status` | Poll the semantic-layer generation job status | Service Token |
`ask_question` requires a datamart and a populated semantic layer. If results are poor, inspect the semantic layer first and improve descriptions before re-running the question.
***
## Dashboards & Widgets
9 tools for dashboard discovery, workspace-level metrics, and customer-scoped widget management.
| Tool | Description | Auth |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| `list_dashboards` | List dashboards globally, by workspace, or by data app | Service Token / API Token |
| `list_widgets` | List widgets on a customer dashboard; returns `externalMetricId`, `metricId`, name, publish state, and creator | API Token |
| `validate_metric_spec` | Validate a SQL-backed metric target without saving it | API Token |
| `create_or_update_metric_from_query` | Dry-run or apply a SQL-backed metric create/update | API Token |
| `create_workspace_metric` | Dry-run or apply create-or-update of a workspace-level metric (unpublished/unattached by default). Pass an existing `metricId` to update in place and re-hydrate Dimensions/Measures from the new SQL | Service Token |
| `add_widget` | Add a widget by cloning a template widget, supplying a metric configuration, or using a generated draft | API Token |
| `update_widget` | Patch a widget by `externalMetricId` for one customer's dashboard | API Token |
| `remove_widget` | Soft-delete a widget for one `clientId` only | API Token |
| `generate_widget` | Generate a widget draft from a natural-language prompt; does not persist by itself | API Token |
### Customer-Scoped Widget Flow
For non-technical widget workflows, provide `clientId` and `dashboardName`; include `workspaceName` only if dashboard names are ambiguous. If you do not know the `clientId`, call `list_tenants` with the workspace first. The tools resolve data app, datasource, embed ID, and integration details automatically.
Use `externalMetricId` for `update_widget` and `remove_widget`. Do not use the user-facing `metricId` slug for those operations.
### SQL-to-Metric Safety
`create_or_update_metric_from_query` and `create_workspace_metric` default to `mode: "dry_run"`. Applying requires:
```json theme={"dark"}
{
"mode": "apply",
"confirm": "APPLY_TO_PRODUCTION"
}
```
Use `validate_metric_spec` first for dashboard-attached metric/widget changes, then dry-run, then apply only after the user reviews the plan. Use `create_workspace_metric` for internal (non-embed) workspace metrics — create by omitting `metricId`, or update by passing an existing `metricId` so the query and Dimensions/Measures are rewritten in place while publish/archived/draft state is preserved.
### `create_workspace_metric` Upsert Behavior
`create_workspace_metric` upserts on `metricId`:
* **Omit `metricId`** to create. The slug is derived from `name`, so re-running with the same name targets the same metric rather than creating a duplicate.
* **Pass an existing `metricId`** to update that metric in place. The new SQL is saved and Dimensions/Measures are re-derived from the query output columns so the metric editor stays populated.
* On update, archived/draft and publish state are preserved. The metric stays unattached to any dashboard unless you publish/attach it as a separate step.
***
## Scheduled Reports
| Tool | Description | Auth |
| ------------------------ | ----------------------------------------------------------------------- | --------- |
| `list_scheduled_reports` | List configured scheduled reports for a specific client/dashboard embed | API Token |
This tool returns schedule metadata such as subject, next scheduled time, recipient count, chart count, and download format.
***
## Tool Count
| Category | Count |
| ---------------------- | ------ |
| Session & Identity | 1 |
| Infrastructure | 6 |
| Data Apps & Tokens | 6 |
| Embeds | 6 |
| Runtime Integration | 2 |
| Query & Semantic Layer | 5 |
| Dashboards & Widgets | 9 |
| Scheduled Reports | 1 |
| **Total** | **36** |
# Troubleshooting
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/troubleshooting
Common issues and solutions for the Databrain MCP server
## Common Issues
**Cause:** Neither `DATABRAIN_SERVICE_TOKEN` nor `DATABRAIN_API_TOKEN` is set, or your MCP client is not reading the configured `env` block.
**Fix:**
1. Check that your token is in the `env` block of your MCP config.
2. Verify the token value has no extra spaces or quotes.
3. Restart your AI client after changing the config.
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "npx",
"args": ["@databrainhq/mcp-server"],
"env": {
"DATABRAIN_SERVICE_TOKEN": "your-actual-token-here"
}
}
}
}
```
If the token is set correctly and the error persists, regenerate it in **Settings -> Service Tokens** in the Databrain UI.
**Cause:** You configured only `DATABRAIN_API_TOKEN`. API tokens are scoped to one data app and cannot run org-level setup tools.
**Fix:** Add `DATABRAIN_SERVICE_TOKEN` when you need discovery, data app management, API token creation, semantic layer operations, or datamart setup.
API-token-only mode is still valid for embed operations, widget operations, guest tokens, demo links, and scheduled report metadata inside the configured data app.
**Cause:** No workspace was selected, the selected workspace has no dashboards, or the configured token is scoped too narrowly.
**Fix:** Ask the assistant:
> "List my workspaces and then show dashboards"
Dashboards are usually scoped to workspaces. If you see workspaces but no dashboards, verify that dashboards exist in the Databrain UI for that workspace.
**Cause:** Usually a token, ID, domain, or guest token payload mismatch.
**Fix:**
1. **Guest token generated server-side?** Never expose API tokens in frontend code.
2. **IDs match?** Verify the embed ID and dashboard ID.
3. **Domain whitelisted?** Check that your frontend's domain is allowed in the data app settings.
4. **Inspect the embed:** Ask the assistant:
> "Check my embed configuration for issues"
The assistant uses `get_embed_details` to inspect access settings, dashboard references, and token inputs.
**Cause:** Existing guest tokens may still carry old configuration.
**Fix:** After updating theme or options through `customize_embed_theme` or `update_embed`:
1. Regenerate the guest token with `generate_guest_token`.
2. Reload your application to use the new token.
Guest tokens are generated server-side and should be refreshed after configuration changes that affect runtime behavior.
**Cause:** The widget may be unpublished, the preview is using a stale guest token, or the wrong `clientId` was used.
**Fix:**
1. Ask the assistant to call `list_widgets` for the target `clientId` and dashboard.
2. Confirm the widget has `isPublished: true` if it should appear to end users.
3. Generate a fresh `get_demo_link` URL.
4. If testing inside your own app, regenerate the app's guest token.
**Cause:** Production writes require an explicit confirmation value.
**Fix:** Run the dry-run first, review the returned plan, then apply only after approval:
```json theme={"dark"}
{
"mode": "apply",
"confirm": "APPLY_TO_PRODUCTION"
}
```
This applies to `create_or_update_metric_from_query` and production datamart creation through `create_datamart`.
**Cause:** The semantic layer is empty, incomplete, or missing business context.
**Fix:** Check its status:
> "Check the semantic layer quality for my datamart"
If descriptions or synonyms are missing, ask:
> "Add descriptions and synonyms to improve query accuracy"
The assistant can update metadata with `update_semantic_layer` or start semantic-layer generation with `start_semantic_layer_generation`.
**Cause:** Usually a Node.js version issue or invalid environment variable.
**Fix:** The MCP server requires Node.js 18 or higher:
```bash theme={"dark"}
node --version
```
If you see a version below 18, update Node.js. Also verify `DATABRAIN_API_URL` and `DATABRAIN_DEMO_DOMAIN` are valid URLs when set.
**Cause:** npm/npx is not installed or the client cannot fetch the package.
**Fix:**
1. Ensure npm is installed: `npm --version`
2. Try running the package directly:
```bash theme={"dark"}
npx @databrainhq/mcp-server
```
3. If fetching the package hangs, install globally:
```bash theme={"dark"}
npm install -g @databrainhq/mcp-server
```
Then update your config to use the global binary:
```json theme={"dark"}
{
"mcpServers": {
"databrain": {
"command": "databrain-mcp-server",
"env": {
"DATABRAIN_SERVICE_TOKEN": ""
}
}
}
}
```
***
## Diagnostics
Ask your assistant:
> "Who am I authenticated as in Databrain?"
This calls `whoami` and confirms whether the session is using a service token or API token.
For embed issues, ask:
> "Check my embed configuration for issues"
The assistant uses `get_embed_details` to inspect access settings and dashboard references, then regenerates a guest token if runtime state changed.
For customer dashboard issues, ask:
> "List widgets for this client and give me a demo link"
The assistant uses `list_widgets` and `get_demo_link`.
***
## Known Limitations
| Area | Limitation | Workaround |
| --------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Datasource setup** | Datasources are connected in the Databrain UI | Create datasources in the Databrain UI, then use `list_datasources`, `discover_datasource_schema`, and `sync_datasource` |
| **Workspace setup** | Workspaces are created in the Databrain UI | Create workspaces in the Databrain UI, then use `list_workspaces` and dashboard workflows |
| **Transport** | stdio only; no HTTP/SSE transport yet | Use `npx` with your MCP client's config file |
| **Production writes** | Datamart and SQL-to-metric apply operations require explicit confirmation | Run dry-run first, review the plan, then apply with `confirm: "APPLY_TO_PRODUCTION"` |
| **Scheduled reports** | `list_scheduled_reports` returns configured schedule metadata | Use Databrain reporting views for delivery status |
***
## Getting Help
Start over with setup
Verify your client config
Review available tools
# Workflows
Source: https://docs.usedatabrain.com/developer-docs/mcp-server/workflows
Step-by-step guides for the most common MCP server use cases
The MCP server supports guided prompts that walk you through common tasks end-to-end. You can trigger these by asking naturally or by referencing the prompt name directly. Some use cases are direct tool workflows without a named prompt; you can still ask for them in natural language.
### Jump to a workflow
Most common starting point
Per-client dashboards
Find valid client IDs
Natural language to SQL
Better AI querying
Per-customer widget edits
Dry-run then apply metrics
Unattached metric drafts
Colors, fonts, layout
Self-serve, filters, i18n
Report metadata
***
## Embed an Existing Dashboard
The most common workflow. You have a dashboard built in the Databrain UI and want to embed it in your application.
**Ask your AI assistant:**
> "Embed my sales dashboard in my React app"
**What happens:**
The assistant calls `list_data_apps` and asks which data app to use when more than one exists.
It checks `list_api_tokens` and creates one with `create_api_token` if needed.
It calls `list_workspaces`, then `list_dashboards` scoped to the selected workspace.
It checks `list_embeds`, then calls `create_embed` with `dashboardId`, `workspaceName`, and `accessSettings: { datamartName }` if a new embed is needed.
It verifies with `get_embed_details`, generates a server-side guest token with `generate_guest_token`, and generates framework code with `generate_embed_code`.
**Prompt name:** `embed-existing-dashboard`
**What you get:** A working embed ID, a guest token payload pattern, and frontend code for React, Next.js, Vue, Angular, Svelte, SolidJS, or vanilla JS.
***
## Multi-Tenant / Per-Client Embeds
Each customer gets their own dashboard copy with a stable `clientId`.
**Ask your AI assistant:**
> "Create per-client dashboard embeds for my SaaS app"
**What happens:**
1. Lists data apps and ensures an API token exists.
2. Calls `list_tenants` to discover valid `clientId` values from the tenancy database.
3. Lists dashboards and asks which source or template dashboard to use.
4. Verifies the datamart and tenancy model.
5. Calls `create_embed` once per customer with `clientId`.
6. Generates guest tokens and frontend code.
**Prompt name:** `embed-blank-dashboard`
`clientId` must match between dashboard embed creation and guest token generation. For `create_embed`, pass only `accessSettings: { datamartName }` plus flags the user explicitly requests; the tool fills required access defaults.
***
## Discover Tenants / Client IDs
Find valid customer identifiers before creating guest tokens, customer dashboards, widgets, demo links, or scheduled-report views.
**Ask your AI assistant:**
> "List tenants for my Demo Workspace"
> "Find client IDs matching Acme before I edit a dashboard"
**What happens:**
The assistant uses `workspaceName` or `workspaceId`; if needed, it calls `list_workspaces` first.
It calls `list_tenants`, optionally with `searchValue`, `datasourceId`, `datamartId`, or `limit`.
It returns tenant labels and values so you can select the correct `clientId` for downstream embed, widget, guest-token, demo-link, or scheduled-report work.
**Prompt name:** Ask naturally. This is usually a preflight for multi-tenant embed, customer-widget, guest-token, demo-link, or scheduled-report workflows.
Prefer `list_tenants` when you need the authoritative customer list. `list_embeds` can show embed configuration, but tenant lookup comes from the workspace tenancy database.
***
## Query Data with Natural Language
Ask questions about your data and get answers with chart suggestions.
**Ask your AI assistant:**
> "What was total revenue last month?"
> "Show me the monthly revenue trend for the past year"
> "Compare sales by region, broken down by quarter"
**What happens:**
The assistant calls `list_datamarts` to see which data models are available.
It calls `get_semantic_layer` to verify table and column descriptions exist.
If descriptions are missing, it improves them with `update_semantic_layer` or starts semantic-layer generation with `start_semantic_layer_generation`.
It sends your question to `ask_question`, which converts it to SQL, executes the query, and returns results with a chart suggestion.
Follow-up questions use conversation context for better accuracy:
> "Now show only the top 5 regions"
**Prompt name:** `query-data`
***
## Populate the Semantic Layer
Bootstrap table and column descriptions to enable natural language querying.
**Ask your AI assistant:**
> "Check the semantic layer quality for my orders datamart and add descriptions"
**What happens:**
Calls `get_semantic_layer` to see the completion score and missing metadata.
Generates business-friendly table and column descriptions, synonyms, and example questions.
Writes metadata with `update_semantic_layer` or starts semantic-layer auto-generation with `start_semantic_layer_generation`.
Re-checks the semantic layer score and optionally tests a sample `ask_question`.
**Prompt name:** `populate-semantic-layer`
***
## Customize a Customer Dashboard
Add, remove, or modify widgets for one customer's dashboard without affecting the template or other customers.
**Ask your AI assistant:**
> "Add the Calls per Day widget to Acme's dashboard"
> "Remove the billing widget for this client only"
> "Generate a widget showing disqualification reasons and add it to a client's embed"
**What happens:**
The assistant asks for `clientId` and `dashboardName`; if you do not know the `clientId`, it calls `list_tenants`. It asks for `workspaceName` only if the dashboard name is ambiguous.
It calls `list_widgets` and presents widget names, publish state, `metricId`, and `externalMetricId`.
It calls `add_widget`, `generate_widget`, `update_widget`, or `remove_widget` depending on the requested change. Customer-scoped writes are blocked when the dashboard is not tenant-scoped for that `clientId`.
It calls `list_widgets` again, then `get_demo_link` so you can preview exactly what that `clientId` sees.
**Prompt name:** `customize-customer-dashboard`
`update_widget` and `remove_widget` require `externalMetricId`, which is returned by `list_widgets`. Do not use the user-facing `metricId` slug for those operations.
***
## SQL-to-Metric Migration
Turn warehouse-validated SQL into a Databrain metric/widget on a customer dashboard with a production-safe validation and apply flow.
**Ask your AI assistant:**
> "Validate this SQL as a new metric on my operations dashboard"
> "Dry-run creating this converted query as a metric, then show me the plan"
**What happens:**
Calls `list_workspaces`, `list_dashboards`, and `list_widgets` to confirm the target workspace, dashboard, client, and existing metric IDs.
Calls `validate_metric_spec` to resolve data app, datasource, embed ID, dashboard ID, and conflicts.
Calls `create_or_update_metric_from_query` with `mode: "dry_run"` and shows the exact plan.
Calls `create_or_update_metric_from_query` with `mode: "apply"` and `confirm: "APPLY_TO_PRODUCTION"` only after the user approves.
Calls `list_widgets` and `get_demo_link`.
**Prompt name:** `sql-to-metric-migration`
The workflow does not apply changes on the first pass. Applying requires the exact confirmation value `APPLY_TO_PRODUCTION`.
***
## Create an Unattached Workspace Metric
Create or update a workspace-level metric from validated SQL without attaching it to a dashboard. This is useful when you want to stage a metric as unpublished first, fix SQL on an existing workspace metric, or refresh Dimensions/Measures after a query change.
**Ask your AI assistant:**
> "Create an unpublished workspace metric from this validated SQL, but do not attach it to a dashboard"
> "Dry-run a workspace metric called Revenue by Region in my Analytics workspace"
> "Update the SQL on my existing workspace metric and refresh its Dimensions and Measures"
**What happens:**
The assistant confirms the target `workspaceName` and datasource context (via `list_workspaces` / `discover_datasource_schema`).
It calls `create_workspace_metric` with `mode: "dry_run"` to validate the name, SQL, optional `metricId`, datasource, and publish state without writing. When updating, the same `metricId` must be carried through dry-run and apply.
It shows the validation result and output columns. On create, the metric will be workspace-level, unpublished by default, and unattached. On update, the existing metric is rewritten in place and Dimensions/Measures are re-derived from the new SQL while publish/archived/draft state is preserved.
It calls `create_workspace_metric` with `mode: "apply"` and `confirm: "APPLY_TO_PRODUCTION"` only after you approve the write.
**Prompt name:** `sql-to-workspace-metric`. Use `sql-to-metric-migration` instead when the metric should become a customer-dashboard widget.
`create_workspace_metric` uses a service token, upserts on `metricId`, and does not publish or attach the metric by default. Applying requires the exact confirmation value `APPLY_TO_PRODUCTION`.
***
## Brand and Theme an Embed
Customize colors, fonts, chart styles, responsive breakpoints, cards, and access presets to match your product.
**Ask your AI assistant:**
> "Make my embed match our brand: primary color #4F46E5, dark mode, Inter font"
> "Apply the corporate theme preset and hide the dashboard name"
**What happens:**
1. Identifies the target embed via `list_embeds` or `get_embed_details`.
2. Applies theme changes through `customize_embed_theme`.
3. Uses `update_embed` for advanced patches such as UI options, filters, localization, or permissions.
4. Regenerates the guest token if the frontend needs the new configuration.
**Prompt name:** `brand-my-embed`
***
## Configure Embed Access, Filters, and Localization
Enable self-serve analytics, add filters, localize embed text, or tighten permissions after an embed already exists.
**Ask your AI assistant:**
> "Enable metric creation on my embed with the visual builder"
> "Add a date range filter and a region dropdown to my dashboard"
> "Set up French translations for my embed"
> "Lock down this embed so users can only view, not edit"
**What happens:**
The assistant calls `list_embeds` or `get_embed_details` to inspect the current access settings, filters, localization, and options.
It calls `update_embed` for access settings, filters, localization, permissions, and advanced embed options. For self-serve metric creation, it sets metric-creation access flags and the requested mode, such as `DRAG_DROP` or `CHAT`.
If frontend behavior depends on guest-token permissions or filters, it regenerates the guest token with `generate_guest_token`.
It re-checks the embed with `get_embed_details` and can generate a demo link with `get_demo_link` for a tenant-scoped dashboard.
**Prompt name:** Ask naturally. For purely visual changes, use `brand-my-embed`.
***
## Scheduled Reports Metadata
Review scheduled report configuration for a customer/dashboard scope.
**Ask your AI assistant:**
> "List scheduled reports for this client's dashboard"
**What happens:**
1. Resolves the dashboard by `dashboardName` and optional `workspaceName`, or by `embedId`.
2. Calls `list_scheduled_reports` with `clientId`.
3. Returns schedule metadata such as subject, next scheduled time, recipient count, chart count, and download format.
This workflow lists configured schedules only.
# Multi-Tenant Access Control
Source: https://docs.usedatabrain.com/developer-docs/multi-tenant-access-control
For your multi-tenant database architectures, establish atomic access controls through row-level policies (Database Tenancy & Table Tenancy), configurable in the Client Settings of our data source settings.
## How Our Row-Level Policies Work?
Set row-level policies for each table using your data source's SQL language.
DataBrain parses and applies these policies as Common Table Expressions (CTEs) during query generation. This step happens post-validation, just before sending the query to your database or warehouse.
This method ensures user-specific data access, e.g., User A sees only their data. You can also define and assign dynamic variables in your SQL queries during token creation.
## Guest Token
For a user to view the embedded DataBrain dashboard in your application, your backend must request a guest token from DataBrain. This request is specific to the user and utilizes their `userId` or `clientId`.
**Example request payload:**
```json theme={"dark"}
{
"clientId": "7807dcd1-1919-474b-aba7-7f23a062d02f"
}
```
These identifiers are then injected into your row-level policies, tailoring the data returned to the user based on these parameters.
## Example of Implementing a Row-Level Policy
To ensure each user only sees data relevant to them in a consumers table, you would set up a row-level policy and create a specific token. Here’s how you can do it:
### Step 1: Defining the Row-Level Policy for the Customers Table
Write a SQL query to define the policy:
```sql theme={"dark"}
SELECT * FROM consumers WHERE id = 'client_id_variable'
```
`client_id_variable` is written as a bare quoted token — no curly braces. At query time Databrain replaces it with the `clientId` from the guest token.
This query ensures that each user only accesses rows in the `consumers` table where their unique identifier matches the `id` column.
### Step 2: Generating a Token
Use a `curl` command to generate a token for a specific user:
```bash theme={"dark"}
curl -X POST --location 'https://api.usedatabrain.com/api/v2/guest-token/create' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data '{ "clientId": "7807dcd1-1919-474b-aba7-7f23a062d02f", "dataAppName": "your-data-app" }'
```
Both `clientId` and `dataAppName` are required on the v2 endpoint — the body is validated strictly. See the [Guest Token reference](/developer-docs/helpers/api-reference/token) for all optional fields.
This process combines secure access control with customized data visibility, aligning with user-specific requirements.
# 5-Minute Embedding Tutorial
Source: https://docs.usedatabrain.com/developer-docs/quick-start/embedding-tutorial
Get your first DataBrain dashboard embedded in 5 minutes
This tutorial will get you up and running with a working embedded dashboard in just 5 minutes. We'll use a sample token and dashboard so you can see results immediately.
## What You'll Build
By the end of this tutorial, you'll have:
* ✅ A working embedded DataBrain dashboard
* ✅ Understanding of the core embedding concepts
* ✅ A foundation to build upon for production
## Prerequisites
* Node.js 14+ installed
* A React, Vue, or vanilla JavaScript project
* 5 minutes of your time ⏱️
## Step 1: Install the Package
```bash npm theme={"dark"}
npm install @databrainhq/plugin
```
```bash yarn theme={"dark"}
yarn add @databrainhq/plugin
```
```bash pnpm theme={"dark"}
pnpm add @databrainhq/plugin
```
## Step 2: Import the Plugin
Add this import to your component or main file:
```javascript React theme={"dark"}
import '@databrainhq/plugin/web';
function Dashboard() {
return (
);
}
export default Dashboard;
```
```javascript Vue theme={"dark"}
```
```javascript Vanilla JS theme={"dark"}
import '@databrainhq/plugin/web';
// In your HTML
document.body.innerHTML = `
`;
```
```html HTML theme={"dark"}
```
## Step 3: Run and View
Start your development server and you should see the sample dashboard! 🎉
```bash theme={"dark"}
npm run dev
# or
npm start
```
**Congratulations!** You've embedded your first DataBrain dashboard. The dashboard you're seeing is a sample with demo data.
## Understanding What You Built
Let's break down the code:
### The Component
```html theme={"dark"}
```
### The Token
```
token="3affda8b-7bd4-4a88-9687-105a94cfffab"
```
This is a **guest token** - a temporary access token that allows viewing the dashboard. In production, you'll generate these from your backend.
### The Dashboard ID
```
dashboard-id="ex-demo"
```
This identifies which dashboard to display. Each dashboard in DataBrain has a unique ID.
## Next: Make It Production-Ready
The sample above works great for testing, but for production you need to:
### 1. Create Your Own Dashboard
1. **Create your own dashboard** at [app.usedatabrain.com](https://app.usedatabrain.com/users/sign-up)
2. **Connect your database** as a data source
3. **Build your metrics and dashboards**
4. **Create a Data App** for embedding
5. **Generate tokens from your backend** (see below)
Follow the full setup process
### 2. Generate Tokens from Your Backend
**Security First:** Never expose your API token in frontend code. Always generate guest tokens from your backend.
Here's how token generation works:
**Token Flow:**
```
1. User accesses dashboard
↓
2. Frontend → Backend (request guest token)
↓
3. Backend → DataBrain API (POST /guest-token/create)
↓
4. DataBrain API → Backend (return guest token)
↓
5. Backend → Frontend (return guest token)
↓
6. Frontend → Dashboard component (render with token)
```
#### Backend Example (Node.js)
```javascript theme={"dark"}
// backend/api/get-token.js
import fetch from 'node-fetch';
export async function getGuestToken(userId) {
const response = await fetch(
'https://api.usedatabrain.com/api/v2/guest-token/create',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DATABRAIN_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
clientId: userId,
dataAppName: 'your-data-app-name'
})
}
);
const data = await response.json();
return data.token;
}
```
#### Frontend Example (React)
```javascript theme={"dark"}
import { useEffect, useState } from 'react';
import '@databrainhq/plugin/web';
function Dashboard({ userId }) {
const [token, setToken] = useState(null);
useEffect(() => {
// Fetch token from YOUR backend
fetch('/api/get-databrain-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId })
})
.then(res => res.json())
.then(data => setToken(data.token));
}, [userId]);
if (!token) return
Loading...
;
return (
);
}
```
Complete token generation API docs
### 3. Customize the Dashboard
Add options to customize appearance and behavior:
```html theme={"dark"}
```
Explore all customization options
## Embed a Single Metric
You can also embed individual metrics instead of full dashboards:
```html theme={"dark"}
```
## Common Customizations
```html theme={"dark"}
```
```html theme={"dark"}
```
```javascript theme={"dark"}
const theme = {
general: {
primaryColor: '#FF6B6B',
backgroundColor: '#F8F9FA',
fontFamily: 'Inter'
},
chart: {
colors: ['#FF6B6B', '#4ECDC4', '#45B7D1']
}
};
```
```javascript theme={"dark"}
// Define global handler
window.handleDashboardEvent = (event) => {
console.log('Dashboard event:', event);
};
```
## Framework-Specific Guides
Get detailed integration guides for your framework:
React integration guide
Next.js with SSR support
Vue 3 integration
Angular setup guide
Svelte integration
Plain JavaScript
## Troubleshooting
**Check:**
* Plugin is imported before component renders
* Token is valid and not expired
* Dashboard ID is correct
* No console errors
**Solution:** Generate a fresh token from your backend. Guest tokens can be set to expire after a certain time.
**Fix:** Ensure your domain is whitelisted in the Data App settings. Or generate tokens from your backend instead of frontend.
**Try:**
* Check for CSS conflicts
* Use custom theme options
* Wrap in a container div
* Check z-index values
Complete troubleshooting reference
## What's Next?
You've successfully embedded a DataBrain dashboard! Here's what to explore next:
Production-ready setup guide
Multi-tenancy and access control
Advanced customization options
Complete API documentation
## Need Help?
Experiment with live examples
Get help from our team
# Rate Limiting Configuration
Source: https://docs.usedatabrain.com/developer-docs/rate-limiting
Configure API rate limits for your self-hosted DataBrain deployment to balance security and performance
DataBrain includes built-in rate limiting to protect your API against abuse, brute-force attacks, and accidental traffic spikes. In a self-hosted deployment, you have full control over these limits through environment variables.
Rate limiting is **enabled by default** on all routes. No configuration is required for basic protection, but tuning the values for your specific traffic patterns is recommended.
***
## How It Works
* Every incoming API request is tracked by the **client's IP address**.
* Each rate limiter defines a **time window** and a **maximum number of requests** allowed within that window.
* If a client exceeds the limit, they receive a `429 Too Many Requests` response until the window resets.
* Standard rate limit headers are included in API responses so clients can monitor their remaining quota.
If DataBrain runs behind a reverse proxy or load balancer (NGINX, AWS ALB, Cloudflare, etc.), make sure the proxy forwards the real client IP. DataBrain checks the `X-Client-IP` header first and falls back to the standard `X-Forwarded-For` header (via Express's built-in trusted proxy support) to identify individual clients. Without proper proxy configuration, all traffic may appear to come from a single IP and get rate-limited together.
***
## Environment Variables
Set these in your `.env` file for the DataBrain API service (Express backend). All values represent the **maximum number of requests per client IP** within the given time window.
### General API Rate Limit
Maximum requests per IP across **all API endpoints** within a **2-minute** window.
This is the global rate limiter — it applies to every request before any route-specific limits are checked.
**Important:** You should always explicitly set this variable in your `.env` file. If left unset, the rate limiter may not enforce the intended default of 500 requests.
### Authentication Rate Limits
These protect login and identity-related endpoints against brute-force and credential-stuffing attacks.
Maximum requests per IP to **authentication endpoints** within a **1-minute** window.
Covers: sign-in, sign-up, SSO, password reset, invitation acceptance, and related auth flows.
Maximum requests per IP to the **token refresh endpoint** within a **1-minute** window.
Controls how frequently a client can request new access tokens.
Maximum requests per IP to **OTP (one-time password) endpoints** within a **1-minute** window.
Covers OTP generation and verification.
### Other Rate Limits
Maximum requests per IP to **email-sending endpoints** within a **1-minute** window.
Covers invitation emails, verification re-sends, and scheduled report triggers.
Maximum requests per IP to the **demo database onboarding endpoint** within a **1-minute** window.
Only relevant if you use the built-in demo database onboarding flow.
***
## Quick Reference
| Variable | Default | Window | Protects |
| ------------------------------------- | ------- | ------ | ----------------------------------- |
| `RATE_LIMIT` | 500 | 2 min | All API routes (global) |
| `AUTH_ROUTE_RATE_LIMIT` | 30 | 1 min | Login, sign-up, SSO, password reset |
| `REFRESH_ROUTE_RATE_LIMIT` | 30 | 1 min | Token refresh |
| `OTP_RATE_LIMIT` | 50 | 1 min | OTP generation and verification |
| `EMAIL_RATE_LIMIT` | 50 | 1 min | Invitation and verification emails |
| `ONBOARDING_DEMO_DATABASE_RATE_LIMIT` | 50 | 1 min | Demo database onboarding |
Route-specific limits (auth, OTP, email) are applied **in addition to** the global limit. A request to a login endpoint must pass both the global `RATE_LIMIT` check and the `AUTH_ROUTE_RATE_LIMIT` check.
***
## Configuration Example
Add these to your DataBrain API `.env` file:
```bash theme={"dark"}
# --- Rate Limiting ---
# Global: max requests per IP across all endpoints (2-minute window)
RATE_LIMIT=500
# Auth routes: sign-in, sign-up, SSO, password reset (1-minute window)
AUTH_ROUTE_RATE_LIMIT=30
# Token refresh endpoint (1-minute window)
REFRESH_ROUTE_RATE_LIMIT=30
# OTP generation and verification (1-minute window)
OTP_RATE_LIMIT=50
# Email sending: invitations, verification (1-minute window)
EMAIL_RATE_LIMIT=50
# Demo database onboarding (1-minute window)
ONBOARDING_DEMO_DATABASE_RATE_LIMIT=50
```
After updating, restart the DataBrain API service for changes to take effect.
***
## Tuning for Your Deployment
The default values are a good starting point for most deployments. Here's how to think about adjusting them:
If you have a **small user base** (under \~100 users) and want tighter security, you can reduce limits — for example, halving `RATE_LIMIT` to `250` or lowering `AUTH_ROUTE_RATE_LIMIT` to `15`. Fewer legitimate users means fewer requests per IP, so tighter limits are less likely to cause false positives.
Increase limits if you see legitimate requests getting `429` errors. Common scenarios:
* **High-traffic embedded dashboards** — Many end users loading dashboards simultaneously can generate significant API traffic. Increase `RATE_LIMIT` as needed (e.g., to `1000` or higher).
* **Shared IP / corporate NAT** — If many users share one public IP (offices, VPNs), they collectively consume one IP's quota. Raise `RATE_LIMIT` proportionally.
* **Automated workflows** — CI/CD pipelines, bulk token generation, or automated testing can trigger auth limits. Raise `AUTH_ROUTE_RATE_LIMIT` or `REFRESH_ROUTE_RATE_LIMIT` for those environments.
1. **Start with the defaults** — they work well for most medium-sized deployments.
2. **Monitor 429 responses** in your logs or monitoring stack.
3. **Increase incrementally** if legitimate traffic is being blocked — double the value and observe.
4. **Avoid setting limits excessively high** — very high limits (e.g., `RATE_LIMIT=100000`) effectively disable rate limiting and remove protection against abuse.
***
## What Happens When a Limit Is Hit
When a client exceeds a rate limit:
1. The API responds with HTTP status **`429 Too Many Requests`**.
2. The response body contains a descriptive error message (e.g., *"Too many requests, please try again later"*).
3. The client should wait until the current window expires before retrying.
Responses include standard rate limit headers that clients can use to manage their request pace:
* **`RateLimit`** — Combined header showing the current limit, remaining requests, and reset time (e.g., `limit=500, remaining=498, reset=120`)
* **`RateLimit-Policy`** — Describes the rate limit policy in effect
* **`Retry-After`** — Seconds to wait before retrying (included on 429 responses)
If your backend integration receives a `429` response:
1. Read the `Retry-After` header to know when to retry.
2. Implement **exponential backoff** — wait 1s, then 2s, then 4s, etc.
3. Do not retry immediately in a tight loop — failed requests still count against the limit, so rapid retries will consume the next window's quota as soon as it resets.
4. Guest tokens are reusable — consider caching them on your backend rather than generating a new one for every page load. Refresh before the token's `expiryTime` to avoid `401` errors.
***
## Best Practices
We strongly recommend explicitly setting the `RATE_LIMIT` variable in your `.env` file rather than relying on the default. This ensures predictable behavior and makes your configuration self-documenting.
Rate limiting is based on client IP. If DataBrain sits behind NGINX, a cloud load balancer, or Cloudflare, ensure the proxy forwards the original client IP. DataBrain checks the `X-Client-IP` header first, then falls back to `X-Forwarded-For` (via Express trusted proxy support). Either header works — just make sure at least one is set.
Without this, all requests appear to come from the proxy's IP, causing legitimate users to be rate-limited together.
Guest tokens are reusable — once created, the same token can authenticate multiple requests until it expires. Instead of calling the guest token API on every page load, cache the token on your backend and reuse it for the same user and parameter combination.
If you set an `expiryTime`, make sure to refresh the token **before** it expires. Expired tokens are periodically cleaned up and will return a `401` error once removed.
Authentication endpoints are the most targeted by brute-force attacks. Keep `AUTH_ROUTE_RATE_LIMIT` and `OTP_RATE_LIMIT` conservative (30–50 per minute) unless you have a specific reason to increase them.
Track 429 responses in your monitoring stack (DataDog, Grafana, etc.). A spike in 429s may indicate either an attack (good — the rate limiter is protecting you) or limits that are too tight for your traffic (adjust accordingly).
***
## Troubleshooting
**Cause:** The reverse proxy is not forwarding the real client IP.
**Fix:** Configure your proxy to forward the real client IP. DataBrain checks `X-Client-IP` first, then `X-Forwarded-For`. For NGINX, add:
```
proxy_set_header X-Forwarded-For $remote_addr;
```
For AWS ALB or Cloudflare, `X-Forwarded-For` is typically set automatically, but verify the header is reaching DataBrain.
**Cause:** High-traffic pages generating too many API calls per IP.
**Fix:**
* Increase `RATE_LIMIT` to accommodate your peak traffic.
* Cache guest tokens on your backend to reduce token-creation calls.
* Ensure dashboards use caching (Workspace Settings → Cache Settings) to reduce repeated data queries.
**Cause:** Auth rate limit exceeded, possibly from automated tests or repeated failed logins.
**Fix:** Wait 1 minute for the window to reset. If this happens regularly for legitimate users, consider increasing `AUTH_ROUTE_RATE_LIMIT` slightly (e.g., from 30 to 50).
***
## Related Documentation
Full overview of DataBrain security features
Embedding configuration for self-hosted deployments
Common issues and solutions for embedded dashboards
Generate secure tokens for embedding
# Error Codes Reference
Source: https://docs.usedatabrain.com/developer-docs/reference/error-codes
Every error string DataBrain can return — embed runtime errors, metric execution errors (E1001–E1007), and guest-token API errors — with cause and fix.
Use this page to look up any error string you see in an embed, the metric builder, or a guest-token API response.
## Embed runtime errors
These surface when an embedded dashboard or metric loads. Guest tokens are **database-backed UUIDs, not signed JWTs** — there is no signing key, so none of these errors are about signatures.
| Error | Meaning | Fix |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_TOKEN` | The token UUID was **not found** in the deployment being queried | Check for a cloud vs self-hosted mismatch (a token exists only in the environment that minted it); confirm the embed receives the exact minted value; mint a fresh token |
| `TOKEN_EXPIRED` | The token exists but its `expiryTime` has passed | Mint a fresh token; refresh cached tokens before the deadline. Tokens without `expiryTime` never expire |
| `UNAUTHORIZED_ORIGIN` | The page's origin is not on the Whitelist Domains list | Add the origin (scheme-less `host[:port]`, wildcards like `*.example.com` supported) under your Data App's settings → **Whitelist Domains**. Whitelist *your* domain, not `api.usedatabrain.com`. The list is account-wide |
| `UNAUTHORIZED` | The token is not allowed this request. On dashboard load: the ID isn't in the token's `params.allowedEmbeds`, or the dashboard doesn't belong to the token's Data App/workspace. On dashboard-filter, metric-filter, dashboard-view, or filter-alias requests: that capability isn't granted | For load errors: fix `allowedEmbeds` or the ID. For filter/view errors: enable the matching Data App access setting or grant it in the token (`params.accessPermissions.isAllowEndUserDashboardFilter`, `isAllowEndUserMetricFilter`, `isAllowDashboardFilterNameChange`, or `isAllowMetricFilterNameChange`; dashboard views use `permissions.isEnableCreateDashboardView`) |
| `INVALID_ID` | The dashboard/embed ID does not belong to the token's Data App | Verify the ID and that the token was minted for the right Data App |
| `UNAUTHORISED REQUEST!` | The request is missing a valid plugin token header | Ensure the embed component receives a `token` attribute |
## Metric execution errors (E1001–E1007)
| Code | Message | Cause & fix |
| ------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `E1001` | `Filter or Client variables detected in the query.` | The final SQL still contains an unresolved `{{…}}` token at execution. Causes: variable name doesn't match the filter's variable name (case-sensitive); the filter has no value or default; no matching filter is attached. Fix the name and give the filter a default value. See [Filter Troubleshooting](/guides/dashboards/filter-troubleshooting) |
| `E1002` | `Metric data or query could not be found.` | The metric's stored query is missing — re-save the metric |
| `E1003` | `Drill-down query execution failed.` | The drill-down query errored — check the underlying SQL |
| `E1004` | `Invalid query or insufficient permissions to access it.` | The query failed validation or the caller lacks access |
| `E1005` | `An error occurred while fetching data from the database.` | The data source returned an error — test the connection and run the SQL directly against the source |
| `E1006` | `Forecast query execution failed.` | The forecast service errored on this metric |
| `E1007` | `Hasura server error occurred while processing the request.` | Internal metadata-layer error — on self-hosted check the hasura service; on cloud contact support |
Multi-select filter variables substitute as a parenthesized quoted list (e.g. `( 'US' , 'CA' )`). Write `WHERE col IN {{var}}` **without** your own parentheses — `IN ({{var}})` double-wraps into invalid SQL.
## Guest-token API errors (mint time)
Returned by `POST /api/v2/guest-token/create`. See the [Guest Token reference](/developer-docs/helpers/api-reference/token) for the accepted payload.
| Code | Meaning |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUTHENTICATION_ERROR` | Invalid or missing API key in the `Authorization` header |
| `INVALID_REQUEST_BODY` | The body failed validation — includes any **unknown field** (`dataAppId`, `client_id`, `tenant_id`, `permissions.dashboards` are not valid fields) |
| `INVALID_DATA_APP_NAME` | `dataAppName` doesn't match any Data App (case-sensitive) |
| `CLIENT_ID_ERROR` | Invalid `clientId` value |
| `WORKSPACE_ID_ERROR` | Workspace not found or inaccessible |
| `DASHBOARD_PARAM_ERROR` / `EMBED_PARAM_ERROR` | Invalid dashboard/embed parameters |
| `APP_FILTER_PARAM_ERROR` | Invalid `params.appFilters` shape |
| `RLS_SETTINGS_PARAM_ERROR` | Invalid `params.rlsSettings` shape |
| `DATASOURCE_NAME_ERROR` / `DATAMART_NAME_ERROR` | `datasourceName` / `datamartName` doesn't resolve |
| `UNSUBSCRIBED_ACCOUNT_ERROR` | The account's subscription doesn't allow this operation |
| `INTERNAL_SERVER_ERROR` | Server-side failure — retry, then contact support |
## Browser-side errors
### `QuotaExceededError … 'metric-data' exceeded the quota`
The embed plugin caches metric data in `localStorage`, and a large metric blew past the browser's per-origin quota (\~5–10 MB).
1. Clear the key: `window.localStorage.removeItem('metric-data')` and reload.
2. Reduce the row/column count of the offending metric (`LIMIT`, pagination, or split it).
This is a browser storage limit — it is unrelated to API rate limits, and the self-hosted `RATE_LIMIT` env var has no effect on it.
## Rate limiting (HTTP 429)
Cloud API requests are throttled per Data App. Back off using the `Retry-After` header and cache read-heavy calls. See [Rate Limiting](/developer-docs/rate-limiting).
# Security & Compliance
Source: https://docs.usedatabrain.com/developer-docs/security
How DataBrain keeps your data secure and helps you meet compliance requirements
**At a Glance:** DataBrain uses bank-level AES-256 encryption, supports enterprise SSO and MFA, provides fine-grained access controls, and maintains SOC 2 Type II, ISO 27001, GDPR, and HIPAA compliance.
DataBrain implements comprehensive security measures across every layer to protect your data, users, and platform. Security is built into our DNA so you can focus on building great analytics with confidence.
For detailed security information, visit our [Security page](https://www.usedatabrain.com/security).
***
## Compliance & Certifications
DataBrain Cloud is certified and compliant with major security and privacy standards:
**Self-Hosted Deployments:** Compliance depends on your infrastructure configuration. DataBrain provides all the security features and controls needed to achieve these compliance standards.
**Related Resources:**
* [Security Overview](https://www.usedatabrain.com/security)
* [Privacy Policy](https://www.usedatabrain.com/privacy)
* [Cookie Policy](https://www.usedatabrain.com/cookie-policy)
***
## Data Protection
### Encryption - Bank-Level Security
**Industry Standard:** We use the same AES-256 encryption used by banks and government agencies to protect your data.
**Everything is encrypted when stored:**
* User credentials and passwords (hashed and salted)
* Database connection strings and credentials
* API keys and authentication tokens
* Dashboard and metric configurations
* Audit logs and activity records
Your data is encrypted on disk, in backups, and in our databases. Even if storage media is compromised, data remains protected.
**All communications are encrypted:**
* Login and authentication requests
* Dashboard and metric data transfers
* API requests and responses
* File uploads and downloads
* WebSocket connections for real-time updates
We enforce HTTPS for all connections and use TLS 1.2 or higher with strong cipher suites.
**Your passwords are never stored in plain text:**
* One-way hashing using industry-standard algorithms
* Unique salt per password (even identical passwords have different hashes)
* Cannot be decrypted by anyone, including DataBrain staff
* Password resets create new passwords rather than retrieving old ones
This means your password is secure even if our database is compromised.
### Database Connection Security
**All database connections are encrypted:**
* PostgreSQL, MySQL, SQL Server with SSL/TLS
* Snowflake and BigQuery (encrypted by default)
* Redshift, Databricks, and all supported databases
DataBrain automatically uses encrypted connections when available.
**For maximum security on AWS:**
* Direct private connection to your VPC
* No public internet exposure required
* Network-level isolation
* Lower latency, higher security
Your database doesn't need a public IP address with VPC peering.
**Best practice for analytics:**
* DataBrain only needs SELECT permissions
* No risk of data modification
* Access limited to specific schemas/tables
* Easy to audit and revoke if needed
Create a dedicated read-only database user for DataBrain.
### Multi-Tenant Data Isolation
Complete data separation for SaaS applications and multi-client environments:
Users see only their authorized data
Applied automatically to all queries
Complete separation by client ID
**In a SaaS application:**
1. Generate guest token with unique client ID
2. DataBrain automatically filters all data by that client
3. Client A sees only Client A's data
4. Client B sees only Client B's data
5. Zero cross-client data access - complete isolation
**No code changes required** - filtering happens automatically at the database level.
**Fine-grained data access control:**
* Filter data based on user attributes (role, department, region, etc.)
* Applied automatically to all queries
* Transparent to end users
* Centrally managed and configured
Perfect for hierarchical access (managers see team data, directors see department data, etc.)
***
## User Authentication
Choose the authentication method that fits your security requirements:
Traditional authentication with strong password policies and account protection
Enterprise SSO with SAML, OIDC, Google Workspace, and Microsoft 365
Passwordless authentication via secure email codes
Additional security layer with authenticator apps, SMS, or email
### Single Sign-On (SSO)
Connect DataBrain with your existing identity provider for centralized user management:
**Enterprise Identity Providers:**
* Okta
* Azure Active Directory
* OneLogin
* Auth0
* Any SAML 2.0 compliant provider
Perfect for large organizations with existing identity infrastructure.
**Modern OAuth 2.0 Providers:**
* Keycloak
* Google Workspace
* Microsoft Identity Platform
* Any OpenID Connect provider
Simpler setup with JSON-based token format and better mobile support.
**One-Click Sign-In:**
* Google Workspace integration
* Microsoft 365 connectivity
* Azure AD support
* Automatic user provisioning
Quick setup with popular enterprise platforms.
### Multi-Factor Authentication (MFA)
**Highly Recommended:** Enable MFA for all administrator accounts. MFA blocks 99.9% of automated attacks.
**Time-based one-time passwords (TOTP):**
* Google Authenticator
* Microsoft Authenticator
* Authy
* Any TOTP-compatible app
Works offline and can't be intercepted. **This is the most secure option.**
**Receive verification codes via text:**
* Works on any mobile phone
* No app installation required
* Good for occasional use
More convenient but less secure than authenticator apps.
**Get verification codes via email:**
* No additional device required
* Good for backup method
* Delivered to your registered email
Convenient option for secondary authentication.
### Session Management
Automatic session security keeps your account protected:
Sessions automatically refresh while you're active - no interruptions to your work.
Automatic logout after 30 minutes of inactivity protects your account on shared devices.
Stay logged in on trusted devices for up to 7 days (optional feature).
**Important:** Don't use "Remember Me" on public or shared computers.
View and manage active sessions across all your devices. Remotely log out from any device.
***
## Access Control & Permissions
DataBrain uses role-based access control (RBAC) to ensure users have appropriate access:
**Principle of Least Privilege:** Always grant the minimum permissions needed. Start with Viewer role and escalate only when necessary.
### User Roles
**Perfect for:** Stakeholders, executives, business users
**Can Do:**
* View dashboards and metrics
* Filter and explore data
* Download reports and exports
* Apply dashboard filters
**Cannot Do:**
* Create or edit content
* Modify configurations
* Manage users or settings
Use this role for users who only need to view and analyze data.
**Perfect for:** Data analysts, business analysts, content creators
**Can Do:**
* Everything Viewers can do, plus:
* Create dashboards and metrics
* Edit existing content
* Configure visualizations
* Write custom SQL queries
* Share dashboards with teams
**Cannot Do:**
* Manage users or roles
* Configure data sources
* Access admin settings
Use this role for users who create and maintain analytics content.
**Perfect for:** IT administrators, security teams, platform managers
**Can Do:**
* Everything Editors can do, plus:
* Manage users and assign roles
* Configure data sources
* Generate and manage API tokens
* Configure SSO and security settings
* Access audit logs
* Set company-wide policies
Use this role sparingly - only for users who need full platform control.
### Custom Roles
Create custom roles for specific use cases:
* **Department-specific access** - "Sales Analyst" role with sales dashboard access only
* **Client-facing roles** - Limited viewer with export restrictions
* **Temporary project access** - Time-limited elevated permissions
* **Specialized workflows** - Custom permission combinations
Document each custom role's purpose and regularly review assignments.
**Follow these guidelines:**
* Start with standard roles (Viewer, Editor, Admin)
* Grant minimum necessary permissions
* Review permissions quarterly
* Remove inactive accounts after 30 days
* Document custom role purposes
* Test permission changes before deployment
***
## Token Management
DataBrain uses secure tokens for API access and embedded analytics:
**For Backend Integration**
* Long-lived tokens for server applications
* Scoped permissions (read, write, admin)
* Production and test environments
* Can be revoked instantly
**For Embedded Dashboards**
* Short-lived tokens for end users
* Automatic client data filtering
* Domain whitelisting
* Usage tracking and analytics
### API Tokens
**Security Critical:** Never expose API tokens in frontend code, GitHub, or client-side applications. Always generate tokens on your backend server.
**Step-by-step process:**
1. Navigate to **Data Apps** → Select your app
2. Click **Generate API Token**
3. Set descriptive name (e.g., "Production Dashboard API")
4. Choose scopes (read, write, delete)
5. Set expiration date (recommended: 1 year)
6. **Copy token immediately** - it won't be shown again!
7. Store securely in password manager or secrets vault
Use descriptive names like `prod-dashboard-2024` to track token purposes.
**Grant only necessary permissions:**
* **Read** - View dashboards and metrics (for embedding)
* **Write** - Create and modify content (for integrations)
* **Delete** - Remove resources (use sparingly)
* **Admin** - Full access (only for administrative tools)
Most embedding scenarios only need read permissions.
**Keep your tokens secure:**
* Store tokens in environment variables
* Use separate tokens for dev/staging/production
* Rotate tokens every 6 months
* Revoke unused tokens immediately
* Monitor token usage for anomalies
* Never commit tokens to version control
If a token is compromised, revoke it immediately and generate a new one.
### Guest Tokens
For secure embedded analytics in customer-facing applications:
**Built-in protection:**
* **Domain Whitelisting** - Only works on approved domains
* **Client Filtering** - Automatic data filtering by client ID
* **Expiration Control** - Set time limits (recommended: 1 year with auto-renewal)
* **Usage Tracking** - Monitor access for billing and security
These features ensure each customer sees only their data.
**Where to use guest tokens:**
* Customer portals with personalized dashboards
* Partner dashboards with specific metrics
* Mobile app analytics integrations
* Public reports on websites
* Embedded analytics in SaaS applications
Generate guest tokens on your backend, not in frontend JavaScript.
**Restrict where dashboards can be embedded:**
* Whitelist entries are **scheme-less** `host[:port]` — do not include `http://` or `https://` (the API rejects entries with a protocol)
* Specify exact domains: `app.yourcompany.com`
* Support subdomains: `*.yourcompany.com` (use carefully)
* Include the port for local dev: `localhost:3000`
* Never use wildcard `*` for all domains
* Serve your embedding pages over HTTPS in production (the scheme just isn't part of the whitelist entry)
The whitelist is stored account-wide — one list covers all your Data Apps. Even if someone steals your guest token, they can't use it on unauthorized domains.
***
## Platform Security
### API Protection
Every API request is secured with multiple protection layers:
All requests must be authenticated with valid tokens
TLS 1.2+ encryption enforced for all connections
Automatic protection against abuse and DDoS
**Industry-standard HTTP security headers applied to all responses:**
* **Strict-Transport-Security** - Forces HTTPS connections
* **X-Frame-Options** - Prevents clickjacking attacks
* **X-Content-Type-Options** - Prevents MIME type sniffing
* **Content-Security-Policy** - Controls resource loading
* **X-XSS-Protection** - Enables browser XSS filters
These headers provide defense-in-depth protection against common web vulnerabilities.
**Protects against abuse and ensures fair usage:**
| Request Type | Time Window | Limit |
| ------------------------ | ----------- | ------------ |
| **Login/Authentication** | 1 minute | 30 requests |
| **General API Calls** | 2 minutes | 500 requests |
| **Data Queries** | 2 minutes | 500 requests |
Need higher limits for your use case? Contact support to discuss custom rate limits.
**Complete visibility into system activity:**
**What's logged:**
* User login/logout events
* Permission changes
* Data access patterns
* API token usage
* Configuration changes
* Failed authentication attempts
**Benefits:**
* Security monitoring and threat detection
* Compliance and audit requirements
* Troubleshooting and debugging
* Usage analytics
Only administrators can access audit logs via Settings → Audit Logs.
***
## Embedded Analytics Security
Secure your embedded dashboards with built-in protection:
### Domain Whitelisting
**Critical Security Control:** Always restrict which domains can embed your dashboards. Never use wildcard `*` for all domains.
**How to configure:**
1. Specify exact allowed domains in guest token settings
2. Use HTTPS only (never HTTP in production)
3. Be specific - avoid broad wildcards when possible
**Examples:**
* **Good:** `https://app.yourcompany.com`
* **Good:** `https://dashboard.yourcompany.com`
* **Use carefully:** `https://*.yourcompany.com` (all subdomains)
* **Never:** `*` (all domains)
Test your configuration: Approved domains should load dashboards, unauthorized domains should be blocked.
### Client Data Isolation
Automatic data separation for multi-tenant applications:
**Complete data isolation in 4 simple steps:**
1. **Generate guest token** with unique client ID on your backend
2. **Embed dashboard** in your application with that token
3. **DataBrain filters** all data automatically by client ID
4. **Client sees only their data** - zero cross-client access
Zero configuration needed - filtering happens automatically at the database level.
**Why automatic client filtering matters:**
* No manual filtering code needed
* Impossible to bypass (enforced at database level)
* Works across all queries automatically
* Scales to thousands of clients
* Complete data isolation guaranteed
Perfect for SaaS applications where each customer needs isolated data.
***
## Self-Hosted Security
Additional security measures for self-hosted deployments:
**Your Responsibility:** For self-hosted installations, you're responsible for infrastructure security. Follow these best practices to maintain a secure deployment.
**Secure your server infrastructure:**
* Keep OS and software updated with latest security patches
* Configure firewall rules (allow only necessary ports)
* Disable unnecessary services and features
* Use SSH key authentication (disable password auth)
* Implement fail2ban to block brute force attempts
* Set up automatic security updates
* Use strong, unique passwords for all accounts
Run security audits quarterly to identify vulnerabilities.
**Enforce encrypted connections:**
* Use valid certificates from trusted CA (Let's Encrypt is free)
* Enable automatic certificate renewal
* Support TLS 1.2 or higher only
* Disable weak cipher suites
* Enable HSTS header
* Test SSL configuration regularly
Never use self-signed certificates in production.
**Protect your database:**
* Use strong, unique passwords (20+ characters)
* Enable SSL/TLS for all connections
* Limit network access (whitelist IPs only)
* Use read-only credentials for DataBrain
* Encrypt data at rest
* Set up automated daily backups
* Test backup restoration monthly
Store database backups in a separate location from primary database.
**Stay informed about security events:**
**System Monitoring:**
* CPU, memory, and disk usage
* Network traffic patterns
* Application error rates
* Service health checks
**Security Monitoring:**
* Failed login attempts
* Unusual access patterns
* Configuration changes
* Certificate expiration
Set up email/SMS alerts for critical events.
**Implement reliable backups:**
**What to backup:**
* Database (all data)
* Application files and configurations
* User uploads and assets
* SSL certificates
**Backup schedule:**
* Full backup: Weekly
* Incremental: Daily
* Test restores: Monthly
**Storage:**
* Encrypt all backups
* Store off-site (different location/region)
* Retain for 30+ days
* Document restore procedures
***
## Related Documentation
Learn how to generate secure guest tokens for embedded analytics
Enhanced security by managing tokens on your backend server
Implement complete data isolation for multi-tenant applications
Complete API reference with authentication examples
***
## Additional Resources
Comprehensive security information and certifications
How we collect, use, and protect your personal data
Information about our use of cookies and tracking technologies
***
## Need Help?
Contact DataBrain support for security assistance or to report security vulnerabilities
Reach out to discuss SOC 2, HIPAA, GDPR, or other compliance requirements
***
**Last Updated:** December 2025 | **Version:** 2.0
# Self Hosted Config
Source: https://docs.usedatabrain.com/developer-docs/self-hosted-config
When self hosted version of the app is used, the app needs to use these settings during embedding.
To change the configs we need to add some changes -
Where we are importing the plugin in the same file -
```js theme={"dark"}
import "@databrainhq/plugin/web";
window.dbn = {
baseUrl: SELFHOSTED_URL,
};
```
Assign configs in the `window.dbn` object. baseUrl - The base API endpoint e.g. [https://api.example.com](https://api.example.com), [https://yourdomain.com](https://yourdomain.com), etc.
You may face typescript errors while assigning to `window.dbn` this can be resolved by adding the below code to any global `d.ts` file
```ts theme={"dark"}
interface Window {
dbn: Record;
}
```
# Self-Hosted Health Checks & Probes
Source: https://docs.usedatabrain.com/developer-docs/self-hosted-health-checks
How to configure liveness/readiness probes and health checks for self-hosted Databrain (Kubernetes and Docker), including graceful shutdown (SIGTERM) behavior.
Self-hosted Databrain exposes built-in health endpoints that you can use for Kubernetes probes, Docker health checks, and external monitoring. This guide explains:
* **Which endpoints to use**
* **How to configure liveness and readiness probes** (Kubernetes)
* **How to configure Docker health checks**
* **How graceful shutdown (SIGTERM) works** in the backend and forecast services
This is a **DevOps configuration guide**, not an API reference.
***
## Health endpoints overview
Databrain services expose simple JSON health endpoints:
* **Backend (Express API)** – default port `3000`
* `GET /health/live` – liveness
* `GET /health/ready` – readiness (checks Hasura, Postgres via Hasura, and Keycloak if configured)
* **Forecast service (FastAPI)** – default port `8082`
* `GET /health/live`
* `GET /health/ready`
* **Hasura**
* `GET /healthz` – built-in Hasura health
* **App (frontend)**
* `GET /` – static app root
> For self-hosted deployments, replace host and ports with your actual values. If you run the backend behind a prefix (e.g. `/api`), the health paths become `/api/health/live` and `/api/health/ready`.
***
## Kubernetes configuration
This section shows typical probe configuration for a **Kubernetes** deployment. Adjust ports and paths to match your manifests.
### Hasura deployment
Use the built-in `/healthz` endpoint for both liveness and readiness:
```yaml theme={"dark"}
livenessProbe:
httpGet:
path: /healthz
port: 8082
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: 8082
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
```
> Note: the backend uses Hasura’s `healthz?strict=true` internally when evaluating Postgres health. **Do not** add query strings like `?strict=true` directly to Kubernetes `httpGet` probes – some Kubernetes versions URL-encode `?` which can break routing. Use plain `/healthz` in the probe and rely on the backend’s `/health/ready` for strict DB checks.
### Backend deployment (Express API)
The backend mounts health endpoints at `/health`. Recommended probes:
```yaml theme={"dark"}
livenessProbe:
httpGet:
path: /health/live
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 3000
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
terminationGracePeriodSeconds: 35
```
* **Liveness (`/health/live`)**
* Returns `{ "status": "live" }` with HTTP 200 when the process is running.
* Does **not** perform dependency checks.
* **Readiness (`/health/ready`)**
* Returns HTTP 200 and `{ "status": "ready", "checks": { ... } }` when:
* Hasura is reachable (`/healthz`)
* Postgres is healthy via Hasura strict health
* Keycloak is healthy (if configured)
* Returns HTTP 503 and `{ "status": "not_ready", "checks": { ... } }` when any check is failing.
### Forecast deployment (FastAPI)
The forecast service is a separate FastAPI app with its own health endpoints:
```yaml theme={"dark"}
livenessProbe:
httpGet:
path: /health/live
port: 8082
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 8082
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
terminationGracePeriodSeconds: 35
```
* `GET /health/live` returns `{ "status": "live" }`.
* `GET /health/ready` returns `{ "status": "ready" }` when the app is initialized and can accept requests.
### App deployment (frontend)
For the frontend container, it’s usually enough to probe the root URL:
```yaml theme={"dark"}
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
```
***
## Docker / Docker Compose health checks
For non-Kubernetes self-hosted setups, use Docker health checks with the same endpoints.
### Backend (Express API)
```yaml theme={"dark"}
services:
backend:
image: your-backend-image
ports:
- "3000:3000"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:3000/health/ready || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 20s
stop_grace_period: 35s
```
### Forecast service (FastAPI)
```yaml theme={"dark"}
services:
forecast:
image: your-forecast-image
ports:
- "8082:8082"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8082/health/ready || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 20s
stop_grace_period: 35s
```
### Hasura
```yaml theme={"dark"}
services:
hasura:
image: hasura/graphql-engine
ports:
- "8082:8080"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/healthz || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 20s
```
### App (frontend)
```yaml theme={"dark"}
services:
app:
image: your-frontend-image
ports:
- "80:80"
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost/ || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 20s
```
***
## Graceful shutdown & SIGTERM behavior
Recent backend changes added **graceful shutdown** handling for the Express API and improved lifecycle hooks for the forecast service.
### Backend (Express API)
Behavior (from `serverless/express/src/index.ts`):
* On `SIGTERM` or `SIGINT`:
* Logs: ` signal received: closing HTTP server`.
* Calls `server.close()`:
* Stops accepting new connections.
* Allows in-flight requests to complete.
* When the server is closed:
* Logs `HTTP server closed`.
* Calls `process.exit(0)`.
* A 30-second timeout is started:
* If shutdown is not complete within 30 seconds:
* Logs `Could not close connections in time, forcefully shutting down`.
* Calls `process.exit(1)`.
**Kubernetes recommendation**
* Set `terminationGracePeriodSeconds` to at least **35 seconds** for the backend pod.
* This gives the app enough time to drain connections and exit cleanly after receiving `SIGTERM`.
### Forecast service (FastAPI)
Behavior (from `forecast-timeseries/api.py`):
* Uses a FastAPI `lifespan` context manager:
* On startup: prints `Starting up Forecast service...`.
* On shutdown: prints `Shutting down Forecast service...`.
* This is where you can extend logic to close external resources (LLM clients, DB connections, etc.).
**Kubernetes / Docker**
* Use the same `terminationGracePeriodSeconds` / `stop_grace_period` (35s) pattern as the backend.
***
## Summary
* Use `/health/live` for **liveness**, `/health/ready` for **readiness**.
* For strict database checks, rely on the backend’s `/health/ready`, which already queries Hasura and Postgres.
* Configure Kubernetes and Docker health checks against these endpoints.
* Ensure termination grace periods are **≥ 35s** so graceful shutdown on `SIGTERM` can complete without forced kills.
# Dashboard for Multiple Clients
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/dashboard-for-multiple-clients
One universal dynamic dashboard for multiple clients
1. **Set up multi-data source workspace with one universal dynamic dashboard**
Kindly refer the below link:
2. **Embedding**
When embedding the dashboard for a client:
* Generate a **guest token** via DataBrain’s API.
* Pass the client's unique ID in the token payload.
* DataBrain will automatically scope all metric queries based on the passed Client ID.
To obtain a guest token from DataBrain, utilize our REST API from your backend system.
### Cloud version:
```bash theme={"dark"}
Post:
```
### Self-hosted version:
```bash theme={"dark"}
Post: /api/v2/guest-token/create
```
### Simple Request Body:
```json theme={"dark"}
{
"clientId": "id", // "None" if no tenancy available
"dataAppName": "dataappname",
"datasourceName": "data source name" // only for multi-datasource embed setup
}
```
This ensures that the same dashboard shows different, correct data for each client — securely and efficiently.
# Dashboards for Client Groups
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/dashboards-for-client-group
Segmenting Dashboards based on user accounts/client groups.
### 1.Client Table with Groups
Each client\_id is associated with a client\_group. Based on the group, they will be served a specific dashboard.
| client\_id | client\_group |
| ---------- | ------------- |
| 1 | Group A |
| 2 | Group B |
| 3 | Group C |
| 4 | Group A |
| 5 | Group B |
| 6 | Group C |
| 7 | Group A |
| 8 | Group B |
| 9 | Group C |
| 10 | Group A |
*Note: The above table is a representation of the client organization table maintained on your database.*
### Implementation Outline:
1. **Master Dashboard**: Create a Master Dashboard containing all metrics.
2. **Client Dashboards**: For each client group, create separate dashboards that pull metrics from the Master Dashboard.
3. **Automatic Sync**: Updates in the Master Dashboard reflect in all client dashboards using those metrics.
4. **Embedding**: Embed each Client Group Dashboard to display only the relevant metrics per group.
### 2. Dashboard IDs by Client Group
Define IDs for each dashboard corresponding to the client groups.
```js theme={"dark"}
const dashboardIds = {
"Group A": "dashboard-id-a",
"Group B": "dashboard-id-b",
"Group C": "dashboard-id-c"
};
// Function to fetch dashboard ID based on client group
function getDashboardId(clientGroup) {
return dashboardIds[clientGroup];
}
```
## Generate Token
To obtain a guest token from DataBrain, utilize our REST API from your backend system.
```bash theme={"dark"}
POST: https://api.usedatabrain.com/api/v2/guest-token/create
```
**Simple Request Body:**
```json theme={"dark"}
{
"clientId": "id",
"dataAppName": "dataappname"
}
```
### 3. Embedding the Dashboard
This function uses the fetched token and dashboard ID for the appropriate client group to embed the dashboard.
```javascript theme={"dark"}
function embedDashboard(clientGroup, token) {
const dashboardId = getDashboardId(clientGroup);
return (
``
);
}
```
### Summary
This consolidated approach uses the `client_id` and `client_group` table to control access to specific dashboards. One token for all dashboards and you change the `dashboard-id` based on `clientGroup`.
# Embedding: Role based Dashboard Filtering
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/embedding-role-based-dashboard-filtering
Dashboard Filtered based on the user role.
**Create a Dashboard Filter**
* In your dashboard, create a new ‘Dashboard Filter’.
* In the "Apply On" section, enable the App Filter option.
**Passing from Guest Token**
* You can link a guest token here to pass the filter values dynamically.
Refer the below document to generate a guest token.
ℹ️ Token
Below is a sample payload structure:
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
"name": "Eric",
"country": ["USA", "CANADA"],
"timePeriod": {
"startDate": "2024-01-01",
"endDate": "2024-03-23"
},
"price": {
"min": 1000,
"max": 5000
}
},
"isShowOnUrl": true
}
]
}
}
```
Make sure the options and values match the data type of the filter for successful integration.
### Example Use Case:
Let’s assume you have three roles:
* Admin
* Editor
* Viewer
And two Dashboard Filters:
* `Country: ["USA", "CANADA", "MEXICO", "CHINA", "INDIA"]`
* `Company: ["ALPHABET", "GOOGLE", "APPLE"]`
And below is the access level of each role:
Role/Dashboard Filters
Company
Country
Admin
All Companies
All Countries
Editor
All Companies
USA, CANADA, MEXICO
Viewer
Alphabet
USA
Now using the information from the table above, you can input the values to generate a guest token according to the specified role.
**Guest token for Admin:**
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
"client": ["ALPHABET", "GOOGLE", "APPLE"],
"country": ["USA", "CANADA", "MEXICO", "CHINA", "INDIA"]
},
"isShowOnUrl": true
}
]
}
}
```
**Guest token for Editor:**
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
"client": ["ALPHABET","GOOGLE","APPLE"],
"country": ["USA","CANADA","MEXICO"]
},
"isShowOnUrl": true
}
]
}
}
```
**Guest token for Viewer:**
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
"client": ["ALPHABET"],
"country": ["USA"]
},
"isShowOnUrl": true
}
]
}
}
```
### Optimizing Large Filters with SQL integration
For filters involving a large number of options (e.g., over 500), manually passing all values becomes inefficient. By integrating SQL, you can dynamically fetch options from your database, simplifying the process and improving efficiency.
The SQL query specified under the "sql" key dynamically fetches the latest values from the specified database table.
### Example Configuration
Let’s modify the earlier example for Admin to demonstrate SQL integration for dynamically fetching filter options:
**Guest token for Admin with SQL Integration:**
```json theme={"dark"}
{
"clientId": "id",
"workspaceName": "workspacename",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
"client": {
"sql": "SELECT \"name\" FROM \"public\".\"companies\" WHERE \"role\"='admin' ",
"columnName": "name"
},
"country": {
"sql": "SELECT \"name\" FROM \"public\".\"countries\" WHERE isEnabled=true",
"columnName": "name"
}
},
"isShowOnUrl": true
}
]
}
}
```
### Key Benefits
1. **Dynamic Updates:** The SQL query retrieves only the latest relevant options from your database.
* Example: `SELECT "name" FROM "public"."countries" WHERE isEnabled=true` fetches active country names.
2. **Efficiency:** Eliminates the need to manually manage large datasets in the configuration.
3. **Flexibility:** The `columnName` specifies the field in the query result to use as filter values.
4. **Scalability:** Handles thousands of options seamlessly, reducing payload size and improving performance.
### Ideal Use Case
This approach ensures that filters remain efficient, scalable, and user-friendly, with minimal manual effort to keep options up to date.
# Timezone Handling in Guest Token
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/guest-token-timezone
Pass a timezone parameter when generating a guest token to ensure SQL queries run in the correct timezone and date/time fields are consistently formatted across regions.
## Overview
Databrain allows you to pass a **timezone parameter (`params.timezone`)** while generating a guest token. This ensures that:
* SQL queries are executed in the correct timezone
* Date/time fields are consistently formatted
* Dashboard users across regions see accurate time-based insights
## Supported Data Sources
Timezone-aware execution is supported for:
* Clickhouse
* Trino
* Redshift
* CockroachDB
* Postgres
* MSSQL
## What is `params.timezone`?
```
params.timezone -- string
```
* Accepts a valid IANA timezone string
* Sets the database session timezone
* Ensures all date/time operations respect the specified timezone
## Common Timezone Values
| Timezone | Description |
| :---------------------- | :------------------------- |
| `"UTC"` | Coordinated Universal Time |
| `"America/New_York"` | Eastern Time (US) |
| `"America/Los_Angeles"` | Pacific Time (US) |
| `"Europe/London"` | GMT / BST |
| `"Asia/Kolkata"` | Indian Standard Time |
| `"Australia/Sydney"` | Australian Eastern Time |
## Guest Token Example with Timezone
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"timezone": "America/New_York"
}
}
```
## Step-by-Step Implementation
Create the required resources via the following APIs:
* [Create DataApp](/developer-docs/helpers/api-reference/create-data-app)
* [Create API Token for corresponding DataApp](/developer-docs/helpers/api-reference/create-api-token)
Ensure your dataset contains a timestamp column. Create a Datamart using the [Create Datamart API](/developer-docs/helpers/api-reference/create-datamart) and specify [isApplyTimezone](/developer-docs/helpers/api-reference/create-datamart#isApplyTimezone).
Create an Embed using your created datamart via the [Create Embed API](/developer-docs/helpers/api-reference/create-dashboard-embed) inside the created DataApp.
Include the `params.timezone` field in your payload when calling the [Guest Token API](/developer-docs/helpers/api-reference/token).
```json theme={"dark"}
{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"timezone": "America/New_York"
}
}
```
Use an appropriate IANA timezone (e.g., `"Asia/Kolkata"`).
Open your **demo link**, click **+ Create Metric**, and drag and drop the **date column** into the chart.
Then:
1. Open **Browser DevTools → Network Tab**
2. Inspect the executed query
Verify:
* The timezone value is applied in the query/session
* `"timezone": ""` is present inside the request payload (`params`)
## How It Works Internally
The timezone is applied at the database session level. Queries run as if the database is operating in that timezone. Functions like `NOW()`, `DATE_TRUNC`, and `TIMESTAMP` conversions will all respect the passed timezone.
# Localized Currency Symbols
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/localized-currency-symbols
This guide provides a practical approach for utilizing Dynamic Property to dynamically display revenue in multiple currencies for different countries.
### Use Case: Representing Revenue in Different Countries
An e-commerce business operating in multiple countries needs to represent revenue in different currencies. The finance team chooses to analyze revenue trends in localized formats by selecting different countries. Here are the steps to implement Dynamic Property for revenue tracking:
### 1. Access Dynamic Property:
* In the metric creation page, click on `"[X]"` icon near the sort icon.
* This will open the **"Dynamic Property"** panel on the right side of the screen.
* Then, click on **"+Property"** to add a dynamic property to your metric.
### 2. Configure Dynamic Property:
* Enter the Property Name and choose between the two Property Types:
* **"Auto"**
* Choose the dataset and the column you want to consider.
* **"Custom"**
* Enter your SQL query to choose your dynamic value and dependent columns, and select the column name.
* In this example, we select the column containing **currency codes** or create a **custom query** and save it as `[[Units]]`.
* Then, select the dependencies: dashboard or metric filter type. (Optional)
* Click **"Create"** to save the property.
### 3. Verify Property Creation
* Check the property listed in the Dynamic Property panel.
* Copy the property name format: \[\[Units]] and close the panel.
### 4. Configure formatting options:
* In the Formatting Section, set the prefix as \[\[Units]]
* This ensures that revenue values in the **Y-axis** display the correct currency code dynamically.
### 5. Save metric to Dashboard
* Click the **"Save to Dashboard"** button.
* Then, use `[[Units]]` in:
* **Metric Title**
* **Metric Description**
* **Metric Long Description**, and
* **Footnote**
### 6. Verify Dynamic Property Functionality
#### Metric Filter Example:
The `[[Units]]` dynamic property updates the **currency unit** based on the **selected country** in the **metric filter**.
### Dashboard Filter Example:
The `[[Units]]` dynamic property updates the **currency unit** based on the **selected country** in the **dashboard filter**.
Please refer the below link on how to create Dynamic Property:
This guide explains the process of using dynamic properties in metric creation. These properties can fetch dynamic values directly from the database, with dependencies on dashboard or metric filters.
# Manage Metrics
Source: https://docs.usedatabrain.com/developer-docs/solutions-alchemy/manage-metrics
Allow end user to manage metrics from embedded dashboard.
**Manage Metrics changes are per-dashboard, not per-viewer.** If multiple customers share the same embedded dashboard, one customer unchecking a metric hides it for **every** customer viewing that dashboard. Only enable Manage Metrics for end users on shared dashboards if that is acceptable — for per-customer metric selection, give each customer their own dashboard using the master + client dashboards pattern in the [Tenancy Model](/developer-docs/tenancy-model#master--client-dashboards-pattern).
By Default, all metrics are marked as mandatory to dashboard, to allow end user to archive metric from dashboard, mark the allowed metric on Save to Dashboard form & save it.
allow end user to archive metric
Enable Manage Metric for end user from **Workspace Settings**
End user can archive/unarchive metrics from manage metric in embedded dashboard settings
# Tenancy Model
Source: https://docs.usedatabrain.com/developer-docs/tenancy-model
How DataBrain enforces tenant isolation: Workspace vs Datamart vs Data App vs Client Group, guest-token variables, Manage Metrics scope, and the master + client dashboards pattern.
This is the single reference for how DataBrain enforces tenant isolation and metric visibility when you embed dashboards in a multi-tenant application.
## Concepts, top-down
* **Workspace** — outermost container. Holds Data Sources, Datamarts, Data Apps, Dashboards, Metrics. Members and permissions are Workspace-scoped. Most teams run one Workspace.
* **Data Source** — connection to your warehouse. Credentials live here.
* **Datamart** — logical selection of tables, columns, relationships, and joins on top of a Data Source. This is where the **Client ID column** for tenant isolation is set, and where the semantic layer lives.
* **Data App** — the unit of embedding. Carries the API key that authenticates guest-token minting and the reference to its Datamart. One Data App per embedding surface — you do **not** need a Data App per tenant.
* **Client Group** — a logical grouping of end-tenants that share a dashboard structure.
* **Manage Metrics** — a per-dashboard toggle that lets users pick which metrics appear. See the gotcha below before relying on it.
## The tenant identifier: three names, three places
| Name | Where | What it is |
| ---------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `clientId` | Guest-token JSON payload | Supplies the tenant value for the session. The only accepted spelling — `client_id` and `tenant_id` are rejected |
| `'client_id_variable'` | Custom metric SQL | A **bare quoted token** (no curly braces) substituted with the session's tenant value at query time, e.g. `WHERE client_column = 'client_id_variable'` |
| `{{DATABASE_NAME}}` | Custom metric SQL | The only curly-brace tenancy variable — resolves to the tenant's database/schema for database-per-tenant setups |
## Tenant-isolation strategies
### 1. Row-per-tenant (client\_id column)
All tenants share tables; every table has a tenant column. Configure the Datamart's Client ID column mapping. How the filter is applied depends on the metric type:
* **Builder (visual/dataset) metrics:** DataBrain auto-injects the tenant filter into the query. Do not add your own.
* **Custom SQL metrics:** the filter is **not auto-injected**. You must write it yourself:
```sql theme={"dark"}
SELECT * FROM orders WHERE client_id = 'client_id_variable'
```
A custom SQL metric that omits the tenant filter runs **unscoped** and returns every tenant's rows. Always include `'client_id_variable'` in custom SQL when your Datamart uses table-level tenancy.
### 2. Schema- or database-per-tenant
Each tenant has its own schema/database. Reference it in metric SQL via `{{DATABASE_NAME}}`, which resolves from the guest token's `clientId` through the Datamart mapping.
### Anti-pattern: hard-coded tenant IDs
Never save a literal tenant id in metric SQL (`WHERE client_id = 'acme'`) — for example by saving a metric while previewing as a specific client. That literal ships to **every** viewer and has caused real cross-tenant data leaks. If a metric must be scoped to one tenant on purpose, use RLS or an App Filter in the guest token instead.
## Manage Metrics scope — the important gotcha
**Manage Metrics visibility is per-dashboard, not per-viewer.** If Customer A unchecks a metric on a shared dashboard, it disappears for Customer B too. That is by design — do not use Manage Metrics for per-tenant metric visibility. Use the pattern below instead.
## Master + client dashboards pattern
For "each customer picks their own metric subset from a shared library":
1. Create one **master dashboard** with every metric in the library.
2. For each customer (or Client Group), create a **client dashboard** derived from the master — its own layout and visible-metric subset.
3. Embed the client dashboard per tenant with that tenant's `clientId` in the guest token.
Client dashboards can be provisioned programmatically — via the [Import Dashboard API](/developer-docs/helpers/api-reference/import-dashboard) or the MCP server's `create_embed` tool (which can clone a `templateDashboardId` per client). Note that import/clone is a **copy** operation: later edits to the master do not propagate to already-created client dashboards.
## Row-level security (RLS)
RLS (`params.rlsSettings` in the guest token) is an additional per-session constraint **on top of** tenant isolation — for example `region = 'NA'` for one user. It is enforced server-side and invisible to the end user. Do not use RLS as a substitute for the Datamart's Client ID mapping.
## Client selector
Embedded dashboards never render a client selector — the tenant is fixed by the guest token's `clientId`. The client/database dropdown you see inside the DataBrain app is for workspace members previewing data as different clients; it is not part of the embed.
## Where each setting lives
| Setting | Where | Scope |
| --------------------------------------- | ----------------------------- | ----------------------------------------- |
| Client ID column mapping | Datamart | Per Datamart |
| Data App API key | Data App | Per Data App |
| Whitelist Domains | Edited from Data App settings | Account-wide (one list for all Data Apps) |
| `clientId`, `rlsSettings`, `appFilters` | Guest token payload | Per session |
| Manage Metrics toggle | Dashboard settings | Per dashboard, shared across viewers |
| Client Group membership | Workspace settings | Per tenant grouping |
## Related
* [Guest Token](/developer-docs/helpers/api-reference/token)
* [Multi-Tenant Access Control](/developer-docs/multi-tenant-access-control)
* [Error Codes Reference](/developer-docs/reference/error-codes)
# Troubleshooting Guide
Source: https://docs.usedatabrain.com/developer-docs/testing/troubleshooting
Common issues and solutions for embedded DataBrain dashboards
This guide covers common issues you might encounter when embedding DataBrain and how to resolve them.
## Quick Diagnostics Checklist
Before diving into specific issues, run through this checklist:
Open Developer Tools (F12) and look for errors in the Console tab
Check the Network tab for failed API calls or 401/403 errors
Ensure your guest token is valid and not expired
Double-check dashboard-id and metric-id values
Try the sample token/dashboard to isolate the issue
## Common Issues
### Dashboard Not Rendering
**Symptoms:**
* Empty space where dashboard should be
* No errors in console
* Component seems to load but shows nothing
**Solutions:**
1. **Ensure plugin is imported before rendering:**
```javascript theme={"dark"}
// ✅ Correct - import first
import '@databrainhq/plugin/web';
import Dashboard from './Dashboard';
// ❌ Wrong - import after component
import Dashboard from './Dashboard';
import '@databrainhq/plugin/web';
```
2. **Check for web component support:**
```javascript theme={"dark"}
// Add this check
if (!customElements.get('dbn-dashboard')) {
console.error('DataBrain web components not loaded');
}
```
3. **Verify container has height:**
```css theme={"dark"}
.dashboard-container {
min-height: 600px; /* or 100vh */
}
```
4. **Check z-index conflicts:**
```css theme={"dark"}
dbn-dashboard {
position: relative;
z-index: 1;
}
```
**Symptoms:**
* Dashboard appears briefly then vanishes
* May happen on route changes or re-renders
**Solutions:**
1. **React: Prevent re-renders destroying the component:**
```javascript theme={"dark"}
import { useRef, useEffect } from 'react';
function Dashboard({ token }) {
const dashboardRef = useRef(null);
useEffect(() => {
if (dashboardRef.current && token) {
dashboardRef.current.setAttribute('token', token);
}
}, [token]);
return (
);
}
```
2. **Vue: Use v-show instead of v-if:**
```vue theme={"dark"}
```
3. **Check for parent component unmounting:**
Add key prop to prevent recreation
```javascript theme={"dark"}
```
**Symptoms:**
* Loading spinner never stops
* Dashboard never renders
**Causes & Solutions:**
1. **Invalid token:**
```javascript theme={"dark"}
// Check token format
console.log('Token:', token);
// Should be a UUID like: 3affda8b-7bd4-4a88-9687-105a94cfffab
```
2. **Wrong dashboard ID:**
```javascript theme={"dark"}
// Verify dashboard-id
console.log('Dashboard ID:', dashboardId);
// Should match ID from Data App
```
3. **Network blocked:**
* Check browser extensions (ad blockers, privacy tools)
* Verify no corporate firewall blocking
* Check CORS settings
### Authentication & Token Errors
Each token error string has exactly one meaning: `INVALID_TOKEN` = token not found in this deployment (usually a cloud vs self-hosted mismatch, or the embed isn't receiving the minted value); `TOKEN_EXPIRED` = past its `expiryTime`; `UNAUTHORIZED_ORIGIN` = origin not on Whitelist Domains; `UNAUTHORIZED` = the token isn't allowed this request — `allowedEmbeds` miss, wrong Data App/workspace, or (for dashboard-filter/view requests) that permission isn't enabled. Guest tokens are database-backed UUIDs — there is no signing secret. Full table: [Error Codes Reference](/developer-docs/reference/error-codes).
**Symptoms:**
* Error: "API key is invalid or expired"
* 401 status in network tab
**Solutions:**
1. **Verify API token is correct:**
```bash theme={"dark"}
# Test API token
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"clientId":"test","dataAppName":"your-app"}'
```
2. **Ensure Bearer prefix:**
```javascript theme={"dark"}
// ✅ Correct
headers: {
'Authorization': `Bearer ${apiToken}`
}
// ❌ Wrong
headers: {
'Authorization': apiToken
}
```
3. **Regenerate API token:**
* Go to Data App settings
* Generate new API token
* Update environment variables
**Symptoms:**
* "Token has expired" message
* Dashboard stops working after some time
**Solutions:**
1. **Set appropriate expiry time:**
```javascript theme={"dark"}
// Backend token generation
{
clientId: userId,
dataAppName: 'your-app',
expiryTime: 3600000 // 1 hour (adjust as needed)
}
```
2. **Implement token refresh:**
```javascript theme={"dark"}
import { useEffect, useState, useCallback } from 'react';
function useDataBrainToken() {
const [token, setToken] = useState(null);
const refreshToken = useCallback(async () => {
const response = await fetch('/api/databrain/guest-token');
const data = await response.json();
setToken(data.token);
}, []);
useEffect(() => {
refreshToken();
// Refresh token every 50 minutes (if set to 1 hour expiry)
const interval = setInterval(refreshToken, 50 * 60 * 1000);
return () => clearInterval(interval);
}, [refreshToken]);
return token;
}
```
3. **Handle token expiry event:**
```javascript theme={"dark"}
window.handleTokenExpiry = async (event) => {
if (event.type === 'TOKEN_EXPIRED') {
const newToken = await fetchFreshToken();
// Update token in component
document.querySelector('dbn-dashboard')
.setAttribute('token', newToken);
}
};
```
**Symptoms:**
* "Access to fetch blocked by CORS policy"
* Cross-origin errors in console
**Solutions:**
1. **Generate tokens from backend (not frontend):**
```javascript theme={"dark"}
// ✅ Correct - backend generates token
// backend/api/token.js
const token = await generateGuestToken(userId);
// ❌ Wrong - frontend trying to generate
// Causes CORS errors
fetch('https://api.usedatabrain.com/api/v2/guest-token/create')
```
2. **Whitelist your domain:**
* Go to your Data App's settings → **Whitelist Domains** (the input field there is labeled "Allowed Origins" — same setting)
* Add your domains as scheme-less `host[:port]` entries, e.g. `app.yoursite.com` or `localhost:3000` — do not include `http://` or `https://`
* Wildcards like `*.yoursite.com` are supported
* Include all environments (dev, staging, prod)
* Note: the whitelist applies account-wide — the same list covers all your Data Apps
3. **Check for mixed content (HTTP/HTTPS):**
```javascript theme={"dark"}
// Ensure HTTPS if embedding on HTTPS site
const apiUrl = window.location.protocol === 'https:'
? 'https://api.usedatabrain.com'
: 'http://api.usedatabrain.com';
```
### Display & Styling Issues
**Symptoms:**
* Dashboard hidden behind other elements
* Modals or dropdowns don't appear correctly
**Solutions:**
1. **Set appropriate z-index:**
```css theme={"dark"}
dbn-dashboard {
position: relative;
z-index: 10;
}
/* If dashboard needs to be on top */
dbn-dashboard::part(modal) {
z-index: 9999;
}
```
2. **Check parent container:**
```css theme={"dark"}
.dashboard-container {
position: relative;
z-index: auto; /* Don't create new stacking context */
}
```
3. **Use isolation:**
```css theme={"dark"}
.dashboard-wrapper {
isolation: isolate;
}
```
**Symptoms:**
* Dashboard doesn't fit screen
* Charts overlap on mobile
* Scrolling issues
**Solutions:**
1. **Ensure container is responsive:**
```css theme={"dark"}
.dashboard-container {
width: 100%;
max-width: 100vw;
min-height: 600px;
overflow: auto;
}
@media (max-width: 768px) {
.dashboard-container {
min-height: 400px;
}
}
```
2. **Set viewport meta tag:**
```html theme={"dark"}
```
3. **Use responsive theme:**
```javascript theme={"dark"}
const theme = {
general: {
primaryColor: '#0066CC'
},
responsive: {
breakpoints: {
mobile: 768,
tablet: 1024
}
}
};
```
**Symptoms:**
* Custom colors not showing
* Font changes not working
* Theme options ignored
**Solutions:**
1. **Stringify theme object:**
```javascript theme={"dark"}
// ✅ Correct
// ❌ Wrong
```
2. **Check theme structure:**
```javascript theme={"dark"}
const theme = {
general: {
primaryColor: '#0066CC',
backgroundColor: '#FFFFFF',
fontFamily: 'Inter, sans-serif'
},
chart: {
colors: ['#0066CC', '#00C2B8'] // Array of colors
}
};
```
3. **Verify CSS specificity:**
```css theme={"dark"}
/* Your styles might be overriding */
dbn-dashboard {
all: initial; /* Reset if needed */
}
```
### Performance Issues
**Symptoms:**
* Dashboard takes long to load
* Metrics render slowly
* Poor performance with large datasets
**Solutions:**
1. **Enable caching in workspace settings:**
* Go to **Workspace Settings → Cache Settings**
* Enable query result caching
* Set an appropriate TTL (start with 3600 seconds / 1 hour)
* Choose **DataBrain Caching** for quick setup, or **BYOC** if you have your own Redis
* See the [Cache Settings guide](/guides/onboarding-and-configuration/workspace-settings/cache-settings) for detailed setup
2. **Apply filters to limit data:**
```javascript theme={"dark"}
const tokenRequest = {
clientId: userId,
dataAppName: 'your-app',
params: {
dashboardAppFilters: [{
dashboardId: 'dashboard-id',
values: {
date_range: {
startDate: '2024-01-01',
endDate: '2024-03-31'
}
}
}]
}
};
```
3. **Optimize metrics:**
* Reduce number of data points
* Use aggregations
* Limit table rows
* Consider pagination
4. **Lazy load dashboards:**
```javascript theme={"dark"}
import { lazy, Suspense } from 'react';
const Dashboard = lazy(() => import('./Dashboard'));
}>
```
**Symptoms:**
* Page slows down over time
* Browser tab crashes
* Increasing memory usage
**Solutions:**
1. **Clean up on unmount:**
```javascript theme={"dark"}
useEffect(() => {
const dashboard = document.querySelector('dbn-dashboard');
return () => {
// Clean up event listeners
if (dashboard) {
dashboard.removeEventListener('*', handleEvent);
}
};
}, []);
```
2. **Remove event listeners:**
```javascript theme={"dark"}
// Don't recreate handler on every render
const handleEvent = useCallback((event) => {
// Handle event
}, []);
```
3. **Limit re-renders:**
```javascript theme={"dark"}
// Use memo for expensive components
const MemoizedDashboard = React.memo(Dashboard);
```
### Cache & Redis Issues
**Symptoms:**
* Dashboard shows old data after an ETL run or manual data update
* Different users see inconsistent data
**Solutions:**
1. **Reset cache after data updates:**
* Go to **Workspace Settings → Cache Settings** and click **Reset Cache**
* This flushes all cached query results for the workspace
2. **Reduce cache TTL:**
* If your data updates frequently, lower the cache expiration time
* For hourly updates, set TTL to `3600` (1 hour) or less
3. **Verify cache is the cause:**
* Temporarily disable caching in **Workspace Settings → Cache Settings**
* If the data is now correct, caching was serving stale results
**Symptoms:**
* Cache settings fail to save with "Invalid Redis credentials" error
* Caching enabled but no speed improvement on repeat dashboard loads
**Solutions:**
1. **Check network connectivity:**
* Your Redis must be reachable from DataBrain's cloud
* Verify your security group allows inbound on the Redis port (default `6379`) from DataBrain's IP (see [Allow Access to our IP](/guides/datasources/allow-access-to-our-ip))
* If your Redis is in a private network, contact DataBrain support for connectivity options
2. **Verify credentials:**
* Double-check the host, port, and AUTH token
* Ensure the AUTH token matches what's configured on your Redis instance
* Try connecting to your Redis from another client to rule out credential issues
3. **Check Redis is running:**
* Ensure your Redis/Elasticache instance is in an "Available" state
* Check for maintenance windows or failover events
4. **Connection timeout:**
* DataBrain uses a 5-second connection timeout
* If your Redis has high network latency (e.g., cross-region), connections may time out
**Symptoms:**
* Caching is enabled but dashboards aren't loading faster
* Every request seems to hit the database
**Solutions:**
1. **Verify caching is enabled:**
* Go to **Workspace Settings → Cache Settings** and confirm the toggle is on
* Confirm you've set a TTL greater than 0
2. **Check cache mode:**
* If using **Databrain Caching**, it should work automatically
* If using **BYOC**, verify your Redis connection was validated successfully (save must succeed)
3. **Understand cache key behavior:**
* Cache keys include the full query, filters, workspace ID, and datasource ID
* Changing any filter or parameter generates a new cache key
* Dashboards with many dynamic filters may have lower cache hit rates
4. **Check TTL is reasonable:**
* Very short TTLs (e.g., 10 seconds) mean cache entries expire before they can be reused
* Start with `3600` (1 hour) and adjust based on your needs
### Framework-Specific Issues
**Issue: Component not updating on prop changes**
```javascript theme={"dark"}
// ✅ Solution: Use useEffect
useEffect(() => {
const element = document.querySelector('dbn-dashboard');
if (element && token) {
element.setAttribute('token', token);
}
}, [token]);
```
**Issue: TypeScript errors**
```typescript theme={"dark"}
// Add type declaration
declare global {
namespace JSX {
interface IntrinsicElements {
'dbn-dashboard': any;
'dbn-metric': any;
}
}
}
```
**Issue: Next.js SSR errors**
```javascript theme={"dark"}
// Use dynamic import with ssr: false
import dynamic from 'next/dynamic';
const Dashboard = dynamic(
() => import('../components/Dashboard'),
{ ssr: false }
);
```
**Issue: Vue warnings about unknown custom element**
```javascript theme={"dark"}
// vue.config.js or vite.config.js
export default {
compilerOptions: {
isCustomElement: tag => tag.startsWith('dbn-')
}
}
```
**Issue: Reactive props not updating**
```vue theme={"dark"}
```
**Issue: CUSTOM\_ELEMENTS\_SCHEMA required**
```typescript theme={"dark"}
// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
```
**Issue: Change detection not working**
```typescript theme={"dark"}
import { ChangeDetectorRef } from '@angular/core';
constructor(private cdr: ChangeDetectorRef) {}
updateToken(newToken: string) {
this.token = newToken;
this.cdr.detectChanges();
}
```
## Debugging Tips
### Inspect Component State
```javascript theme={"dark"}
// Check component attributes
const dashboard = document.querySelector('dbn-dashboard');
console.log({
token: dashboard.getAttribute('token'),
dashboardId: dashboard.getAttribute('dashboard-id'),
options: dashboard.getAttribute('options')
});
```
### Monitor Network Requests
```javascript theme={"dark"}
// Log all DataBrain API calls
const originalFetch = window.fetch;
window.fetch = function(...args) {
if (args[0].includes('usedatabrain.com')) {
console.log('DataBrain API call:', args);
}
return originalFetch.apply(this, args);
};
```
## Error Messages Reference
For the complete list of error codes with causes and fixes, see the [Error Codes Reference](/developer-docs/reference/error-codes).
| Error Message | Cause | Solution |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `INVALID_TOKEN` | Token not found in this deployment (cloud vs self-hosted mismatch, or embed not receiving the minted value) | Mint against the same environment the embed points at; pass the exact minted token |
| `TOKEN_EXPIRED` | Token past its `expiryTime` (tokens without `expiryTime` never expire) | Regenerate token from backend |
| `UNAUTHORIZED_ORIGIN` | Page origin not on Whitelist Domains | Add scheme-less `host[:port]` to your Data App's Whitelist Domains |
| `UNAUTHORIZED` | ID not in the token's `allowedEmbeds`; or the dashboard doesn't belong to the token's Data App/workspace; or, on dashboard-filter, metric-filter, view, or filter-alias requests, that capability isn't granted | Add the ID at mint time; verify the Data App; for filter/view/alias requests enable the matching Data App access setting or token permission (`params.accessPermissions.isAllowEndUserDashboardFilter`, `isAllowEndUserMetricFilter`, `isAllowDashboardFilterNameChange`, or `isAllowMetricFilterNameChange`; dashboard views use `permissions.isEnableCreateDashboardView`) |
| `INVALID_ID` / `Dashboard not found` | Wrong dashboard ID or ID from another Data App | Verify dashboard-id attribute and Data App |
| `CORS policy error` | Frontend trying to call API directly | Generate tokens from backend |
| `Failed to fetch` | Network or firewall issue | Check network connectivity |
| `INVALID_DATA_APP_NAME` | Wrong `dataAppName` in token request (case-sensitive) | Verify Data App name |
| `Rate limit exceeded` | Too many API calls | Implement rate limiting/caching |
## Getting Help
If you're still stuck after trying these solutions:
Use our test environment to isolate issues
Check working examples in playground
Review complete API specs
Contact our support team
## Best Practices to Avoid Issues
Never expose API tokens in frontend code. Use your backend to generate guest tokens.
Always handle token generation failures and network errors gracefully.
Type safety helps catch issues during development.
Verify your implementation works in Chrome, Firefox, Safari, and Edge.
Set up error tracking (Sentry, LogRocket) to catch issues early.
# Token
Source: https://docs.usedatabrain.com/developer-docs/token
This page is the guide. For the field-by-field API reference of this endpoint, see the canonical [Guest Token API reference](/developer-docs/helpers/api-reference/token) — if the two ever disagree, the API reference wins.
To obtain a guest token from DataBrain, utilize our REST API from your backend system. Each request will generate a unique guest token, ensuring security and flexibility.
Once you acquire the guest token, you can seamlessly pass it to your frontend application, where it can be integrated with the web component.
`Create API key from Databrain's dashboard` that should be passed in the headers in these requests.Guest tokens are designed for frontend embedding. Never expose your API key in frontend code — always generate tokens from your backend.
### Quick start (simple use case):
When you need a guest token that you want to use across dashboards and metrics, all you have to do is pass `clientId`, `dataAppName`. If `expiryTime` is not passed, the token will not expire.
#### Cloud Databrain Endpoint:
```http theme={"dark"}
POST https://api.usedatabrain.com/api/v2/guest-token/create
```
#### Self-hosted Databrain Endpoint:
```http theme={"dark"}
POST /api/v2/guest-token/create
```
Generating GUEST TOKEN for your Dashboard/Metric Component.
### Headers
| Name | Type | Description |
| --------------- | ------ | ---------------------------------------------------------------------------------- |
| Authorization\* | String | Bearer [API TOKEN](https://docs.usedatabrain.com/developer-docs/helpers/api-token) |
| Content-Type\* | String | Must be set to `application/json` for all requests |
### Request Body
| Name | Type | Description |
| -------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| dataAppName\* | String | Your Data App Name |
| clientId\* | String | Client ID for whom this guest token is generated. (`"clientId": "None"` if no tenancy selected) |
| params | Object | Additional Params: `rlsSettings`, `appFilters`, `dashboardAppFilters`, `hideDashboardFilters`, `hideDashboardMetrics`, `allowedEmbeds`, `userIdentifier`, `timezone`, `accessPermissions` |
| permissions | Object | Dashboard permission toggles — see [Dashboard Permissions](#dashboard-permissions) below |
| expiryTime | Number | Duration in milliseconds from token creation. Common values: `3600000` (1 hour), `86400000` (24 hours), `604800000` (7 days). If omitted, the token never expires |
| datasourceName | String | Datasource name from Data Studio (*important in case of multi-datasource embed setup*) |
| datamartName | String | Optionally scope the token to a specific Datamart |
The request body is validated strictly — any field not listed above is rejected with `INVALID_REQUEST_BODY`. In particular, `dataAppId`, `tenant_id`, `client_id`, and `permissions.dashboards` are **not** valid fields. Use `clientId` and `dataAppName` exactly as spelled here.Guest tokens are free. There is no charge, metering, or purchase involved in generating them — mint as many as you need from your backend.
```json theme={"dark"}
// 200: OK
{
"token": "..."
}
```
```json theme={"dark"}
// 400: Bad Request
{
"error": {
"message": "invalid dashboard id",
"code": ""
}
}
```
```json theme={"dark"}
// 401: Unauthorized
{
"error": {
"message": "API key is invalid or expired",
"code": "AUTHENTICATION_ERROR"
}
}
```
### Request Body Examples:
#### Simple Request Body:
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname"
}
```
#### Request Body with App Level Metric Filter:
> **App filter**\
> A metric level filter designed specifically for controlling access to individual metrics. Unlike general RLS settings, it restricts access without requiring end user input or control.
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"params": {
"appFilters": [{
"metricId": "The id of the metric you want to have app filters",
"values": {
"paid_orders": true,
"amount": 500,
"country": ["USA", "CANADA"] || "USA", // based on filter variant (select or multi)
{
"sql": "SELECT \"name\" FROM \"public\".\"countries\" WHERE isEnabled=true",
"columnName": "name"
}
}
}]
}
}
```
### Dashboard App Filters:
#### Request Body with Dashboard filters:
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"params": {
"dashboardAppFilters": [
{
"dashboardId": "dashboard-id",
"values": {
// single string
"name": "Eric",
// multi select
"country": ["USA", "CANADA"] || "USA", // based on filter variant (select or multi)
{
"sql": "SELECT \"name\" FROM \"public\".\"countries\" WHERE isEnabled=true",
"columnName": "name"
},
// date-picker
"timePeriod": { "startDate": "2024-01-01", "endDate": "2024-3-23" },
// range
"price": { "min": 1000, "max": 5000 }
},
"isShowOnUrl": true // true/false
}
]
}
}
```
In the above code snippet, `"name"`, `"country"`, `"timePeriod"`, and `"price"` are Dashboard App filters.\
When you disable the `isShowOnUrl`, the filter will not be visible to end users as search params on URL.
### Datasource \[Multi Datasource connection]:
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"datasourceName": "data source name"
}
```
`datasourceName` is available in app data studio tab.
### Hide Dashboard Filters:
To hide dashboard filters in an embedded dashboard:
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"params": {
"hideDashboardFilters": ["filter 1", "filter 2"] // name of dashboard filters to hide
}
}
```
### Hide Dashboard Metrics:
Use `params.hideDashboardMetrics` to hide selected metrics and their layout cards on specific embedded dashboards for this guest token. Each item requires the dashboard's external ID and an array of public metric IDs that are present on that dashboard.
```json theme={"dark"}
{
"clientId": "id",
"dataAppName": "dataappname",
"params": {
"hideDashboardMetrics": [
{
"dashboardId": "sales-overview",
"metricIds": ["revenue-by-region", "gross-margin"]
}
]
}
}
```
The dashboard must be within the API token's data app and workspace scope. This setting affects only the matching dashboard's embed response; it does not delete, archive, or change metrics globally. See the [Guest Token API reference](/developer-docs/helpers/api-reference/token) for validation and error details.
### Allowed Embeds (optional)
To restrict which dashboards a guest token can load, pass an allowlist of IDs in `params.allowedEmbeds`.
When set, the token can only load an embed whose ID (the value you pass to the component's `dashboard-id`/`dashboardId` attribute — an embed ID or dashboard ID both work) is included in the list. Loading any other ID fails with `UNAUTHORIZED`.
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"params": {
"allowedEmbeds": ["", ""]
}
}
```
### Dashboard Permissions
To enable or disable few dashboard permissions from backend:
```json theme={"dark"}
{
"clientId": "id", //"None" if no tenancy available
"dataAppName": "dataappname",
"permissions": {
"isEnableArchiveMetrics": true, // true or false
"isEnableManageMetrics": true, // true or false
"isEnableCreateDashboardView": true, // true or false - allow creating custom dashboard views
"isEnableMetricUpdation": true, // true or false
"isEnableCustomizeLayout": true, // true or false
"isEnableUnderlyingData": true, // true or false
"isEnableDownloadMetrics": true, // true or false
"isShowSideBar": true, // true or false - show the sidebar navigation
"isShowDashboardName": true, // true or false - show the dashboard name in the interface
"isDisableMetricCreation": false // true or false - disable metric creation for end users
}
}
```
### User Identifier for Private & Publish Metrics
Use `userIdentifier` inside the `params` object to uniquely identify the end-user in your embedded dashboard.\
This enables features such as creating **private metrics** and **publishing metrics** directly from the embed view.
```json theme={"dark"}
{
"clientId": "id",
"dataAppName": "dataappname",
"params": {
"userIdentifier": "unique-user-id-123"
}
}
```
Note: userIdentifier should be a unique string representing the logged-in user in your system.
When set, any metrics created by this identifier can be managed (private or published) within the embedded environment.
`isAllowPrivateMetricsByDefault` should be enabled while creating the dashboard.
### Timezone
Use `timezone` inside the `params` object to specify an IANA timezone string for timezone-aware queries and date/time formatting. When provided, SQL queries will be executed with this timezone setting, ensuring consistent date/time handling across different timezones.
**Supported Datasources:** Clickhouse, Trino, Redshift, CockroachDB, Postgres, MSSQL
Common timezone values: `"UTC"`, `"America/New_York"`, `"America/Los_Angeles"`, `"Europe/London"`, `"Asia/Kolkata"`, `"Australia/Sydney"`
```json theme={"dark"}
{
"clientId": "id",
"dataAppName": "dataappname",
"params": {
"timezone": "America/New_York"
}
}
```
### End-user Filter Permissions
Use `params.accessPermissions` to control end-user dashboard and metric filters, restrict filterable columns, and allow end users to rename filter labels in an embedded experience. Each `*Columns` entry requires a `tableName` and a `columns` array of strings.
```json theme={"dark"}
{
"clientId": "id",
"dataAppName": "dataappname",
"params": {
"accessPermissions": {
"isAllowEndUserDashboardFilter": true,
"dashboardFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["customer_id", "region"]
}
],
"isAllowEndUserMetricFilter": true,
"metricFilterColumns": [
{
"tableName": "public.sales_data",
"columns": ["region", "order_date"]
}
],
"isAllowDashboardFilterNameChange": true,
"isAllowMetricFilterNameChange": true
}
}
}
```
When a permission is supplied in the guest token, it takes precedence over the corresponding Data App access setting. See [Update Embedded Filter Alias](/developer-docs/helpers/api-reference/update-filter-alias) to rename a filter through the embedded API.
### Code Examples
```bash cURL (Simple) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-456",
"dataAppName": "sales-dashboard"
}'
```
```bash cURL (Advanced) icon="fa-solid fa-terminal" theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer dbn_live_abc123...' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-456",
"dataAppName": "sales-dashboard",
"params": {
"rlsSettings": [
{
"metricId": "metric_123",
"values": {
"customer_id": "456",
"region": "north-america"
}
}
]
},
"expiryTime": 3600000
}'
```
```javascript Node.js icon="fa-brands fa-node-js" theme={"dark"}
const response = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {
method: 'POST',
headers: {
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
body: JSON.stringify({
clientId: 'user-456',
dataAppName: 'sales-dashboard',
params: {
rlsSettings: [
{
metricId: 'metric_123',
values: {
customer_id: '456',
region: 'north-america'
}
}
]
},
expiryTime: 3600000
})
});
```
```python Python icon="fa-brands fa-python" theme={"dark"}
import requests
response = requests.post(
'https://api.usedatabrain.com/api/v2/guest-token/create',
headers={
'Authorization': 'Bearer dbn_live_abc123...',
'Content-Type': 'application/json'
},
json={
'clientId': 'user-456',
'dataAppName': 'sales-dashboard',
'params': {
'rlsSettings': [
{
'metricId': 'metric_123',
'values': {
'customer_id': '456',
'region': 'north-america'
}
}
]
},
'expiryTime': 3600000
}
)
```
```java Java icon="fa-brands fa-java" theme={"dark"}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.List;
HttpClient client = HttpClient.newHttpClient();
ObjectMapper mapper = new ObjectMapper();
Map requestBody = Map.of(
"clientId", "user-456",
"dataAppName", "sales-dashboard",
"params", Map.of(
"rlsSettings", List.of(
Map.of(
"metricId", "metric_123",
"values", Map.of(
"customer_id", "456",
"region", "north-america"
)
)
)
),
"expiryTime", 3600000
);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.usedatabrain.com/api/v2/guest-token/create"))
.header("Authorization", "Bearer dbn_live_abc123...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(requestBody)))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
```
```php PHP icon="fa-brands fa-php" theme={"dark"}
'user-456',
'dataAppName' => 'sales-dashboard',
'params' => [
'rlsSettings' => [
[
'metricId' => 'metric_123',
'values' => [
'customer_id' => '456',
'region' => 'north-america'
]
]
]
],
'expiryTime' => 3600000
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.usedatabrain.com/api/v2/guest-token/create',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer dbn_live_abc123...',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
?>
```
```ruby Ruby icon="fa-solid fa-gem" theme={"dark"}
require 'net/http'
require 'json'
uri = URI('https://api.usedatabrain.com/api/v2/guest-token/create')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer dbn_live_abc123...'
request['Content-Type'] = 'application/json'
request.body = {
clientId: 'user-456',
dataAppName: 'sales-dashboard',
params: {
rlsSettings: [
{
metricId: 'metric_123',
values: {
customer_id: '456',
region: 'north-america'
}
}
]
},
expiryTime: 3600000
}.to_json
response = http.request(request)
```
```go Go icon="fa-brands fa-golang" theme={"dark"}
package main
import (
"bytes"
"encoding/json"
"net/http"
)
type RLSValue struct {
CustomerID string `json:"customer_id"`
Region string `json:"region"`
}
type RLSSetting struct {
MetricID string `json:"metricId"`
Values RLSValue `json:"values"`
}
type Params struct {
RLSSettings []RLSSetting `json:"rlsSettings"`
}
type RequestBody struct {
ClientID string `json:"clientId"`
DataAppName string `json:"dataAppName"`
Params Params `json:"params"`
ExpiryTime int `json:"expiryTime"`
}
func main() {
requestBody := RequestBody{
ClientID: "user-456",
DataAppName: "sales-dashboard",
Params: Params{
RLSSettings: []RLSSetting{
{
MetricID: "metric_123",
Values: RLSValue{
CustomerID: "456",
Region: "north-america",
},
},
},
},
ExpiryTime: 3600000,
}
jsonData, _ := json.Marshal(requestBody)
req, _ := http.NewRequest("POST", "https://api.usedatabrain.com/api/v2/guest-token/create", bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer dbn_live_abc123...")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
```
```csharp C# icon="fa-solid fa-code" theme={"dark"}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class GuestTokenRequest
{
[JsonProperty("clientId")]
public string ClientId { get; set; }
[JsonProperty("dataAppName")]
public string DataAppName { get; set; }
[JsonProperty("params")]
public Params Params { get; set; }
[JsonProperty("expiryTime")]
public int ExpiryTime { get; set; }
}
public class Params
{
[JsonProperty("rlsSettings")]
public RLSSetting[] RlsSettings { get; set; }
}
public class RLSSetting
{
[JsonProperty("metricId")]
public string MetricId { get; set; }
[JsonProperty("values")]
public Values Values { get; set; }
}
public class Values
{
[JsonProperty("customer_id")]
public string CustomerId { get; set; }
[JsonProperty("region")]
public string Region { get; set; }
}
var client = new HttpClient();
var request = new GuestTokenRequest
{
ClientId = "user-456",
DataAppName = "sales-dashboard",
Params = new Params
{
RlsSettings = new[]
{
new RLSSetting
{
MetricId = "metric_123",
Values = new Values
{
CustomerId = "456",
Region = "north-america"
}
}
}
},
ExpiryTime = 3600000
};
var json = JsonConvert.SerializeObject(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer dbn_live_abc123...");
var response = await client.PostAsync("https://api.usedatabrain.com/api/v2/guest-token/create", content);
```
### HTTP Status Codes
| Status Code | Description |
| ----------- | ------------------------------------------------- |
| `200` | **OK** - Request succeeded |
| `400` | **Bad Request** - Invalid request parameters |
| `401` | **Unauthorized** - Invalid or missing API key |
| `403` | **Forbidden** - Access denied to resource |
| `404` | **Not Found** - Resource not found |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - Server error occurred |
**Rate Limiting**: API requests are limited to prevent abuse. Implement exponential backoff for rate limited requests (429 status).
### Error Codes:
| Error Code | HTTP Status | Description |
| -------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `AUTHENTICATION_ERROR` | 401 | Invalid or missing API key |
| `INVALID_REQUEST_BODY` | 400 | Missing, invalid, or unknown parameters (unrecognized fields are rejected) |
| `CLIENT_ID_ERROR` | 400 | Invalid clientId format or value |
| `INVALID_DATA_APP_NAME` | 400 | `dataAppName` doesn't match any Data App (case-sensitive) |
| `WORKSPACE_ID_ERROR` | 404 | Workspace not found or inaccessible |
| `DASHBOARD_PARAM_ERROR` | 400 | Invalid dashboard filter parameters or a `hideDashboardMetrics` dashboard outside the API token's data app/workspace scope |
| `INVALID_METRIC_ID` | 400 | A `hideDashboardMetrics.metricIds` value is not present on the specified dashboard |
| `APP_FILTER_PARAM_ERROR` | 400 | Invalid app filter configuration |
| `RLS_SETTINGS_PARAM_ERROR` | 400 | Invalid RLS settings |
| `DATASOURCE_NAME_ERROR` | 400 | `datasourceName` doesn't resolve |
| `DATAMART_NAME_ERROR` | 400 | `datamartName` doesn't resolve |
| `INTERNAL_SERVER_ERROR` | 500 | Server error |
At embed runtime (after minting), the distinct errors are `INVALID_TOKEN` (token not found in this deployment), `TOKEN_EXPIRED`, `UNAUTHORIZED_ORIGIN`, `UNAUTHORIZED`, and `INVALID_ID` — see the [Error Codes Reference](/developer-docs/reference/error-codes).
# Create and Access Your Databrain Account
Source: https://docs.usedatabrain.com/getting-started/account-setup
Follow this quick guide to sign up for a new Databrain account or sign in to your existing one.
# Account Setup
## Sign Up
Go to
Databrain App and enter your work email. Click **Continue**.
Provide your name, company name, and password.
Click **Create Account** to complete your registration.
Confirm your email address. After verification, you’ll be redirected to your workspace and guided through a detailed setup walkthrough.
***
## Sign In
Go to
Databrain App
and enter your email and password. Click **Continue**.
Once authenticated, your Databrain account is ready to use.
# Dashboards
Source: https://docs.usedatabrain.com/getting-started/core-concepts/dashboards
Create interactive analytics dashboards to visualize your data
## What is a Dashboard?
A dashboard is a collection of metrics (charts, tables, KPIs) organized into a cohesive view. Dashboards provide a comprehensive overview of your data, allowing you to monitor KPIs, track trends, and gain insights at a glance.
## Key Features
Easily arrange metrics with an intuitive visual interface
Add global filters that apply across all dashboard metrics
Automatic refresh and live data updates
Dashboards adapt to different screen sizes
## Dashboard Components
### Metrics
Individual visualizations like charts, tables, and single-value cards that display your data.
### Dashboard Elements
Add headers, descriptions, images, and other content to provide context.
## Dashboard Filters
Dashboard filters are powerful controls that apply across all metrics on a dashboard simultaneously.
### Filter Types
Select single or multiple values from a list
Filter data by date periods with presets or custom ranges
Free-text search across dimension values
Filter numeric values using min/max ranges
Learn how to create and configure dashboard filters
## Layout & Customization
### Grid System
Dashboards use a responsive grid system. Metrics can be:
* Resized by dragging corners
* Moved by dragging the header
* Arranged in rows and columns
* Stacked or placed side-by-side
### Customize Layout
Access layout customization to:
* Set dashboard width (full-width or fixed)
* Adjust metric spacing
* Configure responsive breakpoints
* Set background colors
Detailed guide on dashboard customization
## Dashboard Settings
Access dashboard settings from the **Settings** icon in the top right corner of any dashboard. The settings dropdown provides access to various dashboard management tools:
### Dashboard Settings Menu
* **Embed Dashboard**: Get embeddable code or the DataBrain app dashboard UI plugin (React and Vue)
* **Customize Layout**: Organize and arrange dashboard metrics
* **Manage Metrics**: Show or hide metrics on the dashboard
* **Export As PDF**: Export the dashboard as a PDF document
* **Report Scheduler**: Create and manage automated dashboard reports
* **Rules Builder**: Hide or unhide metrics based on selected charts
* **Download Metrics**: Download underlying data for all metrics
* **Enable Board**: Create multiple views of a dashboard based on applied filters
### Global Dashboard Settings
Configure account-wide dashboard settings at `/settings/embed/dashboardSettings`:
* **Dashboard Auto Refresh**: Enable automatic refresh of dashboard data
* **Refresh Rate**: Set the refresh interval in seconds (minimum 5 seconds)
Complete dashboard settings reference
## Sharing & Collaboration
### Share Dashboard
Share dashboards with team members or external users:
* Generate shareable links
* Set expiration dates
* Control view/edit permissions
* Password protection
### Export Options
* PDF reports
* Scheduled email delivery
* Image snapshots
* CSV data export
Learn about sharing options
## Embedding Dashboards
Embed dashboards directly into your application using the DataBrain NPM package.
```html theme={"dark"}
```
Complete embedding guide for developers
## Dashboard Actions
### Chart Actions
Configure what happens when users interact with charts:
* Drill down into detailed data
* Navigate to other dashboards
* Filter other metrics
* Open custom URLs
### Interactive Elements
* Click events on charts
* Hover tooltips
* Cross-filtering between metrics
Configure chart interactions
## Best Practices
Each dashboard should serve a specific purpose. Don't try to show everything on one dashboard.
Add dashboard filters to enable self-service analytics. But don't overwhelm users with too many options.
Place the most important metrics at the top. Use size to indicate importance.
Include text descriptions, tooltips, and footnotes to help users understand the data.
Use caching and limit concurrent queries. Consider creating summary metrics for better performance.
## Common Use Cases
### Executive Dashboard
High-level KPIs and trends for leadership. Focus on key metrics and period-over-period comparisons.
### Operational Dashboard
Real-time metrics for day-to-day operations. Include drill-downs and detailed filters.
### Analytics Dashboard
Comprehensive analysis with multiple dimensions. Support ad-hoc exploration.
### Customer Dashboard
Embed in your product to give customers insights into their data. Use row-level security for multi-tenancy.
## Report Scheduling
Schedule dashboards to be delivered via email on a recurring basis:
* Daily, weekly, or monthly cadence
* Custom recipient lists
* PDF or image format
* Include filter selections
Set up scheduled dashboard reports
## Next Steps
Build your first dashboard
Learn about metrics and visualizations
Share dashboards across workspaces
Organize dashboards into collections
# Data Apps
Source: https://docs.usedatabrain.com/getting-started/core-concepts/data-apps
Package dashboards and metrics for embedding in your application
## What is a Data App?
A Data App is a configured package of dashboards and metrics ready for embedding into your application. It acts as the bridge between your DataBrain workspace and your external application, managing authentication, permissions, and access control for embedded analytics.
## Why Use Data Apps?
Pre-configured for easy integration into your app
Manage who can see what with built-in security
Generate tokens for secure communication
Support multiple customers with data isolation
## Key Components
### Dashboards & Metrics
Select which dashboards and metrics from your workspace should be available in the Data App.
### API Token
Each Data App has a unique API token used to generate guest tokens for end users.
### Embed Configuration
Settings that control how embedded components behave and what features are available.
### Client Access
Define which clients (customers/users) can access the Data App and their data.
## Creating a Data App
Go to the Data section in your workspace and click "Data Apps"
Click "New Data App" and provide a name
Choose which dashboards to include in the Data App
Set up permissions, multi-tenancy, and other options
Copy your API token for use in generating guest tokens
Detailed guide on creating Data Apps
## Data App Settings
Data Apps share the same embed settings as workspace-level embed settings. Access these from the Data App settings sidebar:
### Embed Settings
* **API Token**: Generate and manage API tokens for the Data App
* **Theme Settings**: Configure UI theming for embedded dashboards
* **Email Settings**: Configure scheduled email report settings
* **Preview Settings**: Configure demo/preview configuration
* **Whitelist Domains**: Manage allowed domains for embedding
### Integration Settings
For specific Data App types (e.g., MS Teams, Slack), additional integration-specific settings are available:
* **MS Teams**: Configure Teams-specific integration fields
* **Slack**: Connect Slack workspace and select channels
## API Token Management
The API token is used to authenticate requests from your backend to generate guest tokens.
**Never expose your API token in frontend code.** Always generate guest tokens from your backend server.
### Token Best Practices
* Store tokens securely (environment variables, secrets manager)
* Rotate tokens periodically
* Use different tokens for development and production
* Monitor token usage
Learn about API token management
## Guest Token Generation
Guest tokens are temporary tokens that give end users access to your embedded dashboards.
### How It Works
**Token Flow:**
```
1. User logs into your app
↓
2. Your app requests guest token from your backend
↓
3. Your backend → DataBrain API (POST /guest-token/create)
↓
4. DataBrain API → Your backend (returns guest token)
↓
5. Your backend → Your app (returns guest token)
↓
6. Your app → Embedded component (passes token)
↓
7. Embedded component → DataBrain (loads dashboard)
```
### Generate Guest Token
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/guest-token/create \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "user-123",
"dataAppName": "my-data-app"
}'
```
Complete guest token API reference
## Multi-Tenancy
Data Apps support multi-tenant architectures where each customer sees only their own data.
### Row-Level Security (RLS)
Filter data automatically based on the client ID:
```json theme={"dark"}
{
"clientId": "customer-456",
"dataAppName": "analytics-app",
"params": {
"rlsSettings": [{
"metricId": "sales-metric",
"values": {
"customer_id": "customer-456"
}
}]
}
}
```
### Client Isolation
Each client gets a unique view of the data with automatic filtering applied.
Implement multi-tenancy in your app
## Embedding Workflow
Set up your Data App in the DataBrain platform
Copy your API token from the Data App settings
```bash theme={"dark"}
npm install @databrainhq/plugin
```
Create guest tokens from your backend for each user
```html theme={"dark"}
```
## Permissions & Features
Control what embedded users can do:
### Metric Permissions
* Archive metrics
* Download metrics
* View underlying data
* Edit metrics
* Create new metrics
### Dashboard Permissions
* Customize layout
* Manage metrics
* Create dashboard views
* Download dashboards
### UI Options
* Show/hide sidebar
* Show/hide dashboard name
* Show/hide filters
* Enable full-screen mode
Complete list of permission options
## Use Cases
### SaaS Analytics
Embed customer-specific dashboards in your SaaS product. Each customer sees only their data.
### White-Label BI
Provide fully branded analytics to your clients under your brand.
### Internal Tools
Build custom internal dashboards for your team with controlled access.
### Partner Portals
Give partners access to relevant metrics and reports through embedded dashboards.
## Advanced Configuration
### Custom Filters
Pre-apply filters based on user context:
```json theme={"dark"}
{
"params": {
"dashboardAppFilters": [{
"dashboardId": "sales-dashboard",
"values": {
"region": "North America",
"date_range": {
"startDate": "2024-01-01",
"endDate": "2024-12-31"
}
}
}]
}
}
```
### Dynamic Data Sources
Switch data sources based on the client:
```json theme={"dark"}
{
"clientId": "customer-123",
"dataAppName": "analytics-app",
"datasourceName": "customer-123-db"
}
```
## Monitoring & Analytics
Track usage of your Data App:
* Active users
* Most viewed dashboards
* Query performance
* Error rates
* Token generation frequency
## Best Practices
Always generate guest tokens server-side. Never expose API tokens in client code.
Use appropriate expiry times for guest tokens. Short-lived tokens are more secure.
Verify that RLS and data isolation work correctly for different client IDs.
Track query performance and optimize slow dashboards.
Maintain separate Data Apps for development, staging, and production.
## Next Steps
Set up your first Data App
Learn how to embed dashboards
API reference for token generation
Explore embedding patterns
# Datamarts
Source: https://docs.usedatabrain.com/getting-started/core-concepts/datamarts
Create optimized data models for analytics and AI-powered insights
## What is a Datamart?
A Datamart is a curated, optimized subset of your data specifically designed for analytics and AI-powered queries. It sits between your raw data and your dashboards / AI layer, providing a clean, query-ready model that is easy for both humans and AI to work with.
## Why Use Datamarts?
Optimized tables and columns for lightning-fast analytics
Structured for natural language queries and AI insights
Business-friendly data model hiding technical complexity
Single source of truth for key business metrics
## Creating a Datamart
Provide a name and select a datasource. Each datamart connects to a single datasource.
Choose which tables from the schema to include in your datamart. You can select tables from different schemas within the same datasource.
Select which columns to include from the selected tables. Preview table data and configure column visibility.
Set up multi-tenancy settings:
* **Table-level tenancy**: Select a table with primary key and client name columns
* **Database-level tenancy**: Use separate databases per tenant
* **Multi-database tenancy**: Use multiple databases (MSSQL only)
After creation, add business-friendly names, descriptions, and relationships in the Datamart Description page.
Step-by-step datamart creation guide
## Key Features
### Tables
Select tables from your datasource:
* Choose tables from available schemas
* Preview table data before including
* Select multiple tables from different schemas
* Hide tables that aren't needed
### Columns
Configure which columns to include:
* Select specific columns from each table
* Hide unnecessary columns
* Preview column data
* Configure column visibility
### Tenancy Configuration
Set up multi-tenancy (optional):
* Table-level tenancy with primary key and client columns
* Database-level tenancy for complete isolation
* Multi-database tenancy (MSSQL only)
### Relationships
Define relationships between tables (configured after creation):
* One-to-many relationships
* Many-to-many relationships
* Self-referential joins
* Configure join types and cardinality
### Metadata & Descriptions
Add context to make your datamart analytics- and AI-ready (configured after creation):
* Table descriptions
* Column descriptions and labels
* Business-friendly aliases
* Example questions for downstream AI experiences
## Datamart Structure
Each datamart connects to a single datasource. Within that datasource, you can:
* Select tables from multiple schemas
* Configure columns from selected tables
* Define relationships between tables
* Set up multi-tenancy at table, database, or multi-database level
Learn about semantic layer capabilities
## Tenancy & Multi-Tenancy
Datamarts support multi-tenant architectures for data isolation:
### Tenancy Levels
**Table-Level Tenancy**
* Select a table with primary key and client name columns
* Data is filtered automatically based on client ID
* Suitable for single-database multi-tenant setups
**Database-Level Tenancy**
* Use separate databases per tenant
* Each tenant's data is completely isolated
* Automatically routes queries to the correct database
**Multi-Database Tenancy** (MSSQL only)
* Use multiple databases for tenant isolation
* Supports complex multi-tenant architectures
* Configure schema lists per tenant
### Access Control
Datamart access is controlled through workspace permissions:
* View, Create, Edit, Delete permissions
* Edit Tenancy permission for configuring multi-tenancy
## Use Cases
### AI-Powered Analytics
Enable business users to ask questions in natural language (powered by the semantic layer you configure later):
* "Top customers by revenue"
* "Sales trends last quarter"
* "Compare regions"
### Consistent Metrics
Ensure everyone uses the same definitions:
* Standard KPI calculations
* Consistent aggregations
* Unified dimensions
### Fast Dashboards
Power dashboards with optimized data models:
* Selected tables and columns for faster queries
* Clear relationships between tables
* Multi-tenant data isolation
### Multi-Tenant Applications
Enable data isolation for SaaS applications:
* Table-level tenancy for single-database setups
* Database-level tenancy for complete isolation
* Multi-database tenancy for complex architectures
## Best Practices
Begin with core tables and metrics. Expand the datamart gradually as needs grow.
Name fields and tables using terms your business users understand, not technical jargon.
Add descriptions to all fields. This helps both dashboard users and AI understand your data.
Model your datamart around your most frequent query patterns.
Set up regular updates to ensure datamart data is current.
## Datamart vs. Data Warehouse
| Aspect | Datamart | Data Warehouse |
| --------------- | ---------------------------- | ------------------------- |
| **Scope** | Focused on specific use case | Enterprise-wide data |
| **Purpose** | Analytics & AI queries | Source of truth storage |
| **Schema** | Denormalized, optimized | Normalized, comprehensive |
| **Users** | Business analysts, AI | Data engineers, analysts |
| **Performance** | Optimized for reads | Balanced read/write |
## Datamart Features
### Table & Column Management
* Select tables from schemas within your datasource
* Configure which columns are visible
* Preview table data before including
* Hide tables or columns as needed
### Relationships
* Define relationships between tables in your datamart
* Configure cardinality and join types
### Metadata & Descriptions
* Table descriptions
* Column descriptions and labels
* Business-friendly aliases
## Datamart API
Manage datamarts programmatically through the Data App API:
### List Datamarts
```bash theme={"dark"}
curl --request GET \
--url https://api.usedatabrain.com/api/v2/datamarts \
--header 'Authorization: Bearer YOUR_API_TOKEN'
```
### Create Datamart
```bash theme={"dark"}
curl --request POST \
--url https://api.usedatabrain.com/api/v2/datamarts \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"name": "Sales Datamart",
"datasourceId": "your-datasource-id"
}'
```
### Update Datamart
```bash theme={"dark"}
curl --request PUT \
--url https://api.usedatabrain.com/api/v2/datamarts \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"id": "your-datamart-id",
"name": "Updated Name"
}'
```
Complete Data App API reference
***
## Semantic Layer & AI Chat
The semantic layer and AI chat features are built **on top of** your datamart. Once your datamart is created, you configure the semantic layer to make it AI-friendly.
### Semantic Layer Basics
The semantic layer translates technical data structures into business concepts.
#### Business Names
```text theme={"dark"}
customer_acq_date → Customer Acquisition Date
mrr → Monthly Recurring Revenue
cac → Customer Acquisition Cost
```
#### Descriptions
Add helpful descriptions that appear in AI responses and tooltips:
* What the metric or column measures
* How it's calculated
* When to use it
* Known limitations
#### Data Types
Define appropriate data types:
* Dimensions (categories)
* Measures (numeric values)
* Dates and times
* Text and strings
### AI Chat Mode Integration
Datamarts power AI chat mode, enabling natural language analytics.
#### How It Works
1. **User asks a question** – e.g. "What were total sales last month?"
2. **AI understands intent** – uses datamart metadata and semantic layer to interpret the question
3. **Generate SQL** – creates an optimized query based on the datamart structure
4. **Return results** – displays data with a natural language explanation
#### LLM Configuration
Connect your preferred LLM:
* OpenAI GPT
* Claude AI
* Azure OpenAI
* Llama
* Mixtral
Configure AI models for chat mode
### Datamart Management for Semantic Layer
Once the datamart exists, you configure the semantic layer and examples from the Semantic Layer and Datamart Description pages.
#### Datamart Description
Add metadata and context to your datamart:
* **Table Descriptions**: Add business-friendly descriptions for tables
* **Column Descriptions**: Document what each column represents
* **Relationships**: Define relationships between tables
* **Examples**: Add example questions for AI chat mode
* **Synonyms**: Configure column synonyms for better AI understanding
#### Semantic Layer Tools
* **Lab**: Generate and test synthetic queries
* **Playground**: Test natural language questions against the datamart
* **Sample Set**: Configure sample data for AI training and evaluation
### Best Practices for Semantic Layer
Use the same terms your business stakeholders use in meetings and reports.
Test the semantic layer using real questions from users and refine names, descriptions, and examples.
Regularly review and update example questions and feedback to improve AI answers over time.
## Next Steps
Build your first datamart
Set up AI-powered queries
Configure your semantic layer
Understand AI integration
# Embedding Architecture
Source: https://docs.usedatabrain.com/getting-started/core-concepts/embedding-architecture
Understanding DataBrain's embedding architecture and how it works
**At a Glance:** DataBrain uses a stateless token-based architecture that enables secure, multi-tenant embedded analytics. This guide explains the core concepts and architecture patterns.
## How Embedding Works
DataBrain's embedding architecture is built on five core components that work together to deliver secure, real-time analytics:
Your frontend and backend where dashboards are embedded
Analytics engine that processes queries and renders visualizations
Your production database or data warehouse (your data never leaves)
Stateless authentication for secure, multi-tenant access
***
## Architecture Flow
### Cloud Deployment
When using DataBrain Cloud, the platform hosts the analytics engine while securely connecting to your database:
Your user authenticates with your application
Your backend requests a guest token from DataBrain API with user context
Your frontend receives the token and embeds the DataBrain component
DataBrain queries your database directly and streams results to the embedded component
**Data Security:** Your data never passes through DataBrain's storage. Queries execute directly against your database, and results stream to the end user.
### Self-Hosted Deployment
With self-hosted deployment, you run the entire DataBrain platform in your own infrastructure:
* **Complete control** over data and infrastructure
* **Network isolation** - everything stays within your VPC
* **Custom deployment** options (single server, HA, multi-region)
* **Air-gapped** support for isolated environments
***
## Key Architecture Concepts
### Stateless Guest Tokens
DataBrain uses stateless tokens instead of traditional user authentication:
**Benefits:**
* ✅ No user data storage - complete privacy
* ✅ No SSO setup required - integrate in minutes
* ✅ Multi-tenant isolation built-in
* ✅ Automatic expiration for security
* ✅ Opaque server-side tokens — nothing to forge or decode client-side
**How it works:**
```javascript theme={"dark"}
// Your backend generates a token
const token = await fetch('https://api.usedatabrain.com/api/v2/guest-token/create', {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
body: JSON.stringify({
clientId: 'customer-123',
dataAppName: 'analytics-app'
})
});
// Your frontend embeds with the token
```
### Multi-Tenant Data Isolation
DataBrain supports N-level tenancy hierarchy (industry-unique):
Route different customers to completely different database servers. Perfect for dedicated database per enterprise customer.
Switch databases based on tenant within the same database server.
Isolate tenants in separate schemas within the same database.
Apply row-level security filters to ensure users only see their data.
```sql theme={"dark"}
-- Example RLS rule
SELECT * FROM orders WHERE customer_id = '{clientId}'
```
### Real-Time Query Execution
1. User interacts with embedded dashboard
2. Component sends authenticated request
3. DataBrain validates token and permissions
4. Generates optimized SQL with RLS applied
5. Executes directly against your database
6. Streams results back to user
**No data copying** - queries run in real-time against your live database.
**Built-in optimizations:**
* Query caching for frequently accessed data
* Connection pooling to your database
* Automatic query optimization
* Result streaming for large datasets
* CDN delivery for frontend assets
**Security at every layer:**
* Encrypted database connections (SSL/TLS)
* Row-level security enforcement
* Token expiration and validation
* Domain whitelisting
* Audit logging
***
## Deployment Options
### Cloud vs Self-Hosted
Choose the deployment that fits your needs:
**Best for:**
* Fast time-to-market
* Minimal DevOps resources
* Automatic updates
* Built-in scalability
**How it works:**
* DataBrain hosts the platform
* Connects securely to your database
* 99.9% uptime SLA
* Auto-scaling included
**Security:**
* VPC peering available (AWS)
* IP whitelisting
* SOC 2, ISO 27001, GDPR compliant
* Encrypted connections (TLS 1.2+)
**Best for:**
* Strict data sovereignty requirements
* Air-gapped environments
* Complete infrastructure control
* Custom compliance needs
**How it works:**
* Deploy in your infrastructure
* Full network isolation
* Custom deployment patterns
* Your security controls
**Infrastructure:**
* Docker, Kubernetes, or VMs
* PostgreSQL + Redis required
* Scales horizontally
* High-availability options
***
## Security & Compliance
### Data Protection
**At Rest:** AES-256 encryption for credentials
**In Transit:** TLS 1.2+ for all connections
**Passwords:** One-way hashing, never stored
**Token-based:** Stateless guest tokens
**Row-Level:** Automatic RLS enforcement
**Permissions:** Fine-grained access control
**VPC Peering:** Private connections (AWS)
**IP Whitelist:** Restrict access by IP
**Domain Whitelist:** Control embedding domains
**SOC 2 Type II:** Security audits
**ISO 27001:** Information security
**GDPR & HIPAA:** Data protection
### Best Practices
* Store API keys in environment variables
* Never expose keys in frontend code
* Rotate keys periodically
* Use separate keys per environment
* Set reasonable expiration times (1-24 hours)
* Refresh tokens before expiration
* Shorter expiry = better security
* Include RLS rules in token generation
* Whitelist only necessary domains
* Remove development domains in production
* Always use HTTPS in production
* Review whitelist regularly
***
## When to Use What
**Choose when:**
* You want fast deployment
* You have limited DevOps resources
* You need automatic scaling
* You want managed infrastructure
**Examples:**
* SaaS startups
* Small to medium businesses
* Teams without dedicated DevOps
**Choose when:**
* You have strict data residency requirements
* You need complete infrastructure control
* You operate in air-gapped environments
* You have specific compliance needs
**Examples:**
* Financial institutions
* Healthcare organizations
* Government agencies
* Large enterprises
***
## Next Steps
Get your first dashboard embedded in 5 minutes
Complete production deployment guide
Detailed technical architecture and implementation
Comprehensive security documentation
***
## Common Questions
No. DataBrain only stores metadata like dashboard configurations and metric definitions. Your actual data stays in your database. Queries execute in real-time against your database.
DataBrain supports 4-level tenancy: datasource, database, schema, and row-level. You can route users to different databases or apply row-level security filters - whatever matches your architecture.
**Cloud:** 99.9% uptime SLA with automatic failover and redundancy.
**Self-hosted:** Availability depends on your infrastructure. You can deploy with high-availability configurations.
Yes! DataBrain supports multi-datasource workspaces. You can route different customers to different databases, even across different database types.
Tokens are opaque UUIDs issued and stored server-side — there is nothing to decode or forge client-side, and there is no signing key to manage. They're validated against the server on every request, can be configured to expire, and include origin checking to prevent unauthorized use.
# Metrics
Source: https://docs.usedatabrain.com/getting-started/core-concepts/metrics
Build individual visualizations and KPIs to power your dashboards
## What is a Metric?
A metric is an individual visualization or KPI that displays data from your connected data sources. Metrics are the building blocks of dashboards - they can be charts, tables, single-value cards, or other visual representations of your data.
## Types of Charts
Bar, line, pie, area, scatter, and more
Data grids with sorting and pagination
KPIs with trend indicators
Progress and goal tracking
Conversion & flow analysis
Location-based visualizations
## Creating Metrics
DataBrain offers multiple ways to create metrics:
### Visual Builder
Drag-and-drop interface for building metrics without SQL. Select dimensions, measures, and apply transformations visually.
### Custom SQL
Write your own SQL queries for complete control over the data. Perfect for complex transformations and calculations.
### AI Chat Mode
Describe what you want in natural language, and let AI generate the metric for you. "Show me revenue by region for the last quarter"
Step-by-step guide to creating metrics
## Chart Types
DataBrain supports 20+ chart types:
* **Bar Chart** - Compare values across categories
* **Line Chart** - Show trends over time
* **Pie Chart** - Display proportions
* **Area Chart** - Visualize cumulative trends
* **Scatter Plot** - Show correlation
* **Combo Chart** - Mix bars and lines
* **Stacked Bar** - Show composition
* **Waterfall** - Visualize sequential changes
* **Funnel** - Display conversion rates
* **Sankey** - Flow diagrams
* **Table** - Data grid with sorting
* **Pivot Table** - Multi-dimensional analysis
* **Single Value** - KPI card
* **Gauge** - Progress indicator
## Metric Filters
Add filters to control what data appears in your metric:
### Static Filters
Fixed conditions applied to the metric query.
Option Types include:
1. Auto Filter - Automatically fetches values from a selected database column.
2. Manual Filter - Allows custom value labels in the frontend while using database values for filtering.
3. Range Filter - Filters data based on a specified range.
4. Date Filter - Filters data by a single date or a date range.
### Variable Filters
Dynamic filters that users can modify. Great for interactive dashboards.\
[Learn more about variable filters →](https://docs.usedatabrain.com/guides/metric/apply-metric-filter/metric-filter-variable)
### Custom SQL Filters
Advanced filtering using custom SQL expressions.
[Learn more about custom SQL filters →](https://docs.usedatabrain.com/guides/metric/apply-metric-filter/metric-filter-custom)
## Customization & Styling
### Chart Appearance
* Colors and palettes
* Fonts and text sizing
* Axis labels and formatting
* Legend position
* Grid lines and ticks
Customize chart styling and appearance
### Metric Actions
Configure what happens when users interact with your metrics:
#### Click Actions
* Drill down to detailed data
* Navigate to other dashboards
* Open custom URLs
* Apply filters to other metrics
#### Drill Down
Create hierarchical exploration paths. Click on a region to see cities, click a city to see stores.
#### Cross-Dashboard Drill Down
Navigate to related dashboards while preserving filter context.
Configure interactive chart actions
## Advanced Features
### Custom Columns
Create calculated fields using formulas and functions. No SQL required.
```
Revenue Per Customer = Total Revenue / Customer Count
```
### Metric Expressions
Build complex KPIs with custom expressions for single-value cards.
```
((Current Month - Previous Month) / Previous Month) * 100
```
### AI Summary
Generate natural language summaries of metric data automatically.
### Dynamic Properties
Create conditional formatting and styling based on data values.
Add conditional formatting to metrics
## Metric Management
### Organize Metrics
* Archive unused metrics
* Tag and categorize
* Search and filter
* View unpublished drafts
### Share & Export
* Download as images (PNG, JPEG)
* Export underlying data (CSV, Excel)
* Share specific metrics
* Embed individual metrics
### Version Control
* Track metric changes
* Restore previous versions
* View edit history
Learn how to edit and manage metrics
## Embedding Metrics
Embed individual metrics into your application:
```html theme={"dark"}
```
Embedded metrics support:
* Custom styling
* Event handlers
* Responsive sizing
* Filter controls
Developer guide for embedding metrics
## Best Practices
Match your chart type to your data and message. Use bars for comparisons, lines for trends, pies for proportions.
Don't overcrowd charts. Focus on the key message and remove unnecessary elements.
Write clear, descriptive titles that tell users what they're looking at.
Include footnotes, descriptions, and tooltips to help users interpret the data.
Limit data points, use aggregations, and apply filters to keep queries fast.
## Performance Tips
* **Use Aggregations** - Pre-aggregate data in your queries
* **Apply Filters** - Limit the data range with date filters
* **Leverage Caching** - Enable query result caching
* **Optimize SQL** - Write efficient custom SQL queries
* **Limit Rows** - Set reasonable row limits for tables
## Next Steps
Build a metric step-by-step
Use AI to generate metrics
Write custom SQL queries
Customize metric styling
# Workspaces
Source: https://docs.usedatabrain.com/getting-started/core-concepts/workspaces
Organize your analytics projects with workspaces
## What is a Workspace?
A workspace is a container for organizing your analytics assets. Think of it as a project or environment where you create dashboards, metrics, and manage data connections. Each workspace is isolated, allowing you to separate different projects, clients, or environments.
## Key Features
Each workspace has its own data sources and access controls
Invite team members and control their permissions
Connect multiple data sources within a single workspace
Switch between multiple datamarts on one workspace and dashboard
Configure caching, downloads, and access control per workspace
## Workspace Types
### Standard Workspace
A standard workspace is visible to all organization members (based on permissions). Use this for team-wide analytics projects.
**Best for:**
* Shared team dashboards
* Department-level analytics
* Cross-functional reporting
### Private Workspace
A private workspace is only accessible to its creator and explicitly invited members. Perfect for personal or sensitive projects.
**Best for:**
* Personal analytics projects
* Client-specific dashboards (draft mode)
* Sensitive data analysis
Learn how to create workspaces in our [Create a Workspace](/guides/onboarding-and-configuration/create-a-workspace) guide.
## Workspace Components
A workspace contains several key components:
Create collections of metrics and visualizations
Individual charts, tables, and KPIs
## Workspace Settings
Each workspace has configurable settings to control behavior and access:
### General Settings
* **Workspace name**: Edit the workspace name
* **Creator Settings**: Choose creation mode:
* **Power Mode**: Drag-and-drop functionality or custom queries. Select **Data Source** from dropdown.
* **Chat Mode**: Keyword-based search. Select preferred **Datamart**.
* **LLM Settings**: Choose LLM for Chat Mode and Metric Summary. Enable **Metric Suggestions**.
* **Theme Settings**: Set workspace themes
### Access Control Settings
* Configure permissions for end users:
* Metric Creation, Deletion, Updation
* Manage Metrics
* Change Dashboard Layout
* Schedule Email Reports
* Underlying Data access
* Choose between Power Mode and Chat Mode for users
### Cache Settings
* Query result caching
* Cache duration (in seconds)
* Cache host and port configuration
* Access key/AUTH token
* Databrain Caching option
### Download Settings
* Enable/disable download via email
* Control users' ability to download raw data
Learn more about workspace settings configuration
## Multi-Datasource Workspaces
DataBrain supports connecting multiple data sources to a single workspace. This enables cross-database analytics and unified reporting.
**Benefits:**
* Combine data from different sources
* Create unified dashboards
* Reduce data silos
* Flexible data modeling
Learn about multi-datasource workspace setup
## Best Practices
Create separate workspaces for different projects or clients to maintain clear boundaries and access control.
Name your workspaces clearly to make them easy to identify. Include project names, client names, or environment indicators.
Configure permissions and access control when creating the workspace to prevent security issues later.
Archive or delete unused workspaces to keep your organization tidy and reduce clutter.
## Common Use Cases
### SaaS Product Analytics
Create workspaces for different customer segments or product areas. Use multi-tenancy to isolate customer data.
### Internal BI
Set up workspaces for each department (Sales, Marketing, Finance) with appropriate data sources and access controls.
### Client Reporting
Create dedicated workspaces for each client with their specific data connections and custom dashboards.
### Development & Production
Maintain separate workspaces for development, staging, and production environments.
## Next Steps
Step-by-step guide to creating a workspace
Add data sources to your workspace
Understand dashboard concepts
Learn about metrics and visualizations
# Dashboard Customization
Source: https://docs.usedatabrain.com/getting-started/dashboard-customization
Learn how to customize your dashboard layout, add new elements, and manage metrics in Databrain.
## Prerequisites
* A **Workspace** with at least one existing **Dashboard**
* Metrics already added to the **Dashboard**
## Open the Dashboard
Navigate to the **Dashboard** you want to customize within your workspace.
*Watch the video below for a quick walkthrough.*
## 1. Customize Layout
* Click the **“Dashboard Settings”** icon and select **“Customize Layout”** option.
* Once in customize mode, you can freely rearrange dashboard elements. Click and drag charts or tiles to reposition them on the grid layout. Adjust the size of each component by dragging its borders.
* (Optional) Use the **“Adjust Spacing”** option to ensure proper spacing between elements.
* Click **“Save Layout”** once you’re done to preserve your updated arrangement.
**Reference:**\
[Customize Layout](https://docs.usedatabrain.com/guides/dashboards/customize-layout#customize-layout)
More reference to customize layout:\
[Merge Metrics](https://docs.usedatabrain.com/guides/metric/merge-metrics)
## 2. Adding Elements
* Click on the **“+ Elements”** option near the + Metric button.
* Choose the element type:
* **Custom Text Box:** Section separators to group relevant metrics under distinct categories
* **Metric Summary:** Automatically generate AI-powered summaries of selected metrics
* **Metric Expression:** Create custom calculations for Single-Value Card elements
* Configure the properties of the element and click on **“Save”**.
**Reference:**\
[Adding Elements to Dashboard](https://docs.usedatabrain.com/guides/dashboards/adding-elements-to-dashboard#adding-elements-to-dashboard)
## 3. Manage Metrics
* Click on the **“Dashboard Settings”** icon and click on the **“Manage Metrics”** option.
* Check or Uncheck the metrics to include or remove them from the dashboard.
* If unchecked, the metrics will appear as **Unpublished Metrics**.
**References:**\
[Manage Metrics](https://docs.usedatabrain.com/guides/dashboards/dashboard-settings),[View Unpublished Metrics](https://docs.usedatabrain.com/guides/metric/view-unpublished-metrics#view-unpublished-metrics)
You’ve successfully customized your dashboard in Databrain!
With layout customization, flexible elements, and metric management, you can build personalized dashboards that fit your team’s reporting needs.
# Welcome to DataBrain
Source: https://docs.usedatabrain.com/getting-started/introduction
Embed powerful analytics dashboards into your application in minutes
## What is DataBrain?
DataBrain is a powerful embedded analytics platform that enables you to integrate beautiful, interactive dashboards and metrics into your application with minimal code. Whether you're building a SaaS platform, internal tool, or customer-facing analytics, DataBrain provides the infrastructure and components you need.
Learn how DataBrain helps you build and manage analytics dashboards
Get started embedding DataBrain into your application
Complete guide to using the DataBrain platform
Comprehensive API documentation for developers
## Why Choose DataBrain?
Embed dashboards and metrics with just a few lines of code. Our NPM package works seamlessly with React, Vue, Angular, and more.
Match your brand with extensive theming options. Customize colors, layouts, and component behavior.
Built-in multi-tenancy, row-level security, and SSO support ensure your data stays secure.
Enable natural language queries with our AI chat mode. Let users ask questions and get instant answers.
Support for 20+ chart types including bar, line, pie, scatter, heatmaps, and more.
Deploy on your infrastructure or use our cloud service. Full control over your data.
## Quick Links
Embed your first dashboard
Set up analytics with your AI assistant
Understand key concepts
React, Vue, Angular & more
## Popular Use Cases
Provide your customers with powerful analytics dashboards inside your application. Support multi-tenancy with row-level security to ensure data isolation.
**Perfect for:** B2B SaaS platforms, Multi-tenant applications
Build custom business intelligence dashboards for your team. Connect to multiple data sources and create comprehensive reporting solutions.
**Perfect for:** Data teams, Operations, Executive reporting
Give your customers insights into their data with beautiful, interactive dashboards. Customize the look and feel to match your brand.
**Perfect for:** Customer portals, Self-service analytics
Rebrand DataBrain completely to match your product. Full control over theming, domain, and user experience.
**Perfect for:** OEM partners, Resellers, Product integrations
## Getting Started Paths
**Start here if you want to:**
* Create dashboards and metrics
* Connect data sources
* Build reports
* Manage workspaces
[Go to Platform Guides →](/guides/onboarding-and-configuration/sign-up)
**Start here if you want to:**
* Embed dashboards in your app
* Use the NPM package or MCP server
* Integrate with your codebase
* Set up analytics via AI assistant
[Go to Developer Docs →](/developer-docs) | [Try MCP Server →](/developer-docs/mcp-server/overview)
## What You'll Learn
Learn about workspaces, dashboards, metrics, data apps, and datamarts
Connect to databases, warehouses, or upload CSV files
Create interactive dashboards with drag-and-drop simplicity
Integrate DataBrain into your application with our developer tools
## Community & Support
Comprehensive guides and API references
Latest updates, tutorials, and best practices
Try DataBrain components live
Get help from our team
## Ready to Get Started?
Create your free account and start building dashboards
Follow our 5-minute embedding tutorial
# Invite Users
Source: https://docs.usedatabrain.com/getting-started/invite-users
Learn how to configure invite users in both app and self-hosted environments.
# App Environment
In the app environment, an admin can invite users with or without configuring email settings. In both cases, the invited user will receive an email notification with a secure login link.
**If email settings are configured:**\
The invitation email will be sent using your configured email service.
**If email settings are not configured:**\
Databrain will automatically send the invitation email.
***
# Self-Hosted Environment
In a self-hosted environment, the admin must configure email settings before inviting users. This ensures that invitation emails are delivered successfully.
* Navigate to the **Settings** page.
* In the **Embed Settings** section, configure the required email settings.
* Click **Authenticate** to save and validate the configuration.
***
# Inviting a User
1. Navigate to the **Invite User** section.
2. Enter the user’s email address.
3. Assign a role — Developer, Editor, or Viewer — and select the workspaces the user should have access to.
4. Click **Invite** to complete the process.
***
# Accept Invitation (Invited User)
The invited user will receive an email containing a login link. By clicking the link, they can log in and access their Databrain account.
Once the invited user has accepted the invitation, you can view the list of users in **Settings → Users**.
# Metric Customization
Source: https://docs.usedatabrain.com/getting-started/metric-creation
Learn how to customize metrics in DataBrain dashboards by switching axes, grouping data, drilling down, and configuring chart click actions.
## Prerequisites
Before you start customizing metrics, ensure you have:
* Access to the **Databrain App**
* A **Workspace** with at least one **Dashboard**
* Metrics already added to the **Dashboard**
## Access the Dashboard
* Log in to your **Databrain Workspace**.
* Open the desired **Dashboard** containing the metric you want to customize.
## 1. Switch X-Axis, Group By, Switch Y-Axis, and Drill Down
*Watch the video below for a quick walkthrough.*
### Switch X-Axis
* Click on the **“Settings”** icon.
* In the **“Actions”** menu, turn on the **“Switch X Axis”** toggle in the **“Add Actions On Current Card”** dropdown.
* Select a different dimension (e.g., *Date*, *Region*, or *Product*).
* The chart automatically updates to reflect your new X-Axis selection.
### Group By
* Click on the **“+”** icon above the chart.
* Within the Group By menu, choose the dimension by which you want to group data (e.g., *Sales Rep*, *Category*, *Channel*).
* The chart reorganizes and aggregates the metric by your chosen group.
### Switch Y-Axis
* Click on the **“Settings”** icon.
* In the **“Actions”** menu, turn on the **“Switch Y Axis”** toggle in the **“Add Actions On Current Card”** dropdown.
* Pick a different metric (e.g., *Revenue*, *Orders*, *Profit Margin*).
* The visualization refreshes instantly, displaying the new measure along the Y-Axis.
### Drill Down
* Click on the **“Settings”** icon.
* In the **“Actions”** menu, turn on the **“Drill down”** toggle in the **“Add Actions On Current Card”** dropdown.
* Add fields in hierarchical order — for example:
* Level 1: Region
* Level 2: Country
* Level 3: City
* Save the configuration.
* Once defined, this hierarchy allows users to interactively explore lower levels of data.
* The chart updates dynamically to show the drilled-down data.
**References:**\
[Switch X axis and Switch Y axis](https://docs.usedatabrain.com/guides/metric/switch-x-axis-and-switch-y-axis#switch-x-axis-and-switch-y-axis), [Group By](https://docs.usedatabrain.com/guides/metric/group-by#group-by),[Drill Down](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/drill-down#drill-down)
## 2. Chart Click Action
* Click on the **“Settings”** icon.
* In the **“Actions”** menu, turn on the **“Chart Click Actions”** toggle.
* Choose what should happen when a user clicks a chart element:
* **Apply Filter:** Automatically filter the dashboard based on the clicked value (e.g., region, category).
* **Open Dashboard:** Redirect users to another linked dashboard or detailed report.
* **Open External Link:** Navigate to an external URL (e.g., CRM page or analytics view).
* Click **Save** to apply the configuration.
*Watch the video below for a quick walkthrough.*
**Reference:**\
[Chart Click Action](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/chart-click-action#chart-click-action)
More references on chart actions:\
[Chart Click Action with metric](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/chart-click-action-with-metric), [Card Click Action](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/card-click-action)
You’ve successfully customized metrics in Databrain!
With these options, users can interactively adjust dimensions, measures, and interactions to create a more flexible, self-serve analytical experience within any dashboard.
# Adding Elements to Dashboard
Source: https://docs.usedatabrain.com/guides/dashboards/adding-elements-to-dashboard
This guide provides a straightforward approach to enhancing your dashboard by adding new elements, which can improve data visualization and user engagement.
### 1. Access Elements Creation
Click the **"+ Elements"** button in the top-right corner of the dashboard (next to the preview icon).
### 2. Add Elements Section
* Enter a title and description.
* Set title and description alignment (left, center, or right).
* Choose from the following element types:
* `Custom Text Box`
* `Metric Summary`
* `Metric Expression`
#### Custom Text Box:
* Enter the content in the text box and format using the toolbar.
* Optionally, toggle **"Merge Card to Background"** if you want the element to blend with the dashboard background.
* Click **"Save"** to add the element to the dashboard.
> Custom Text Box Elements can be used as section separators to group relevant metrics under distinct categories. They allow intuitive, categorized data presentation.
By using `Custom Text Box` elements as section headers, you can group and label these sections, making it easier for users to locate specific data types and enhancing the dashboard’s overall readability.
### Metric Summary:
* Select the metrics to include and enter a prompt for the summary.
* Optionally, toggle **"Merge Card to Background"** if you want the element to blend with the background.
* Click **"Save"** to add the element to the dashboard.
Learn more about how to configure Metric Summary and its use cases in Databrain.
### Metric Expression:
* Select the metrics you want to include in the **"Metric Expression"** textbox.
* Use metric IDs to perform calculations and define expressions.
* Optionally, toggle **"Merge Card to Background"** if you want the element to blend with the background.
* Click **"Save"** to add the element to the dashboard.
For more details on Metric Expression, kindly refer the below link.
You’ve successfully added elements to your dashboard.\
Your dashboard now includes enhanced summaries, expressions, and formatted text sections that improve readability, structure, and user engagement.
# Boards
Source: https://docs.usedatabrain.com/guides/dashboards/boards
Boards allow you to save multiple configurations of a dashboard based on applied dashboard metric filters, and switch axis. You can then quickly switch between these saved boards without re-applying filters every time.
## **Why Use Boards?**
* Save time by avoiding repetitive filter selections.
* Quickly switch between perspectives (e.g., different locations, time ranges, or product types).
* Share consistent dashboard states with your team.
## **Steps to Create a Board**
### **1. Open Your Dashboard**
* Navigate to the dashboard you want to work with.
### **2. Apply Filters**
* Use the filter panel to set conditions (for example: Location = “North Region”, Date Range = “Last 30 Days”).
* Confirm the dashboard updates with your selected filters.
### **3. Save as a Board**
* Open the **Dashboard Settings** dropdown and toggle **Enable Board**.
* In the **Board** dropdown, click **+ Add Board**.
* Enter a name for your board and click **Save Board**.
* Example: *"All Stores Overview"*
* **All Stores Overview** is created
### **4. Switch Between Boards**
* Open the **"Board"** dropdown to view the list of all your saved boards.
* Select a board to load it—the dashboard will automatically update with the saved filters.
### **5. Delete Boards**
* From the **Board** dropdown, you can **delete** saved boards
You’ve successfully created and managed Boards.\
Your dashboard now supports fast, filter-based switching—making analysis smoother, faster, and far more organized.
# Create/Modify Dashboard Filter
Source: https://docs.usedatabrain.com/guides/dashboards/create-modify-dashboard-filter
Dashboard filters allow for more precise data viewing and analysis within your dashboard.
> Take control of your data exploration with Databrain's powerful dashboard filters. Whether you
> need simple dropdowns, dynamic ranges, or complex SQL-based filtering, our comprehensive
> filter system puts precision data analysis at your fingertips. This guide walks you through creating
> and customizing filters that transform how you interact with your dashboards.
1. **Add Dashboard Filters:**
* Click the "+" icon to add a dashboard filter.
* Choose filter type from the dropdown menu:
* **Select**: Creates filters at the top of your dashboard
* **Switch Select**: Creates compact dropdown filters with labels in the left sidebar **"Filters"** panel
* **Other**: Creates additional filters in the left sidebar **"Filters"** panel
2. **Configuring a Filter:**
Choose the desired type of filter from the **"Option Type"** radio buttons:
* **Method 1: Auto Filter Type**\
Automatically filters based on existing database columns - best for straightforward data filtering without customization.
* **Method 2: Range Filter Type**\
Creates min-max sliding selectors - perfect for numerical data like prices, ages, or quantities.
* **Method 3: Date Filter Type**\
Handles all time-based filtering - ideal for selecting date ranges and time periods.
* **Method 4: Manual Filter Type**\
Uses predefined static options - great when you need a fixed list of specific choices.
* **Method 5: Custom Filter Type**\
Enables complex SQL-based filtering - essential when you need custom logic or calculations in your filters.
**Common Customization Options**
* **Filter Variant**: Choose between single select, multi-select, or search options
* **Choose a Unique Label Column**
* **Show Client Scoped Filter Options**
* **Auto Select Default Value**
* **Depend On**
**Method 1: Auto Filter Type**
**Method 2: Range Filter Type**
**Method 3: Date Filter Type**
**Method 4: Manual Filter Type**
* Manual filter options are entered **one by one** in the UI: for each option, enter a **Value** (the exact value used in the query) and a **Label** (what users see in the dropdown). You do not paste a full JSON structure—add options using the UI (e.g. "Add option" or similar).
**Method 5: Custom Filter Type**
3. **Apply on and Variable Filter:**
For a more detailed guide on Variable Apply On, kindly refer the below link:
Functioning of Variable Apply On method available in Dashboard Filters.
4. **Modify Dashboard Filter:**
* To modify the configurations of any dashboard filter, click on the **"Edit"** button.
* To remove a filter, select **"Delete"** filter.
Dashboard Filter created and configured successfully.
# Add LHS and RHS custom sql support for dashboard filter
Source: https://docs.usedatabrain.com/guides/dashboards/create-modify-dashboard-filter/add-lhs-and-rhs-custom-sql-support-for-dashboard-filter
This guide is essential for users looking to enhance their dashboard's filtering capabilities with custom SQL support.
### 1. Create a Dashboard Filter
Click the **'+' icon** to add a new filter and choose the **'Select'** option to configure the filter.
> **Use case:**\
> Adding LHS (Left-Hand Side) and RHS (Right-Hand Side) custom SQL allows dynamic filtering.\
> For example, you can search for product names dynamically by applying transformations in the `WHERE` clause using the `{{global_selected_values}}` variable.
### 2. Use `{{global_selected_values}}` in the "Apply on" section
Apply transformations like `CONCAT()`, `LOWER()`, and `UPPER()` in **Custom RHS SQL** using `{{global_selected_values}}`
### 3. View the Results of Custom LHS and RHS SQL
When a user searches for a product name, `{{global_selected_values}}` dynamically fetches the corresponding values, regardless of case sensitivity or type casting.
LHS and RHS custom SQL added and configured successfully.
# Dashboard Filter - Variable Apply On
Source: https://docs.usedatabrain.com/guides/dashboards/create-modify-dashboard-filter/dashboard-filter-variable-apply-on
In this page you can see the functioning of variable apply on method available in Dashboard Filters.
Using Variable Filter in Dashboard Filter with Custom SQL
### Creating a Dashboard Filter with Variable Filter:
1. Create Dashboard Filter
2. In the “Apply On” section, choose **"Variable Filter"**
3. Assign Variable Name:
* Assign a variable name, for example, `{{global_value}}` for Dashboard Filter.
* Copy the variable `{{global_value}}` for use in your custom SQL query.
### Example Use Case: Dynamic Country Population Analysis
Let's say you're building a dashboard where analysts need to quickly filter population data for different countries without modifying the underlying SQL query each time. Here's how the Dashboard Filter would be valuable:
**Purpose:**
* Allows users to dynamically select different countries to view their population data
* Eliminates the need to write separate queries for each country
* Provides a user-friendly interface for non-technical users
**Example Custom SQL Query with Variable Filter:**
* **Custom SQL you write:**
* **Custom SQL added with Variable Filter:**
Then the Generated SQL we generate would look like this:
* **Resulting SQL:**
### Working:
* Initial SQL query gets all country population data
* Variable Filter adds a WHERE clause with `{{global_value}}`
* When users select a country from the filter, it automatically updates the query
* Results are instantly filtered to show only the selected country's data
### Important: Where and how to use the variable
* **Keep the variable in the WHERE clause** of your metric's SQL. The variable name must exactly match the filter's variable name (case-sensitive), and the filter needs a value or default — if the query runs while a `{{variable}}` is still unresolved, you get: **Error: Filter or Client variables detected in the query.** There is no built-in way to display or "inspect" the current filter value in a metric, so a variable in SELECT has no supported use.
* **Single-select filter:** The variable is replaced by a single quoted value; use `WHERE column = {{var}}`.
* **Multi-select filter:** The variable is replaced by a parenthesized list of quoted values, e.g. `( 'US' , 'CA' )`; use `WHERE column IN {{var}}` — **without** your own parentheses (`IN ({{var}})` double-wraps into invalid SQL), and do not use `= {{var}}` for multi-select.
### Dashboard Result After Applying Filter with Variable Value
The metrics are filtered according to the values selected in the dashboard filter
Variable Apply-On Filter configured successfully. The filter now passes the selected value into your SQL query dynamically.
# Customize Layout
Source: https://docs.usedatabrain.com/guides/dashboards/customize-layout
Customizing the layout of metrics provides a tailored view to analyze data more effectively
### 1. Access & Enable Customized Layout Setting:
* Click on the **"Settings"** icon located near the **"Elements"** button
* From the dropdown menu, select **"Customize Layout"** option.
### 2. Adjust Metric Cards:
* With this mode enabled, all metric cards become movable.
* Drag and position them to your preferred spots.
* Adjust their sizes as needed for an optimal view.
### 3. Customize and Save:
Set the value for vertical and horizontal gap between the metrics.
Finally, click on **"Save Layout"** button to store your modifications.
You’ve successfully customized your dashboard layout.\
Your metrics are now arranged exactly the way you prefer, improving navigation and analysis efficiency.
# Dashboard Settings
Source: https://docs.usedatabrain.com/guides/dashboards/dashboard-settings
The dashboard settings offer various tools to enhance, manage, and customize your analytics experience.
1. **Navigate to Dashboard Settings**
* On the dashboard, click the **"Settings"** icon in the top right corner, next to the **"Share"** button.
* A list of drop-down options will be displayed.
2. **`>` Embed Dashboard**:
Here, you can retrieve the embeddable code or the Databrain app dashboard UI plugin, available in both React and Vue languages.
3. **Customize Layout**:
* Organize your dashboard metrics to create a personalized view.
* For more details, please refer to the link below:
Customize Layout
4. **Manage Metrics**:
* This tool lets you oversee the metric cards on the dashboard.
* From the dropdown, decide which metrics to display and which to hide. Unselected metrics are sent to the archive metric store. If needed, you can recover them later by unarchiving.
5. **Report Scheduler**
* Create, schedule, and manage automated dashboard reports with customizable delivery options to meet your reporting needs.
* For more details, please refer to the link below:
6. **Rules Builder**\
Users can now hide or unhide metrics based on selected charts.
7. **Download Metrics**\
Users can now download the underlying data for all metrics with just one click.
8. **Boards**\
Users can now create multiple views of a dashboard based on applied dashboard filters and easily switch between them. For more details, please refer to the link below:\
[https://docs.usedatabrain.com/guides/dashboards/boards#boards](https://docs.usedatabrain.com/guides/dashboards/boards#boards)
Report Scheduler
You’ve successfully reviewed Dashboard Settings. All core management tools—layout customization, metric controls, rules, reports, and embedding—are now configured for a tailored dashboard experience.
# Edit a Dashboard
Source: https://docs.usedatabrain.com/guides/dashboards/edit-a-dashboard
This guide provides essential instructions for efficiently managing your dashboard, allowing you to customize it to better suit your needs.
1. Navigate to the dashboard you want to edit.
2. **Managing Dashboards**:
* Click on the three-dot icon next to the dashboard name to access options to **"Rename"**, **"Export"** or **"Delete"** your dashboard
* Use the **"Move to"** option to transfer your dashboard to another workspace.
* Check the box to **keep a copy** of the dashboard in the current or testing workspace, if needed.
Dashboard update completed. Your dashboard configuration changes are now applied and ready for use.
# Import/Export Dashboard
Source: https://docs.usedatabrain.com/guides/dashboards/import-export-dashboard
This guide provides clear instructions for importing and exporting dashboards, offering two methods to streamline your workflow.
You can also export and import dashboards programmatically via the Data App APIs: [Export Dashboard](/developer-docs/helpers/api-reference/export-dashboard) and [Import Dashboard](/developer-docs/helpers/api-reference/import-dashboard).
## Method 1: Export Dashboard and Import External Dashboard
* Navigate to the **Dashboards** section in the **Home** page.
* Find the dashboard you want to export.
* Click the vertical three dots (⋮) menu button on the right side of the dashboard row.
* Select **Export** from the dropdown menu.
* The dashboard will be automatically downloaded as a JSON file.
A prompt saying **Downloaded Exported Dashboard** will be displayed.
* On the **Home** page, click the **dropdown** icon next to the **"+ Dashboard"** button.
* Choose the dashboard to import by either dragging and dropping the JSON file or selecting it from your file system.
* *(Optional)* Configure Schema Mapping:
* Enter the target schema name
* Click **Replace Schema** if needed
* Use the (+) button to add additional schema mappings
* Click the **Import** button to complete the process.
The imported dashboard will appear in the **Dashboards** section.
You’ve successfully exported or imported a dashboard.\
Your workflow is now streamlined with reusable dashboard structures that can be transferred, backed up, or restored effortlessly.
***
## Method 2: Move an Internal Dashboard to Another Workspace
* Navigate to the **Dashboards** section in the **Home** page.
* Find the dashboard you want to move.
* Click the vertical three dots (⋮) menu button on the right side of the dashboard row.
* Select **Move to** from the dropdown menu.
* Select the workspace to which you want to move the dashboard.
* *(Optional)* Choose to save a copy of the dashboard in the original workspace.
* *(Optional)* Configure Schema Mapping:
* Enter the target schema name
* Click **Replace Schema** if needed
* Use the (+) button to add additional schema mappings
* Click **Move** to complete the process.
The moved dashboard will now appear in the selected workspace.
Your dashboard has been successfully moved or duplicated across workspaces.\
You can now manage dashboards across teams and environments with improved flexibility and control.
# Schedule Reports For Internal Users
Source: https://docs.usedatabrain.com/guides/dashboards/report-scheduler
This guide demonstrates how to create, schedule, and manage automated dashboard reports with flexible delivery options for users.
Please refer the below guide if email settings is not configured.
## 1. Access Report Scheduler
* Click on the **Settings** icon located next to the Preview icon.
* Select **"Report Scheduler"** from the dropdown menu.
* Then, click on the **"+ New Schedule"** button in the Report Scheduler window.
## 2. Configure Report Scheduler
* Enter a descriptive subject line for the report and add recipient email addresses in the **"Send to"** field.
* Then, select desired charts from the **"Charts to Attach"** dropdown menu and choose relevant clients from the **"Clients"** dropdown list.
* Set email frequency by selecting one of the following options:
* Daily
* Weekly
* Monthly
* Then, choose specific days for report delivery and set your preferred scheduled time and timezone.
* Finally, click **"Save"** to confirm the settings.
## 3. View the Scheduled Reports
Once scheduled, all created reports will be visible under the **Report Scheduler** window.\
This list displays the **report title**, **recipient email**, and **scheduled time**.
## Manage Existing Scheduled Reports
* **To edit:** Click on the report to make the necessary changes and click on **"Update"**
* **To delete:** Click the three dots (⋮) icon and select **"Delete"**
You’ve successfully scheduled automated dashboard reports.\
Your reports will now be delivered automatically to the selected recipients with the configured frequency and charts.
# Share Dashboard
Source: https://docs.usedatabrain.com/guides/dashboards/share-dashboard
Sharing dashboards allows for easy collaboration and data presentation.
1. **Navigate to Dashboard and Initiate Sharing**
* Open the **dashboard** you want to share.
* Click the **"Share"** button next to the **"Elements"** button.
2. **Generate a Shareable Link**
* Choose an **expiry time** for the shared dashboard.
* Set **access controls** to define user permissions.
* Click **"Generate Link"** to create a shareable URL.
3. **Access Link**
* Click **"Copy"** to save the generated link to your clipboard.
* To preview the shared dashboard, click **"Preview"** or paste the copied link into a browser.
4. **Delete preview links**
* Click the **"Share"** icon near the **settings** icon (top-right corner).
* Select **"View All Links"** to see active shared links.
* Delete any links that are no longer needed.
Dashboard shared successfully. Your link is active with the configured access controls.
# Datadog Integration
Source: https://docs.usedatabrain.com/guides/datadog-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to Datadog
# Integrating Databrain with Datadog
This guide explains how to send OpenTelemetry traces, metrics, and logs from your self-hosted Databrain instance to Datadog.
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Datadog account with APM enabled
* Datadog API key
## Configuration
### 1. Get Your Datadog API Key
1. Log into your [Datadog account](https://app.datadoghq.com/)
2. Navigate to **Organization Settings** → **API Keys**
3. Copy an existing API key or create a new one
### 2. Determine Your Datadog Site
Identify your Datadog site (region):
| Site | OTLP Endpoint |
| ------------- | ------------------------------- |
| US1 (default) | `https://api.datadoghq.com` |
| US3 | `https://api.us3.datadoghq.com` |
| US5 | `https://api.us5.datadoghq.com` |
| EU | `https://api.datadoghq.eu` |
| US1-FED | `https://api.ddog-gov.com` |
| AP1 | `https://api.ap1.datadoghq.com` |
### 3. Configure Databrain Environment Variables
Add these environment variables to your Databrain backend:
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# Datadog OTLP endpoint (adjust for your site)
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.datadoghq.com
# Service name (appears in Datadog APM)
OTEL_SERVICE_NAME=databrain-api
# Datadog API key (required for authentication)
DD_API_KEY=your_datadog_api_key_here
# Optional: Set environment tag
DD_ENV=production
# Optional: Set version tag
DD_VERSION=1.0.0
# Optional: Enable debug logging
LOG_LEVEL=info
```
### 4. Docker Compose Configuration
Update your `docker-compose.yml`:
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://api.datadoghq.com"
OTEL_SERVICE_NAME: "databrain-api"
DD_API_KEY: "${DD_API_KEY}"
DD_ENV: "production"
DD_VERSION: "1.0.0"
LOG_LEVEL: "info"
```
**Security Note**: Store your `DD_API_KEY` in a `.env` file, not directly in `docker-compose.yml`.
### 5. Kubernetes Configuration
For Kubernetes deployments:
```yaml theme={"dark"}
apiVersion: v1
kind: Secret
metadata:
name: datadog-secret
type: Opaque
stringData:
api-key: your_datadog_api_key_here
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: databrain-backend
spec:
template:
spec:
containers:
- name: backend
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://api.datadoghq.com"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
- name: DD_API_KEY
valueFrom:
secretKeyRef:
name: datadog-secret
key: api-key
- name: DD_ENV
value: "production"
```
## Alternative: Using Datadog Agent
For better performance and additional features, use the Datadog Agent as an OTLP collector:
### 1. Deploy Datadog Agent
**Docker Compose:**
```yaml theme={"dark"}
services:
datadog-agent:
image: gcr.io/datadoghq/agent:latest
environment:
DD_API_KEY: "${DD_API_KEY}"
DD_SITE: "datadoghq.com" # Adjust for your site
DD_APM_ENABLED: "true"
DD_APM_NON_LOCAL_TRAFFIC: "true"
DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_HTTP_ENDPOINT: "0.0.0.0:4318"
DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_GRPC_ENDPOINT: "0.0.0.0:4317"
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /proc/:/host/proc/:ro
- /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
networks:
- databrain
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://datadog-agent:4318"
OTEL_SERVICE_NAME: "databrain-api"
```
**Kubernetes (using Datadog Operator):**
```yaml theme={"dark"}
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
name: datadog
spec:
global:
credentials:
apiKey:
site: datadoghq.com
features:
apm:
enabled: true
otlp:
receiver:
protocols:
http:
enabled: true
endpoint: "0.0.0.0:4318"
grpc:
enabled: true
endpoint: "0.0.0.0:4317"
```
Then configure Databrain:
```yaml theme={"dark"}
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://datadog-agent.datadog.svc.cluster.local:4318"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
```
## What Gets Sent to Datadog
Once configured, Databrain automatically sends:
| Telemetry Type | Datadog Product | Description |
| -------------- | --------------- | -------------------------------------------------------- |
| **Traces** | APM | API request spans with timing, status codes, and errors |
| **Metrics** | Metrics | Request latency histograms, error rates, throughput |
| **Logs** | Log Management | Correlated logs with trace context (trace\_id, span\_id) |
## Verification
### 1. Restart Databrain
```bash theme={"dark"}
docker compose restart databrainbackend
# or
kubectl rollout restart deployment/databrain-backend
```
### 2. Generate Test Traffic
Make a few API requests to your Databrain instance:
```bash theme={"dark"}
curl -X GET "https://your-databrain-instance.com/api/health"
curl -X POST "https://your-databrain-instance.com/api/v2/metric/execute" \
-H "Content-Type: application/json" \
-d '{"metricId": "test-123"}'
```
### 3. Check Datadog UI
1. **APM Traces**:
* Navigate to **APM** → **Traces**
* Filter by `service:databrain-api`
* You should see traces within 1-2 minutes
2. **Service Map**:
* Go to **APM** → **Service Map**
* Look for `databrain-api` and its dependencies (PostgreSQL, Redis, etc.)
3. **Metrics**:
* Navigate to **Metrics** → **Explorer**
* Search for `trace.http.request.duration` or `http.server.duration`
4. **Logs**:
* Go to **Logs** → **Search**
* Filter by `service:databrain-api`
* Click on a log entry to see correlated traces
## Custom Tags and Attributes
Add custom tags to all telemetry:
```bash theme={"dark"}
# Environment-specific tags
DD_TAGS="env:production,team:backend,region:us-east-1"
# In docker-compose.yml
environment:
DD_TAGS: "env:production,team:backend,region:us-east-1"
```
These tags will appear in Datadog and can be used for filtering and grouping.
## Advanced Configuration
### Sampling Configuration
To reduce costs, configure trace sampling in the Datadog Agent:
```yaml theme={"dark"}
# datadog.yaml for Agent
apm_config:
max_traces_per_second: 10
trace_sample_rate: 0.5 # Sample 50% of traces
```
### Resource Attributes
Databrain automatically includes these resource attributes:
* `service.name` - Your service name (databrain-api)
* `service.version` - Databrain version
* `deployment.environment` - From DD\_ENV
* `host.name` - Container/pod hostname
## Troubleshooting
| Issue | Solution |
| ------------------ | ------------------------------------------------------ |
| No data in Datadog | Verify `OTEL_ENABLED=true` and DD\_API\_KEY is correct |
| 403 Forbidden | Check API key has APM permissions in Datadog |
| Connection timeout | Verify endpoint URL matches your Datadog site |
| Missing traces | Wait 2-3 minutes; Datadog has ingestion delay |
| High costs | Implement sampling in Datadog Agent configuration |
### Debug Mode
Enable debug logging to troubleshoot:
```bash theme={"dark"}
LOG_LEVEL=debug
```
Check Databrain logs for:
```
[Telemetry] OpenTelemetry initialized - service: databrain-api
```
### Verify Agent Connectivity (if using Agent)
Check Datadog Agent logs:
```bash theme={"dark"}
# Docker
docker logs datadog-agent | grep -i otlp
# Kubernetes
kubectl logs -n datadog daemonset/datadog-agent | grep -i otlp
```
You should see:
```
OTLP HTTP receiver listening on 0.0.0.0:4318
```
## Datadog Features
### APM Dashboard
Datadog APM provides:
* **Service Overview**: Latency percentiles (p50, p75, p95, p99), throughput, error rates
* **Flame Graphs**: Visual representation of trace spans
* **Deployment Tracking**: Compare performance before/after deployments
* **Error Tracking**: Automatic error detection and grouping
### Log Correlation
Click on any trace in Datadog APM to see:
* All logs generated during that request
* Database queries executed
* External API calls made
* Full request/response context
### Alerts
Set up monitors in Datadog:
```
Alert when:
avg(last_5m):avg:trace.http.request.duration{service:databrain-api} > 2000
```
## Pricing Considerations
Datadog pricing is based on:
* **Indexed Spans**: Number of traces retained for search
* **Ingested Spans**: Total spans sent (used for metrics)
* **Custom Metrics**: Number of unique metric timeseries
**Cost Optimization Tips**:
1. Use sampling to reduce indexed spans (keeps metrics accurate)
2. Filter low-value traces (health checks, static assets)
3. Use the Datadog Agent for local aggregation
4. Set retention periods appropriately
## Support
* **Datadog Documentation**: [https://docs.datadoghq.com/tracing/](https://docs.datadoghq.com/tracing/)
* **Datadog Support**: Available via in-app chat or email
* **OpenTelemetry Compatibility**: [https://docs.datadoghq.com/tracing/trace\_collection/otel\_instrumentation/](https://docs.datadoghq.com/tracing/trace_collection/otel_instrumentation/)
For Databrain configuration issues, contact your Databrain support team.
# Allow Access to our IP
Source: https://docs.usedatabrain.com/guides/datasources/allow-access-to-our-ip
Getting Started with Database IP Whitelisting for Databrain
### Requirements:
* An active database instance on one of the supported platforms: Amazon Redshift, BigQuery, ClickHouse, ElasticSearch, MySQL, Postgres, MongoDB, Snowflake, Databricks.
* Admin-level permissions for the database instance to modify security settings.
* Ensure Databrain's IP or IP range is known for whitelisting.
* **Databrain IP Address:** 44.198.8.73
### Setup Guide
#### For Public Database Instances:
#### Ensure Databrain's Connectivity:
1. Ensure your database instance is active and Databrain can reach it.
2. The connectivity largely depends on your cloud provider's permissions and security configurations.
3. The most straightforward way to verify this is through your database's connectivity test feature or UI.
#### Whitelist Databrain's IP:
1. Navigate to the security or firewall settings of your database.
2. **Rule Type**: Typically "Inbound" to allow incoming connections.
3. **IP Address**: Input Databrain's IP or IP range.
4. **Protocol & Port**: Defined by the database (e.g., TCP 3306 for MySQL).
**Security Note**: Always ensure you only whitelist trusted IPs. Databrain's IP is required for seamless data integration.
### For Non-Public Database Instances:
#### Setup Your Bastion Host or Jump Server:
1. Log in to your AWS Management Console.
2. Navigate to the EC2 dashboard.
3. Click on "Launch Instance" to start the instance creation wizard.
4. Choose an appropriate Amazon Machine Image (AMI) based on your requirements. For a bastion host, you can typically use a standard Linux AMI such as Amazon Linux or Ubuntu.
5. Select an instance type based on the expected workload and resource requirements.
6. Ensure that the VPC selected for the bastion host is the same as the one where your database cluster resides. This ensures that the bastion host and database are within the same virtual network for seamless connectivity.
7. Configure the instance details including the subnet within the selected VPC and any additional settings required for your environment.
8. Add storage as needed for the instance.
9. Configure security groups for the instance. Ensure that at least SSH (port 22) access is allowed from your IP address or range.
10. Review the instance configuration and launch the EC2 instance.
#### Configure Database Security Group:
1. Navigate to the security group associated with your database cluster.
2. Add inbound rules to allow traffic from the bastion host's security group on the port used by the database.
3. This step allows incoming connections from the bastion host to the database cluster.
***
#### Whitelist Databrain's IP in Bastion's Security Settings:
1. Navigate to the security or firewall settings of your bastion host.
2. **Rule Type**: Typically "Inbound" to allow incoming connections.
3. **IP Address**: Input Databrain's IP or IP range.
4. **Protocol & Port**: The port used for SSH (typically port 22).
> **Security Note**: Always ensure you only whitelist trusted IPs. Databrain's IP is required for seamless data integration.
***
#### Provide SSH details in Databrain app (connect datasource):
* **SSH Host**: \[SSH host endpoint of the SSH instance. Ensure the Databrain IP is whitelisted.]
* **SSH Port**: 22
* **Username**: \[Username to connect to SSH host]
* **Private Key**: \[Private key to authenticate with the SSH host]
> **Note**: This is applicable for PostgreSQL, Redshift and Trino only.
#### Finding Configuration Details in Your Database Platform:
1. **Rule Type:**\
Locate this under your database's security or firewall settings. Often labeled as "Inbound Rules" or "Access Control".
2. **IP Address:**\
Use the IP or IP range provided by Databrain. This ensures Databrain can connect to your database.
3. **Protocol & Port:**\
Check your database's documentation. Each database type generally has a standard protocol and port.
**Remember to save any changes made to the security settings and periodically verify that the whitelisted IPs are accurate and up-to-date.**
> **Note**: The exact terms and navigation paths might vary slightly based on the cloud provider and database platform, but the overarching principle remains the same. Always refer to the specific documentation of the database or cloud provider for detailed steps.
# Configure Tenants
Source: https://docs.usedatabrain.com/guides/datasources/configure-tenants
After setting up a data source, the next step is to configure the organization details to tailor the analytics experience for your clients.
* Determine your organization’s **Tenancy Level**. Options include **Database** or **Table**.
* Select the appropriate tenancy for your customer information, ensuring a personalized analytics experience.\
Choose between:
* **Database**: Choose this when your client data is stored at the database level (each client has its own database).
* **Table**: Choose this when your client data is stored as rows identified by an ID column in a single table.
Select the tenancy level as **Database** if your client data is stored in separate databases for each customer.
Select Client Data Source and Determine Primary Key:
* Find and select the **Table** that houses your client, organization, or customer data.
* Use the search function if necessary. Clicking a table displays its columns.
* Choose the **Primary Key** column (e.g., `id`, `user_id`, `org_id`).
* Select the column indicating the **Customer Name**\
(e.g., `name`, `client_name`, `org_name`, `company_name`).
* After designating both the primary key and customer name columns, press **Complete** to finalize the configuration.
With these steps, you've successfully added customer organizations of your company to Databrain.
# Amazon Redshift
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/amazon-redshift
### Getting Started with Redshift Destination Configuration
### Requirements:
* Active Redshift cluster.
* Allow connections from Databrain to your Redshift cluster.\
For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on:
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Cluster Accessibility:**
* Make sure your cluster is active and accessible from the machine running Databrain.
* This is dependent on your networking setup. The easiest way to verify if Databrain is able to connect to your Redshift cluster is via the Add a Data Source UI.
* For a deeper dive on configuring your cluster's access, you can consult the AWS Redshift documentation.
2. **Grant Necessary Permissions:**
* Read Access on Tables and `information_schema`: Grant read access permissions to the tables within Redshift as well as the `information_schema` schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing Redshift to enable reading from tables and accessing metadata stored in the `information_schema`.
* Grant SELECT permission on all tables in the specified schema:\
`GRANT SELECT ON ALL TABLES IN SCHEMA schema_name TO your_user_or_role;`
3. **Fill Up Connection Info:**
Provide the necessary information to connect to your cluster:
* **Host Endpoint**: Part of the connection string or endpoint accessible without the port and database name. It typically includes the cluster-id, region, and ends with `redshift.amazonaws.com`
* **Port**: e.g., `5439`
* **Database Name**: Name of the database you want to sync data into
* **Username**: Username to access the database
* **Password**: Password associated with the username
* **SSL Mode**: Specify if SSL mode is required and the type of authentication to be used.
*Note on Schema Configuration:*
* **Default Schema**: Public. This is the default schema tables are written to if the source does not specify a namespace. Unless specifically configured, the usual value for this field is `"public"`.
### Encryption:
* In the case of a private instance, SSH credentials should also be provided for authentication purposes along with Redshift Credentials.
### Permissions:
* Permission to read `information_schema`
* Whitelist the IP address
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
Replace the placeholders inside the square brackets with actual values when filling in the details.
### Locating the Configuration Details in Redshift
1. **Destination Name**
* This is a custom name you decide for identification within Databrain. Choose a descriptive name based on your use case.
2. **Host Endpoint (Endpoint)**
* Navigate to the AWS Management Console and open the Amazon Redshift dashboard.
* Select the desired cluster.
* In the "Cluster Details" or "Properties" tab, you'll find the `Endpoint` listed.
3. **Port**
* Typically, this is `5439` for Amazon Redshift. Confirm this in the "Cluster Details" or "Properties" tab where you found the Endpoint.
4. **Database Name**
* This is the database name you specified when creating the cluster. View it under the "Configuration" details in the Redshift dashboard.
5. **Username & Password**
* These are the credentials set during cluster creation or when creating a specific user in the database. If you're an admin, you can manage and view users using SQL client tools connected to Redshift.
6. **SSL Mode**
* Amazon Redshift supports SSL connections. Check your cluster’s security configurations or consult with your DBA to determine if you require SSL or the specific SSL mode used.
7. **Default Schema**
* As noted, the default schema in Amazon Redshift is typically `public`. Verify and manage schemas using SQL client tools connected to your Redshift cluster.
# Amazon S3
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/amazon-s3
### Getting Started with S3 Source Configuration
#### Requirements:
* Active AWS account with S3 access.
* Appropriate IAM permissions to access the desired S3 buckets.
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Bucket Accessibility:**
* Make sure your S3 bucket is active and accessible from Databrain.
* This depends on your AWS account settings and bucket permissions.
2. **Grant Necessary Permissions:**
* Read Access on Buckets and Objects: Grant read access permissions to the S3 buckets and objects you want to sync.
3. **Fill Up Connection Info:**
* Provide the following information to connect to your S3 bucket:
* *Destination Name*: A custom name to identify this connection in Databrain.
* *S3 Region*: The AWS region where your S3 bucket is located (e.g., us-east-1).
* *S3 Access Key ID*: Your AWS Access Key ID for authentication.
* *S3 Secret Access Key*: Your AWS Secret Access Key associated with the Access Key ID.
* *S3 Bucket Dataset Folder Path*: The specific folder path within your bucket (e.g., awss3\_folder\_test\_less/).
* *S3 Bucket Name*: The name of your S3 bucket (e.g., databrain-s3-test-csv).
* *Table Level*: Select whether to interpret data at the Folder or File level.
### Permissions:
* Permission to list bucket contents.
* Permission to read objects from the specified bucket.
* If using KMS encryption, permission to use the KMS key for decryption.
### Locating the Configuration Details in AWS S3
1. **Destination Name:**
* Choose a descriptive name for this connection within Databrain.
2. **S3 Region:**
* Log in to the AWS Management Console and open the S3 service.
* Select your bucket, and find the region information in the bucket's "Properties" tab.
3. **S3 Access Key ID & Secret Access Key:**
* Generated in the IAM (Identity and Access Management) section of AWS.
* Navigate to IAM, select the desired user, go to the "Security credentials" tab, and create or manage access keys.
4. **S3 Bucket Dataset Folder Path:**
* Navigate to your bucket in the S3 console and note the specific folder path you wish to sync.
5. **S3 Bucket Name:**
* This is the name of your S3 bucket, visible in the S3 dashboard of the AWS Management Console.
6. **Table Level:**
* Determine whether your data should be interpreted at the folder level or file level based on your S3 bucket structure and data organization.
# Athena
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/athena
This guide will walk you through the steps to connect your Athena database to Databrain.
### Requirements:
* Active AWS account with **Athena** and **S3** access.
* Proper **IAM permissions** to access Athena and the related S3 buckets.
* A selected **Databrain Workspace** where this source will be added.
### Setup Guide:
1. **Ensure Athena and S3 Accessibility:**
* Make sure your **Athena database** is active and queries can write results to the designated **S3 bucket**.
* Ensure that both Athena and S3 are accessible using the credentials you plan to use with Databrain.
* Your S3 bucket should be in a region supported by Athena (e.g., `us-east-1` is preferred).
2. **Grant Necessary Permissions:**
You must assign the appropriate IAM policies to the user or role you're using. These should include:
* **Access to Athena** for querying.
* **Access to Glue Data Catalog**, if used.
* **Access to S3** for reading/writing query results.
3. **Fill Up Connection Info:**
Provide the following fields in Databrain to configure your Athena source:
* **Destination Name**: A custom name to identify this Athena connection in Databrain.\
*Example: `Athena Destination Spec`*
* **S3 Region**: The AWS region where your Athena query result bucket is located.\
*Example: `us-east-1`*
* **S3 Access Key ID**: Your AWS Access Key ID for authentication.
* **S3 Secret Access Key**: Your AWS Secret Access Key associated with the Access Key ID.
* **Database**: The name of the Athena database you want to connect to.\
*Example: `iceberg_db`*
* **S3 Bucket Name**: The name of the S3 bucket where Athena stores query results.\
*Example: `output-bucket-name`*
### Locating the Configuration Details in AWS
1. **Destination Name:**
Choose any descriptive name to label your Athena connection in Databrain. This does not affect AWS resources.
2. **S3 Region:**
* Log in to the AWS Management Console and open the **S3** service.
* Select the bucket used by Athena for output.
* Then, find the **Region** under the bucket’s **Properties** tab.
3. **S3 Access Key ID & Secret Access Key:**
* Open the **IAM** console and select the desired IAM **User** or **Role**.
* Then, go to the **Security Credentials** tab and create or retrieve **Access Keys** for use in Databrain.
4. **Database:**
* Open the **Athena** service in the AWS console and select your desired database from the left sidebar (e.g., `iceberg_db`).
5. **S3 Bucket Name:**
* In the **Athena console**, go to **Settings**.
* Then, find the **Query result location** (S3 URI like `s3://your-bucket-name/path`).
* Use the bucket name from this URI (e.g., `your-bucket-name`).
# BigQuery
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/bigquery
### Getting Started with BigQuery Destination Configuration
#### Requirements:
* Active Google Cloud Platform (GCP) project with BigQuery enabled.
* Allow connections from Databrain to your BigQuery dataset.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Project Accessibility:**
* Ensure your GCP project with BigQuery is active and accessible from the machine running Databrain.
* The accessibility is dependent on your GCP permissions and IAM settings. The easiest way to verify if Databrain can connect to your BigQuery is via the Add a Data Source UI.
2. **Grant Necessary Permissions:**
* Read Access on Datasets, Tables, and `information_schema`: Grant read access permissions to the datasets, tables, and the `information_schema` dataset within BigQuery. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign the predefined role `roles/bigquery.dataViewer` to provide read access to datasets and tables.
* Add `jobs.create` Permissions: Additionally, grant permissions to create jobs in BigQuery by assigning the `roles/bigquery.jobUser` role. This allows Databrain to create and manage jobs for tasks such as querying data into BigQuery.
*Note on Project & Dataset IDs:*
* Project IDs must contain 6–63 lowercase letters, digits, or dashes. Some project IDs also include a domain name separated by a colon. IDs must start with a letter and may not end with a dash.
* Dataset IDs follow similar rules, adhering to the same length and character restrictions. It’s important to maintain consistency and compliance with these guidelines to ensure proper functionality and interoperability within BigQuery.
3. **Fill Up Connection Info:**
* Provide the necessary information to connect to your BigQuery:
* `Destination Name`: \[Pick a name to help you identify this destination in Databrain]
* `Project ID`: \[The GCP project ID for the project containing the target BigQuery dataset]
* `Default Dataset ID`: \[The default BigQuery Dataset ID that tables are replicated to if the source doesn't specify a namespace]
* `Service Account Key JSON`: \[The JSON value of the Service Account Key to authenticate into your Service Account. This is mandatory for Cloud and optional for Open-Source versions of Databrain]
*Note on Dataset Configuration:*
* Ensure the default dataset ID is set correctly for proper data synchronization. This is where tables will be replicated if the source does not specify a namespace.
### Encryption:
* All BigQuery connections via Databrain are secure, leveraging GCP's built-in security features.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Allow job creation and provide read access to datasets, ensuring dataset IDs adhere to standard rules.
Replace the placeholders inside the square brackets with actual values when filling in the details.
### Locating the Configuration Details in BigQuery
1. **Destination Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that is relevant and descriptive of your BigQuery setup.
2. **Project ID:**
* Navigate to the [Google Cloud Console](https://console.cloud.google.com).
* On the top right corner, the current project name is displayed. Clicking on it will show a dropdown with all your projects.
* Beside each project name, there is an ID which is the Project ID.
3. **Default Dataset ID:**
* In the Google Cloud Console, navigate to BigQuery.
* In the left sidebar, under the project name, you'll see a list of datasets. The Dataset ID is the name of these datasets.
4. **Service Account Key JSON:**
* In the Google Cloud Console, navigate to "IAM & Admin" > "Service Accounts".
* Find the service account you want to use or create a new one.
* Once you have the service account, click on the three dots (options) for that account, and select "Manage keys".
* Click on "Add Key" and choose "JSON" as the key type.
* Once created, the JSON key will be downloaded to your computer. This is the JSON value you need for the Service Account Key JSON.
# ClickHouse
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/clickhouse
## Getting Started with ClickHouse Server Destination Configuration
### Requirements:
* Active ClickHouse server instance.
* Allow connections from Databrain to your ClickHouse server.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
Learn how to whitelist Databrain's IP addresses to ensure secure connectivity to your ClickHouse server.
* Choose the Databrain Workspace to which you wish to connect the data.
## Setup Guide
### 1. Ensure Server Accessibility:
* Ensure your ClickHouse server is active and accessible from the machine running Databrain.
* Accessibility is dependent on your ClickHouse user privileges and network settings. The easiest way to verify if Databrain can connect to your ClickHouse server is via the check connection tool in the UI. For detailed setup and permissions, refer to the ClickHouse documentation.
### 2. Fill Up Connection Info:
* Provide the necessary information to connect to your ClickHouse server:
* *Destination Name*: \[Pick a name to help you identify this destination in Databrain]
* *ClickHouse Account Details*:
* **Host**: \[Enter your ClickHouse account locator, e.g., `https://ru7b3vwqoe.eu-west-1.aws.clickhouse.cloud`]
* **Port**: 8443 (This is the default port for ClickHouse servers)
* *Authentication Details*:
* **Username**: \[Enter the name of the user you want to use to access the database]
* **Password**: \[Enter the password associated with the username]
### Encryption:
* Ensure you have SSL/TLS set up for your ClickHouse server if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
> Replace the placeholders inside the square brackets with the actual values when filling in the details.
### Locating the Configuration Details in ClickHouse
1. **Destination Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that is relevant and descriptive of your ClickHouse server.
2. **Host:**
* For remote servers or cloud installations, it would be the IP address, domain name, or endpoint URL of the machine where ClickHouse is running.
* For cloud installations like ClickHouse Cloud, you can find this information in the respective cloud dashboard or the connection details page.
3. **Port:**
* The default port for ClickHouse is `8123` for HTTP interface and `8443` for HTTPS. However, it might be different based on your setup, especially for cloud providers. Ensure you're using the correct port based on your connection requirements and setup.
4. **Username:**
* If you've set up authentication for ClickHouse, this would be the username you use to access ClickHouse. Default installations might not have authentication enabled, but for production environments, it's recommended to secure your ClickHouse instance.
* If you're unsure of the username, check the ClickHouse configuration files (`users.xml` or `config.xml`) or consult with the person who set up ClickHouse.
5. **Password:**
* This is the password associated with the username you provided. Again, you'd find this in the ClickHouse configuration if it's set up or you'd need to know it if it was provided to you during setup.
Explore the official ClickHouse documentation for detailed integration guides, best practices, and advanced configuration options.
# CockroachDB
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/cockroachdb
### Getting Started with CockroachDB Source Configuration
### Requirements:
* Active **CockroachDB** cluster (Self-hosted or CockroachDB Cloud).
* Allow connections from Databrain to your CockroachDB cluster.
* Ensure your CockroachDB user has sufficient read permissions.
* Choose the Databrain Workspace to which you wish to connect the data.
For details on setting up IP whitelisting and secure connectivity, refer to:
### Setup Guide:
1. **Ensure Database Accessibility:**
* Ensure your CockroachDB cluster is active and accessible from the machine running Databrain.
* Accessibility depends on:
* Network rules / firewall settings
* CockroachDB Cloud IP allowlisting (if using managed cloud)
* User privileges
* The easiest way to verify connectivity is by using the **Authenticate** button in the Databrain connection UI after filling in the details.
2. **Grant Necessary Permissions:**
* Databrain requires:
* Read access on tables
* Access to metadata (information\_schema)
* Usage on schema
Run the following:
```sql theme={"dark"}
-- Grant USAGE on schema
GRANT USAGE ON SCHEMA schema_name TO username;
-- Grant SELECT on all existing tables
GRANT SELECT ON ALL TABLES IN SCHEMA schema_name TO username;
-- Grant SELECT on future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA schema_name
GRANT SELECT ON TABLES TO username;
```
Replace `schema_name` and `username` with your actual values.
3. **Fill Up Connection Info:**
Provide the following details in the Databrain UI:
* **Integration Name:** Pick a name to help you identify this source in Databrain (e.g., CockroachDB – Production).
* **Host:** Hostname of the CockroachDB cluster (Example: free-tier.gcp-us-central1.cockroachlabs.cloud)
* **Port:** `26257` (Default CockroachDB SQL port) Note: Some managed environments may expose 5432 for Postgres compatibility.
* **Database Name:** Name of the database you want to sync.
* **Username:** CockroachDB user with read access.
* **Password:** Password associated with the username.
* **Schemas:** Defaults to `public`. Provide a comma-separated list (case sensitive) if syncing from multiple schemas.
* **Encryption:** CockroachDB **requires secure connections (TLS/SSL)** in most deployments.
* **SSL Mode:** Enable SSL Mode if:
* You are using CockroachDB Cloud
* TLS is enforced in your cluster (default in most setups)
* If your cluster enforces secure transport, SSL Mode must be enabled in Databrain.
* **SSH Tunnel (If Required):** If your CockroachDB cluster is inside a private network:
* **SSH Host:** SSH endpoint of the bastion/jump server
* **SSH Port:** 22
* **Username:** SSH username
* **Private Key:** Private key used for SSH authentication
* **Ensure:**
* Databrain IP is whitelisted
* The SSH server can access the CockroachDB cluster internally
### Permissions Checklist:
* Whitelisted Databrain IP
* **USAGE** on schema
* **SELECT** on tables
* Default privileges for future tables (recommended)
* Permission to read `information_schema`
Replace placeholders inside square brackets with actual values when configuring.
### Locating the Configuration Details in CockroachDB
**Host:**
* For CockroachDB Cloud: Available in your cluster connection string.
* For self-hosted: IP address or DNS of the CockroachDB node/load balancer.
* You can find it in:
* CockroachDB Cloud console → Connect → SQL Connection string
**Port:**
* Default CockroachDB SQL port: `26257`
* Check your cluster configuration if customized.
**Database Name:**
* Connect using:
```sql theme={"dark"}
SHOW DATABASES;
```
**Username:**
* List users:
```sql theme={"dark"}
SHOW USERS;
```
* Or consult your database administrator.
**Password:**
* CockroachDB does not display passwords.
* If forgotten, reset it:
```sql theme={"dark"}
ALTER USER username WITH PASSWORD 'new_password';
```
**Schemas:**
* List schemas:
```sql theme={"dark"}
SHOW SCHEMAS FROM database_name;
```
**SSL Mode:**
* Check cluster settings:
```sql theme={"dark"}
SHOW CLUSTER SETTING server.ssl.enabled;
```
* In CockroachDB Cloud, SSL is enabled by default.
# CSV
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/csv
## Getting Started with CSV Source Configuration
### Requirements:
* CSV files with correctly formatted data.
* Ensure the files are accessible to Databrain from your local system.
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Fill Up Connection Info:**
* Provide the necessary information to connect your CSV data to Databrain:
* Destination Name\*: \[Pick a name to help you identify this destination in Databrain]
* Table Level\*: \[Select whether you want the data source to be file-based or folder-based]
* Choose File\*: \[Upload or link to the specific CSV file or folder containing your data]
# DataBricks
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/databricks
### Getting Started with Databricks Data Source Configuration
#### Requirements:
* Active Databricks cluster.
* Allow connections from Databrain to your Databricks cluster.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Cluster Accessibility:**
* Ensure your Databricks cluster is active and accessible from the machine running Databrain.
* Accessibility is dependent on your Databricks user privileges and network settings. The easiest way to verify if Databrain can connect to your Databricks cluster is via the check connection tool in the UI. For detailed setup and permissions, refer to the Databricks documentation.
2. **Fill Up Connection Info:**
* Provide the necessary information to connect to your Databricks cluster:
* *Data Source Name*: \[Pick a name to help you identify this data source in Databrain]
* *Databricks Cluster Details*:
* **Host**: \[Host Endpoint of the Databricks Cluster, e.g., `dbc-a1b2345c-d6e7.cloud.databricks.com`]
* **Path**: \[Path of the data warehouse, e.g., `/sql/1.0/endpoints/a1b234c5678901d2`]
* *Authentication Details*:
* **Token**: \[Access token, e.g., `dapi1ab2c34defabc567890123d4efa56789`]
### Encryption:
* Ensure you have SSL/TLS set up for your Databricks connection if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
Replace the placeholders inside the square brackets with the actual values when filling in the details.
## Locating the Configuration Details in Databricks
1. **Data Source Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that is relevant and descriptive of your Databricks source.
2. **Host:**
* Log in to your Databricks workspace. The URL in your browser's address bar is your Host Endpoint. It typically has the format `dbc-a1b2345c-d6e7.cloud.databricks.com`.
3. **Path:**
* This is specific to the SQL endpoint you want to connect to in Databricks. Navigate to the SQL tab in your Databricks workspace, and select the desired SQL endpoint. In the endpoint details, you should find the full path. The path typically looks like\
`/sql/1.0/endpoints/a1b234c5678901d2`.
4. **Token:**
* In Databricks, navigate to the user settings by clicking on the user icon in the top right corner.
* Choose "User Settings" and then go to the "Access Tokens" tab.
* Generate a new token or use an existing one. Note that once you generate a token and close the window.
# ElasticSearch
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/elasticsearch
### Getting Started with Elasticsearch Source Configuration
#### Requirements:
* Active Elasticsearch server.
* Allow connections from Databrain to your Elasticsearch server.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
#### 1. Ensure Server Accessibility:
* Ensure your Elasticsearch server is active and accessible from the machine running Databrain.
* Accessibility is dependent on your Elasticsearch user privileges and network settings. The easiest way to verify if Databrain can connect to your Elasticsearch server is via the check connection tool in the UI. For detailed setup and permissions, refer to the Elasticsearch documentation.
#### 2. Fill Up Connection Info:
* Provide the necessary information to connect to your Elasticsearch server:
* *Integration Name*: \[Pick a name to help you identify this source in Databrain]
* *Server Type*: \[The type of Elasticsearch server to be used]
* *Authentication Configuration*:
* **Credentials**: \[Specify if authentication is enabled. If "Yes", provide the authentication type and credentials below. If "No", you can skip the following authentication details.]
* *Type*: \[The type of authentication to be used]
* **Authentication Details (if Credentials are enabled)**:
* *Username*: \[Basic auth username to access a secure Elasticsearch server]
* *Password*: \[Basic auth password to access a secure Elasticsearch server]
### Encryption:
* Ensure you have SSL/TLS set up for your Elasticsearch server if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
### Locating the Configuration Details in Elasticsearch
1. **Integration Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that is both relevant and descriptive for your Elasticsearch source.
2. **Server Type:**
* This information refers to your Elasticsearch deployment type. If you've set up Elasticsearch on your servers or infrastructure, it's "Self-managed". If you're using Elastic's cloud service, it's "Elastic Cloud". Check your Elasticsearch service or setup documentation to determine this.
3. **Credentials:**
* Verify if your Elasticsearch cluster requires authentication by trying to access the cluster without any credentials. If authentication is required, you'd need to enable this option. If not, you can disable it.
4. **Username (if Credentials enabled):**
* This would be the username you've set up for accessing your secured Elasticsearch cluster. If you're unsure, check with the individual who configured Elasticsearch security or look into the Elasticsearch security configurations.
5. **Password (if Credentials enabled):**
* This is the associated password for the above username. For security reasons, Elasticsearch doesn't display passwords, so you'd need to know this or have it stored securely.
# Firebolt
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/firebolt
### Requirements:
* Active Firebolt account and setup.
* Ensure the necessary service account, role, and user permissions are configured for connectivity.
### Setup Guide:
1. **Create a Service Account**:
* Log in to your Firebolt account.
* Navigate to the **Configure** tab and select the **Service Accounts** section.
* Click **CREATE** to establish a new service account.
2. **Assign Roles**:
* Go to the **Govern** tab and create a new role.
* Assign the role the permissions to **use any database** and **use any engine**.
3. **Create a User**:
* Create a user within Firebolt and assign the newly created role to the user.
4. **Retrieve Service Account Keys**:
* Return to the **Service Accounts** section.
* Copy the **Client\_ID** and **Client\_Secret** for the created service account.
5. **Fill Up Connection Info**:\
Provide the necessary information to connect to your Firebolt account in Databrain:
* **Integration Name**: Pick a name to help you identify this source in Databrain.
* **Firebolt Datasource**: Select Firebolt as your data source.
* **Client\_ID**: Copy and paste the Client\_ID retrieved from the service account.
* **Client Secret**: Copy and paste the Client\_ID retrieved from the service account.
* **Account Name**: Provide the account name for your Firebolt setup.
* **Database Name**: Enter the name of the database.
* **Engine Name**: Specify the name of the engine (e.g., my\_engine).
* **Schema**: Provide the schema name to be used.
6. **Test the Connection**:
* Use the **Add a Data Source** UI in Databrain to verify that the connection is successful.
### Locating the Configuration Details in Firebolt:
* **Service Account Client\_Secret & Client\_ID**:
* These are found under the **Service Accounts** tab in the Firebolt Configure section.
* **Role Permissions**:
* Verify roles and permissions in the **Govern** tab. Ensure the role has access to all required databases and engines.
* **Database and Engine Details**:
* Review your Firebolt account dashboard to confirm database and engine configurations.
#### Notes:
* Ensure you are using the correct Client\_Secret and Client\_ID for your service account.
* Maintain the security of your credentials to prevent unauthorized access.
### Troubleshooting intermittent failures
If the Firebolt connection works sometimes and fails at other times, work through these in order:
1. **Capture the exact error.** Open the data source in DataBrain and hit **Test connection** a few times — note whether the message changes between attempts. An auth error that appears only intermittently usually means an expired service-account token being refreshed mid-request.
2. **Engine state.** Firebolt engines can auto-stop when idle. If the first query after a quiet period fails and the retry succeeds, the engine was cold-starting. Check the engine's auto-stop setting in Firebolt, or use an always-on engine for embedded dashboards.
3. **Role scope.** Confirm the service account's role has **use any database** and **use any engine** (or explicit grants covering the configured database and engine). A role change in Firebolt takes effect on new connections, which looks intermittent while old connections drain.
4. **Concurrency limits.** Dashboards fire several metric queries at once. If failures correlate with dashboard loads (not single metrics), the engine may be hitting its concurrency limit — scale the engine or reduce simultaneous metrics.
5. **Still failing?** Contact support with the exact error string, the time window, and whether Test connection reproduces it — intermittent driver-level issues need the failing query and timestamp to trace.
# Connecting Data Sources to Databrain
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/index
Getting Started with Connecting Popular Data Sources with Databrain
Databrain simplifies data integration by offering a wide range of connectors, allowing businesses to centralize their data from multiple platforms. Below, we explore some of the most popular data connectors available in Databrain and how they can enhance your data strategy.
### Getting Started with Database IP Whitelisting for Databrain
When integrating Databrain with your database, IP whitelisting is crucial for secure and seamless connectivity. This guide outlines the steps to set up IP whitelisting, allowing Databrain access while ensuring security. Databrain IP Address can be found here.
## Available Data Source Connectors
Databrain supports a comprehensive range of data source connectors to meet your business intelligence and analytics needs. Below is a complete list of all available connectors:
### Relational Databases
* **PostgreSQL** - Connect to PostgreSQL databases for powerful relational data analytics
* **MySQL** - Integrate MySQL databases seamlessly with Databrain
* **Microsoft SQL Server (MSSQL)** - Connect to SQL Server databases for enterprise data analytics
* **SingleStore** - High-performance SQL database connector for real-time analytics
### Cloud Data Warehouses
* **Amazon Redshift** - Connect to AWS Redshift for scalable data warehousing
* **Google BigQuery** - Integrate with BigQuery for serverless data analytics
* **Snowflake** - Connect to Snowflake's cloud data platform
* **Databricks** - Integrate with Databricks for unified analytics
* **Firebolt** - Connect to Firebolt for fast cloud data warehouse analytics
### Query Engines & Analytics Platforms
* **Amazon Athena** - Query data directly from S3 using SQL
* **Trino** - Distributed SQL query engine for big data analytics
* **ClickHouse** - Connect to ClickHouse for real-time analytics
### Search & NoSQL Databases
* **Elasticsearch** - Connect to Elasticsearch for search and analytics
* **OpenSearch** - Integrate with OpenSearch for search and observability
* **MongoDB** - Connect to MongoDB for document-based data analytics
### File & Object Storage
* **Amazon S3** - Connect to S3 buckets for file-based data analytics
* **CSV** - Import and analyze CSV file data directly
## Frequently Asked Questions (FAQ)
To connect a new data source to Databrain:
1. Navigate to the Data Sources section in your Databrain dashboard
2. Click on "+ Data Source".
3. Select your desired connector from the available options
4. Provide the necessary connection credentials (host, port, database name, username, password)
5. Configure IP whitelisting if required for your database
6. Test the connection and save
For detailed step-by-step instructions for each connector, refer to the specific connector documentation.
The credentials required vary by data source, but typically include:
* **Host/Endpoint**: The server address or hostname
* **Port**: The port number for the database connection
* **Database Name**: The specific database you want to connect
* **Username**: A user with appropriate read permissions
* **Password**: The password for the database user
* **Additional Parameters**: Some databases may require SSL certificates, regions, project IDs, or other specific configuration
For cloud data warehouses, you may also need API keys, service account credentials, or OAuth tokens.
Yes, if your database has firewall restrictions or network security rules in place, you'll need to whitelist Databrain's IP addresses to allow secure connectivity. This is especially important for:
* Self-hosted databases
* Cloud databases with VPC or security group restrictions
* Databases behind corporate firewalls
You can find Databrain's IP addresses and detailed whitelisting instructions in our [IP Whitelisting Guide](https://docs.usedatabrain.com/guides/datasources/allow-access-to-our-ip).
Yes, Databrain takes data security seriously:
* All connections use encrypted protocols (SSL/TLS)
* Credentials are stored securely and encrypted at rest
* Databrain follows industry-standard security practices
* You can configure read-only database users to limit access
* IP whitelisting provides an additional layer of security
* Data is never stored permanently unless explicitly configured
For self-hosted deployments, you have full control over your data and infrastructure.
Each Databrain workspace is limited to one data source connection. However, you have several options to work with multiple data sources:
* **Use Trino**: Connect to Trino as your data source, which acts as a distributed SQL query engine that can query multiple databases simultaneously
* **Multiple Workspaces**: Create separate workspaces for different data sources, then combine the dashboards when embedding them downstream in your application
* **Semantic Layer**: Use Databrain's Semantic Layer to create unified data models that can bridge data across different sources
* **Data Integration**: Consolidate your data in a single data warehouse (like Snowflake, BigQuery, or Redshift) before connecting to Databrain
These approaches ensure optimal performance and clear data source management while still enabling multi-source analytics through strategic architecture.
If a data source connection fails, Databrain will:
* Display an error message with connection details
* Provide troubleshooting suggestions
* Allow you to test and reconfigure the connection
* Log the connection attempts for debugging
Common connection issues include:
* Incorrect credentials
* Network/firewall restrictions
* IP address not whitelisted
* Database server downtime
* Incorrect host or port configuration
Data syncing in Databrain can be configured based on your needs:
* **Real-time**: Queries are executed on-demand when viewing dashboards
* **Scheduled Sync**: You can configure periodic data refreshes
* **Manual Sync**: Trigger data refresh manually when needed
* **Caching**: Configure caching policies to balance freshness and performance
The sync frequency depends on your data source type and configuration. Refer to the [Data Source Sync Guide](https://docs.usedatabrain.com/guides/datasources/how-to-sync-a-datasource) for more details.
Yes, Databrain works with both cloud-hosted and self-hosted databases. For self-hosted databases:
* Ensure your database is accessible over the network
* Configure firewall rules to allow Databrain's IP addresses
* Set up appropriate user permissions for read access
* Consider using VPN or SSH tunneling for enhanced security
Databrain also offers self-hosted deployment options if you prefer to keep all infrastructure on-premises.
Databrain requires minimal permissions to function:
* **Read Permissions**: SELECT access to tables and views you want to analyze
* **Schema Access**: Permission to view database schema and table structures
* **Optional**: Some features may require additional permissions like creating temporary tables or views
It's recommended to create a dedicated read-only user for Databrain to minimize security risks. Databrain does not require write, update, or delete permissions on your data.
# MongoDB
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/mongoDB
### Getting Started with MongoDB BI Connector Configuration
#### Requirements:
* Active MongoDB BI Connector instance.
* Allow connections from Databrain to your MongoDB BI Connector.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on:
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Connector Accessibility:**
* Ensure your MongoDB BI Connector is active and accessible from the machine running Databrain.
* Accessibility is dependent on your MongoDB user privileges and network settings. The easiest way to verify if Databrain can connect to your MongoDB BI Connector is via the check connection tool in the UI. For detailed setup and permissions, refer to the MongoDB BI Connector documentation.
2. **Fill Up Connection Info:**
* Provide the necessary information to connect to your MongoDB BI Connector:
* *Integration Name*: \[Pick a name to help you identify this integration in Databrain]
* *Host*: \[Enter your MongoDB BI connector Hostname]
* *Port*: 3306 (or enter your specific MongoDB BI Connector Port)
* *Username*: \[Enter your MongoDB BI Connector User]
* *Password*: \[Enter the password associated with the username]
### Encryption:
* Ensure you have SSL/TLS set up for your MongoDB BI Connector if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Sync the BI connector with intervals, based on schema change frequency.
* Whitelist the IP address.
* Grant read access to schemas (usage) and tables, noting that access to only tables may not suffice in certain databases.
Replace the placeholders inside the square brackets with actual values when filling in the details.
### Locating the Configuration Details in MongoDB BI Connector
1. **Integration Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that's relevant and descriptive for your MongoDB BI Connector source.
2. **Host:**
* This is the server address where your MongoDB BI Connector is running. For remote servers, it would be the IP address or domain name of the server.
* Check the MongoDB BI Connector's configuration or startup parameters to confirm the host details.
3. **Port:**
* By default, MongoDB BI Connector listens on port `3306`. However, this might be different based on your setup.
* Confirm the specific port by checking the BI Connector's configuration or the command-line arguments used to start it.
4. **Username:**
* The MongoDB BI Connector uses the MongoDB database's authentication when set up with authentication. You'd use the same credentials as those to connect to your MongoDB cluster.
* If you're not sure about the credentials, consult with your MongoDB administrator or the person who set up the BI Connector.
5. **Password:**
* The password associated with the username. This would be the same password used for the MongoDB cluster when authentication is enabled.
* For security reasons, passwords are typically not displayed in configurations. Ensure you have it stored securely or consult your MongoDB administrator if unsure.
6. **Permissions:**
* To synchronize the schema in a BI connector when auto-sync is not enabled, it's necessary to manually configure the auto-sync interval. This interval should be adjusted based on the frequency of schema changes; if changes occur frequently, a shorter interval should be set.
# MSSQL
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/mssql
### Getting Started with MSSQL Destination Configuration
#### Requirements:
* Active MSSQL database instance.
* Allow connections from Databrain to your MSSQL database.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Database Accessibility:**
* Ensure your MSSQL database is active and accessible from the machine running Databrain.
* Accessibility is dependent on your MSSQL user privileges and network settings. The easiest way to verify if Databrain can connect to your MSSQL database is via the check connection tool in the UI. For detailed setup and permissions, refer to the MSSQL documentation.
2. **Grant Necessary Permissions:**
* Read Access on Tables and `information_schema`: Grant read access permissions to the tables within MSSQL as well as the `information_schema` schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing MSSQL to enable reading from tables and accessing metadata stored in the `information_schema`.
–- Grant SELECT permission on all tables in the specified schema
GRANT SELECT ON \[schema\_name].\[table\_name] TO \[username]
3. **Fill Up Connection Info:**
* Provide the necessary information to connect to your MSSQL database:
* *Name:* \[Pick a name to help you identify this destination in Databrain]
* *Server:* \[Enter your MSSQL account locator. (e.g., mssql-server.database.windows.net ⤴)]
* *Port:* 1433 (This is the default port for MSSQL databases)
* *Database Name:* \[Name of the database]
* *User:* \[Enter the name of the user you want to use to access the database]
* *Password:* \[Enter the password associated with the username]
### Encryption:
* Ensure you have SSL/TLS set up for your MSSQL database if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
## Locating the Configuration Details in MSSQL
1. **Name:**
* This is a custom name you decide for identification within Databrain. Choose a name that is relevant to your MSSQL setup.
2. **Server:**
* For remote servers, it would be the IP address or domain name of the machine where MSSQL is running.
* If you have access to the MSSQL shell, you can also use the command `SELECT SERVERPROPERTY('MachineName')` to retrieve the server name.
3. **Port:**
* The default port for MSSQL is 1433. However, this can be customized. If you're in the MSSQL shell, you can use the command `SELECT SERVERPROPERTY('Port')` to check the port MSSQL is running on.
4. **Username:**
* The username is the one you use to log in to the MSSQL shell. If you're logged in, you can use the command `SELECT SYSTEM_USER` to display the current user.
5. **Password:**
* The password is associated with your MSSQL username. MSSQL does not provide a direct method to view passwords due to security reasons. If you've forgotten the password, you'll need to reset it or consult your database administrator.
Replace the placeholders inside the square brackets with actual values when filling in the details. This guide will help you configure MSSQL as a destination in Databrain, ensuring smooth data integration and management.
# MySQL
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/mysql
### Getting Started with MySQL Destination Configuration
#### Requirements:
* Active MySQL database instance.
* Allow connections from Databrain to your MySQL database.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide
#### 1. Ensure Database Accessibility:
* Ensure your MySQL database is active and accessible from the machine running Databrain.
* Accessibility is dependent on your MySQL user privileges and network settings. The easiest way to verify if Databrain can connect to your MySQL database is via the check connection tool in the UI. For detailed setup and permissions, refer to the MySQL documentation.
#### 2. Grant Necessary Permissions:
* Read Access on Tables and `information_schema`: Grant read access permissions to the tables within MySQL as well as the `information_schema` schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing MySQL to enable reading from tables and accessing metadata stored in the `information_schema`.
–- Grant SELECT permission on all tables in the specified schema
GRANT SELECT ON `schema_name`.`table_name` TO ;
#### 3. Fill Up Connection Info:
* Provide the necessary information to connect to your MySQL database:
* *Destination Name*: \[Pick a name to help you identify this destination in Databrain]
* *Host*: \[Enter your MySQL account locator]
* *Port*: 3306 (This is the default port for MySQL databases)
* *Username*: \[Enter the name of the user you want to use to access the database]
* *Password*: \[Enter the password associated with the username]
### Locating the Configuration Details in MySQL
1. **Destination Name**
* This is a custom name you decide for identification within Databrain. Choose a name that is relevant to your MySQL setup.
2. **Host**
* For remote servers, it would be the IP address or domain name of the machine where MySQL is running.
* If you have access to the MySQL shell, you can also use the command\
`SHOW VARIABLES WHERE Variable_name = 'hostname';` to retrieve the hostname.
3. **Port**
* The default port for MySQL is `3306`. However, this can be customized. If you're in the MySQL shell, you can use the command\
`SHOW VARIABLES WHERE Variable_name = 'port';` to check the port MySQL is running on.
4. **Username**
* The username is the one you use to log in to the MySQL shell. If you're logged in, you can use the command\
`SELECT USER();` to display the current user.
5. **Password**
* The password is associated with your MySQL username. MySQL does not provide a direct method to view passwords due to security reasons. If you've forgotten the password, you'll need to reset it or consult your database administrator.
# OpenSearch
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/opensearch
## Requirements:
* An Active Opensearch server.
* Allow connections from Databrain to your Opensearch server.
* For guidance on IP whitelisting and secure connectivity, refer to our guide on:
* Choose the appropriate Databrain Workspace to which you want to connect the data.
## Setup Guide:
### 1. Ensure Server Accessibility:
* Ensure your Opensearch server is active and accessible from the machine running Databrain.
* Accessibility depends on your OpenSearch user privileges and network settings.
* To verify connectivity, use the **Check Connection** option in the Databrain UI.
* For detailed setup and permission instructions, refer to the [Opensearch documentation](https://opensearch.org/docs/).
### 2. Fill Up Connection Info:
Provide the necessary information to connect to your Opensearch server:
* **Integration Name**:\
\[Pick a name to help you identify this source in Databrain]
* **Server Type**:\
\[The type of Opensearch server to be used]
* Self-managed (hosted on your own infrastructure)
* OpenSearch Cloud (hosted by OpenSearch service)
* **Authentication Configuration**:
* **Credentials**:\
\[Specify if authentication is enabled. If "Yes", provide the authentication type and credentials below. If "No", you can skip the following authentication details.]
* **Type**:\
\[The type of authentication to be used]
* **Authentication Details** *(if Credentials are enabled)*:
* **Username**:\
\[Basic auth username to access a secure Opensearch server]
* **Password**:\
\[Basic auth password to access a secure Opensearch server]
## Encryption:
* Ensure you have SSL/TLS set up for your Opensearch server if you require encrypted connections from Databrain for enhanced security.
## Permissions:
* Whitelist the IP address.
* Grant read access to the tables.
## Locating the Configuration Details in Opensearch
### 1. Integration Name
This is a custom name you define to help identify the source within Databrain. Use a descriptive, relevant name.
### 2. Server Type
Check your deployment setup:
* If OpenSearch is hosted on your own servers or cloud VMs → **Self-managed**
Refer to your infrastructure or service provider for clarity.
### 3. Credentials
To determine if authentication is required:
* Try accessing your OpenSearch cluster without credentials.
* If it denies access, enable authentication in the Databrain configuration.
### 4. Username & Password *(if authentication is required)*
* Use the **username** configured for secure access.
* You will need the **password** as OpenSearch doesn’t expose stored credentials.
# Postgres
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/postgres
### Getting Started with Postgres Source Configuration
#### Requirements:
* Active Postgres database instance.
* Allow connections from Databrain to your Postgres database.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on:
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Database Accessibility:**
* Ensure your Postgres database is active and accessible from the machine running Databrain.
* Accessibility is dependent on your Postgres user privileges and network settings. The easiest way to verify if Databrain can connect to your Postgres database is via the check connection tool in the UI. For detailed setup and permissions, refer to the Postgres documentation.
2. **Grant Necessary Permissions:**
* Read Access on Tables and `information_schema`: Grant read access permissions to the tables within Postgres as well as the `information_schema` schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing Postgres to enable reading from tables and accessing metadata stored in the `information_schema`.
```sql theme={"dark"}
-- Grant SELECT permission on all tables in the specified schema
GRANT SELECT ON ALL TABLES IN SCHEMA `schema_name` TO `username`
```
3. **Fill Up Connection Info:**
* Provide the necessary information to connect to your Postgres database:
* *Integration Name*: \[Pick a name to help you identify this source in Databrain]
* *Host*: \[Hostname of the database]
* *Port*: 5432 (This is the default port for Postgres databases)
* *Database Name*: \[Name of the database]
* *Username*: \[Username to access the database]
* *Password*: \[Password associated with the username]
* *Schemas*: Defaults to `"public"`. \[Provide a list of schemas (case sensitive) to sync from, if different from the default]
### Encryption:
* *SSL Mode*: \[Specify if the "require\_secure\_transport" parameter is turned on then enable or disable based on it]
* To securely connect to your Postgres instance, you might need to provide SSH details:
* *SSH Host*: \[SSH host endpoint of the SSH instance. Ensure the Databrain IP is whitelisted.]
* *SSH Port*: 22
* *Username*: \[Username to connect to SSH host]
* *Private Key*: \[Private key to authenticate with the SSH host]
* Ensure you have SSL/TLS set up for your Postgres database if you require encrypted connections from Databrain for enhanced security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
Replace the placeholders inside the square brackets with the actual values when filling in the details.
### Locating the Configuration Details in PostgreSQL
1. **Host:**
* For remote PostgreSQL servers, it would be the IP address or domain name of the machine where PostgreSQL is running. You can also check the PostgreSQL configuration file (usually named `postgresql.conf`) for the `listen_addresses` setting to confirm.
2. **Port:**
* The default port for PostgreSQL is `5432`. However, this can be customized. Confirm the specific port your PostgreSQL instance is using by checking the `postgresql.conf` file for the `port` setting.
3. **Database Name:**
* Connect to your PostgreSQL instance and use the command `\l` in the `psql` interface to list all databases.
4. **Username:**
* The credentials you use to access your PostgreSQL database. If you're unsure, consult with the person who set up the PostgreSQL database or your database administrator. Usernames can also be listed by connecting to your database and running the command `\du` in the `psql` interface.
5. **Password:**
* The password associated with the username. This would typically be known by you or set up during the PostgreSQL installation or user creation. PostgreSQL doesn't display passwords for security reasons, so ensure you have it stored securely or reset it if needed.
6. **Schemas:**
* By default, PostgreSQL uses the "public" schema. If you have other schemas in use, connect to your database and run the command `\dn` in the `psql` interface to list them.
7. **SSL Mode:**
* PostgreSQL supports various SSL modes. To check the mode in use, refer to the `postgresql.conf` file for the `sslmode` setting or consult with your database administrator.
# SingleStore
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/singlestore
This guide will walk you through the steps to connect your SingleStore database to Databrain.
### Requirements
* Activate SingleStore account.
* Allow connections from Databrain to your SingleStore account.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on
* Choose the Databrain Workspace to which you wish to connect the data.
### Prerequisites
Before you begin, ensure you have the following information:
* **SingleStore Host** (your account locator)
* **Port** (default: `3333`)
* **Username** (e.g., `your-email@domain.com`)
* **Password** (associated with the username)
* **Database Name** (the target database for synchronization)
### Locating the Configuration Details in SingleStore
To connect SingleStore to Databrain, you need specific details from your SingleStore instance. Follow these steps to locate them:
1. **Log in to SingleStore**
* Open your SingleStore workspace.
* Navigate to the **Admin Portal**.
2. **Find Your Account Locator**
* In the SingleStore portal, go to **Deployments**.
* Select your database instance.
* The **Account Locator** (Host) will be displayed in the connection details.
3. **Retrieve Connection Credentials**
* Go to **Access Control** and find your database user.
* Ensure you have the correct username and password for authentication.
4. **Check the Database Name**
* Open the **Databases** tab in the SingleStore Admin Portal.
* Identify the name of the database you want to sync with Databrain.
### Steps to Connect SingleStore to Databrain
1. **Navigate to SingleStore Configuration**
* Log in to Databrain.
* Go to **Data Sources** and click **Add Data Source**.
* Select **SingleStore** from the list of available connections.
2. **Enter Connection Details**
* **Name**: Enter a name to help you identify the connection (e.g., `SingleStore`).
* **Host**: Provide your SingleStore account locator.
* **Port**: Enter `3333` (or the port assigned to your instance).
* **Username**: Enter the email address or username associated with your SingleStore account.
* **Password**: Enter the password for authentication.
* **Database**: Specify the name of the database you want to sync data into.
3. **Authenticate and Connect**
* Click **Authenticate** to validate the credentials.
4. **Complete the Setup**
* Once connected, you can proceed to configure data sync settings.
* Define tenancy level: database or table
# Snowflake
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/snowflake
### Requirements:
* Active Snowflake account.
* Allow connections from Databrain to your Snowflake account.
* For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide below.
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Account Accessibility:**
* Make sure your Snowflake account is active and accessible from the machine running Databrain.
* This is dependent on your networking setup. The easiest way to verify if Databrain can connect to your Snowflake account is via the Add a Data Source UI.
2. **Grant Necessary Permissions:**
* Read Access on Tables and `information_schema`: Grant read access permissions to the tables within Snowflake as well as the `information_schema` schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing Snowflake to enable reading from tables and accessing metadata stored in the `information_schema`.
–- Grant SELECT permission on all tables in the specified schema
GRANT SELECT ON ALL TABLES IN SCHEMA `schema_name` TO
3. **Fill Up Connection Info:**
* Provide the necessary information to connect to your Snowflake account:
* `Destination Name`: \[Pick a name to help you identify this destination in Databrain]
* `Host`: \[Enter your Snowflake account's locator, typically in the format `..`]
* `Role`: \[The Snowflake user’s role is what allows that user to access tables. In order to query your data, ensure your user has the appropriate roles.]
* `Warehouse`: \[Enter the name of the warehouse you want to sync data into]
* `Database`: \[Enter the name of the database you want to sync data into]
* `Default Schema`: \[Enter the name of the default schema you want to use]
* `Username`: \[Enter the username you want to use to access the database]
* `Password`: \[Enter the associated password]
* **Note on Schema Configuration:**
* If no schema is specified, all tables with permission will be presented regardless of their schema.
### Encryption:
* All Snowflake connections via Databrain are encrypted to ensure security.
### Permissions:
* Permission to read `information_schema`.
* Whitelist the IP address.
* Grant read access to the schema (usage) and tables, noting that access to only tables may not suffice in certain databases.
Replace the placeholders inside the square brackets with actual values when filling in the details.
### Locating the Configuration Details in Snowflake
1. **Host (Account Locator):**
* When you log in to the Snowflake web interface, the URL in your browser's address bar is your account locator. It's typically in the format `..`.
* Example: `vj12833.ap-south-1.aws`
2. **Role:**
* In the Snowflake web UI, on the top right, there's a dropdown that shows the current role. Clicking on it will show you all the roles assigned to you.
3. **Warehouse:**
* Navigate to the 'Warehouses' tab in the Snowflake web UI. This section lists all the warehouses you have access to.
4. **Database:**
* Navigate to the 'Databases' tab in the Snowflake web UI. This section lists all the databases you can access.
5. **Default Schema:**
* Once you're inside a specific database in the Snowflake web UI, you can see the list of schemas.
* The one you typically use or want to set as default for Databrain should be chosen.
6. **Username:**
* The username is the one you use to log in to the Snowflake web UI.
* If you're an admin, you can also find usernames of other users by navigating to the 'Users' tab.
7. **Password:**
* This is the password associated with your Snowflake username.
* For security reasons, Snowflake doesn't display passwords, so you should know this or have it stored securely.
# Trino
Source: https://docs.usedatabrain.com/guides/datasources/connecting-data-sources-to-databrain/trino
### Getting Started with Trino Destination Configuration
### Requirements:
* Active Trino cluster.
* Allow connections from Databrain to your Trino cluster.\
For details on setting up IP whitelisting and ensuring secure connectivity, refer to our guide on:
* Choose the Databrain Workspace to which you wish to connect the data.
### Setup Guide:
1. **Ensure Cluster Accessibility:**
* Make sure your Trino cluster is active and accessible from the machine running Databrain.
* This is dependent on your networking setup. The easiest way to verify if Databrain is able to connect to your Trino cluster is via the Add a Data Source UI.
* For a deeper dive on configuring your cluster's access, you can consult the Trino documentation.
2. **Grant Necessary Permissions:**
* Read Access on Tables and Catalogs: Grant read access permissions to the tables within Trino as well as the system information schema. This allows Databrain to retrieve necessary information and replicate data accurately. You can assign appropriate permissions to the user or role accessing Trino to enable reading from tables and accessing metadata.
* Grant SELECT permission on all tables in the specified schema:\
`GRANT SELECT ON schema_name.* TO USER your_user;`
* Grant access to system information views:\
`GRANT SELECT ON system.information_schema.* TO USER your_user;`
3. **Fill Up Connection Information:**
Provide the necessary information to connect to your cluster:
* **Host/Server**: The hostname or IP address of your Trino coordinator
* **Port**: e.g., `8080` (HTTP) or `8443` (HTTPS)
* **Catalog**: The catalog you want to connect to (e.g., `hive`, `postgresql`, `mysql`)
* **Schema**: The default schema within the catalog (e.g., `default`)
* **Username**: Username to access the database
* **Password**: Password associated with the username (if authentication is enabled)
* **SSL/TLS**: Specify if SSL/TLS encryption is required for the connection
*Note on Catalog and Schema Configuration:*
* **Catalog**: Trino uses catalogs to organize data sources. Each catalog represents a connection to a data source like Hive, PostgreSQL, etc.
* **Default Schema**: This is the default schema tables are accessed from if not explicitly specified. Common values include `default` or `public`.
### Connecting over an SSH tunnel
If your Trino coordinator is not reachable from the internet, DataBrain can connect through an SSH bastion. Enable **SSH Tunnel** on the connection form and fill in both sets of fields — they are separate:
| Field | What to enter |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **SSH Host** | The bastion/jump host's public hostname or IP (the machine DataBrain SSHes into) |
| **SSH Port** | The bastion's SSH port (usually `22`) |
| **SSH Username** | The SSH user on the bastion |
| **SSH Private Key** | The private key for that SSH user |
| **Host/Server** | The Trino coordinator's **internal** hostname or IP, as reachable *from the bastion* (e.g. `trino.internal.local`) — not the bastion itself |
| **Port / Catalog / Schema / Username / Password** | Exactly the same values as a direct connection — the tunnel does not change them |
Common mistake: putting the bastion's address in **Host/Server**. The SSH fields get DataBrain into your network; **Host/Server** must then point at Trino as seen from inside. If you're unsure of the catalog name, run `SHOW CATALOGS` in Trino.
### Encryption:
* Trino supports TLS/SSL encryption for secure connections. Configure HTTPS on port 8443 if encryption is required.
* For private instances, additional network security configurations should be in place for authentication purposes along with Trino credentials.
### Permissions:
* Permission to read system information schema
* Whitelist the IP address
* Grant read access to the catalog and schema, noting that access to only tables may not suffice for proper metadata retrieval.
Replace the placeholders inside the square brackets with actual values when filling in the details.
### Locating the Configuration Details in Trino
1. **Destination Name**
* This is a custom name you decide for identification within Databrain. Choose a descriptive name based on your use case.
2. **Host/Server**
* This is the hostname or IP address where your Trino coordinator is running.
* Check your Trino deployment configuration or consult with your infrastructure team.
3. **Port**
* Typically, this is `8080` for HTTP or `8443` for HTTPS connections. Confirm this in your Trino coordinator configuration.
4. **Catalog**
* Catalogs are defined in your Trino configuration files. Common catalogs include `hive`, `postgresql`, `mysql`, `mongodb`, etc.
* You can view available catalogs by running `SHOW CATALOGS` in the Trino CLI or web UI.
5. **Schema**
* Schemas are specific to each catalog. For Hive catalogs, common schemas include `default`.
* You can view available schemas by running `SHOW SCHEMAS FROM catalog_name` in Trino.
6. **Username & Password**
* These depend on your authentication configuration. Trino supports various authentication methods including LDAP, Kerberos, and password files.
* Consult your Trino administrator or authentication configuration for the correct credentials.
7. **SSL/TLS**
* Check your Trino coordinator configuration to determine if HTTPS is enabled and required for connections.
* If using HTTPS, ensure you're connecting to the correct port (typically 8443) and have proper certificates configured.
# Create Data App
Source: https://docs.usedatabrain.com/guides/datasources/create-a-data-app
This guide provides a straightforward process for creating a Data App, catering to various integration needs such as demonstration, embedded applications, and popular collaboration platforms
**Data App**
A Data App is a data application designed to visualize, analyze, or interact with data. It can serve various purposes, including demonstrations or integration with collaboration platforms.
**Integration Types**
Demo, Embedded, Microsoft Teams Integration, Slack Integration
In the "Data Studio" page, navigate to the "Data Apps" section and click on the "+ New Data App".
* Enter the App Name in the provided field and select the type from:
* `embedded`: For embedded applications
* `msTeams`: For Microsoft Teams integration
* `slack`: For Slack integration
* Then, choose your workspace from the dropdown list.
* Finally, click on **"Save"** to create the data app.
Your new app will appear in the main Data Apps table. You can view its:
* **App Name**
* **Type**
* **Embeds Count**
* **Creation Date**
Your Data App has been successfully created. You can now manage, embed, or integrate it with platforms like Microsoft Teams or Slack directly from the Data Apps dashboard.
# Create a datamart
Source: https://docs.usedatabrain.com/guides/datasources/create-a-datamart
This guide provides a straightforward process for creating a datamart in Databrain, allowing users to efficiently manage and analyze data.
**What is a Datamart?**
A datamart is a specialized subset of a data warehouse designed to cater to the analytical needs of a specific department. It allows users to efficiently manage and analyze relevant data by providing a more focused and optimized dataset.
**Purpose of Datamart**
A datamart solves the problem of managing large and complex datasets by delivering fast query performance and simplified access to data, tailored to the needs of specific departments.
* In the **Data Studio** page of Databrain, navigate to the **Datamarts** section.
* Click on the **+ Data Mart** button in the top right corner.
* Enter a suitable name for your datamart and choose the corresponding datasource from the dropdown list.
* Choose between:
* **Database**: Choose this when your client data is stored at the database level (each client has its own database).
* **Table**: Choose this when your client data is stored as rows identified by an ID column in a single table.
* Click on **Next.**
> Database tenancy refers to organizing and controlling access to data based on specific groups. It ensures that each group can access only their own data, keeping it secure and separate from other.
* Choose the schema that Databrain will use to build your datamart.
* Click on **Next**.
* Use the search box to find specific tables or browse available tables in the schema.
* Select required tables and click **Next.**
* For each column, you can configure:
* **ALIAS** : Create custom names for columns
* **LABEL** : Create Custom names for end user
* **HIDE** : Hide the column for end user
* **COMMON** : Set the column as Common field between databases
* **HIDE TO** : Set visibility options
* **TRANSFORM** : Apply data transformations
* Then, click **Next**.
* Navigate to the **Define Relationships** tab and describe the relationships between the columns and cardinality between the tables.
* Then, specify any other relevant information or important constraints.
* Click on **Next**.
* View the tenancy details if required.
* Finally, click **Complete** to finish the datamart creation.
Your new datamart will appear in the Data Marts list!
# Create Embed
Source: https://docs.usedatabrain.com/guides/datasources/create-embed
Learn how to create embeds for your Data App so you can integrate Databrain into your product experience.
You need at least one existing Data App before you can create embeds.
Navigate to **Data Studio → Data Apps** and select the Data App you want to create an embed for.
In the **Embed Info** section:
* Click the **+ Add New Embed** button.
* Select the **Workspace** where the embed should point.
* Choose the **Embed type** (Dashboard or Metric).
* Select the specific **Dashboard** or **Metric** to embed.
* Click **Save** to create the embed.
Once the embed is created, it appears in the **Embed Info** table. Click the embed name to open its settings, where you can configure:
* Security and access controls
* UI behavior and layout
* Other embed preferences before using it in your application
Your embed is now ready to be used in your application. Use the embed configuration details on this page when integrating Databrain into your frontend.
# Creating a Custom Dataset/View in a Multi-Datasource Environment
Source: https://docs.usedatabrain.com/guides/datasources/creating-a-custom-dataset-view-in-a-multi-datasource-environment
This guide provides essential steps for creating and saving a custom dataset in a multi-datasource environment, ensuring efficient and organized data management.
* Create the desired metric and view the underlying data you wish to save as a custom dataset.
* Click on **"+ Custom Dataset"** at the bottom left corner, then select **"Save to Dataset"** to save the view.
* Enter a suitable title for your dataset and specify a common schema name across the different data sources.
* Select the data sources where you want to save the view.
* Click **"Save"** to finalize the process.
Once saved, you can access and manage the custom dataset in all selected data sources.
* Navigate to the schema browser on the left panel.
* Your saved view (e.g., `id_view`) will now be available under each selected data source.
* Ensure that all selected data sources follow a **consistent schema** across the tables.
Your custom dataset has been successfully created and synchronized across all selected data sources. It’s now available in the schema browser under each source, ensuring consistent and unified data access.
# Edit tenancy
Source: https://docs.usedatabrain.com/guides/datasources/edit-tenancy
This guide provides a straightforward approach to modifying tenancy settings within a datasource connection.
* In the **"Data"** tab, spot the three dots next to a datasource connection and click on it.
* From the dropdown, select **"Edit Tenancy"**.
* In the window that opens up, you'll find all the options you need to tweak your tenancy settings.
* After making the necessary adjustments, ensure you hit the **"Complete"** button.
* This step locks in your updated organization settings, readying them for action.
Tenancy settings have been successfully updated. Your data source is now aligned with the latest configuration, ensuring accurate organization-level data segregation and access control.
# Generate API Key
Source: https://docs.usedatabrain.com/guides/datasources/generate-api-key
Learn how to generate API keys for your Data App so you can authenticate API requests securely.
You need at least one existing Data App before you can generate an API key.
Navigate to **Data Studio → Data Apps** and select the Data App for which you want to create an API key.
In the left sidebar, select **API Token**, then click **Generate Token** in the top-right corner of the API Tokens table.
In the **API Token Settings** panel:
* Enter your **Token name** (for example, your company or integration name).
* Optionally add a **description** to clarify how this key will be used.
* Click **Generate API Key** to create the key for this Data App.
After the key is created, it appears in the API Tokens table. Use the **Copy** action to copy the API key and store it securely.
Your API key is now active for this Data App. Use it in your backend services to authenticate API requests on behalf of this Data App.
# How to Sync a Data Source
Source: https://docs.usedatabrain.com/guides/datasources/how-to-sync-a-datasource
This guide provides a straightforward, step-by-step approach to syncing a data source, ensuring users can efficiently manage their data connections.
* Navigate to the **"Data Studio"** tab in the top menu and click on **"Datasources"** in the left sidebar.
* Select the data source you want to sync.
* Click on **"Sync"** button to save and synchronize the connection.
If you are using the AWS3 data source, click the "Sync Interval" button and specify the time duration to automatically sync your files.
* Make the necessary changes in **"Tenancy Level"**.
* Click **"Complete"** to finish the setup.
Your data source has been successfully synced and configured. Databrain will now automatically keep your data updated based on your selected sync interval.
# Semantic Layer
Source: https://docs.usedatabrain.com/guides/datasources/semantic-layer
This guide provides a comprehensive step-by-step process for building and managing a semantic layer in Databrain's Data Studio, making it essential for data professionals.
**What is a Semantic Layer?**
A semantic layer is a business representation of data and offers a unified and consolidated view of data across an organization.
**Purpose of Semantic Layer**
A semantic layer provides a user-friendly interface that translates complex data structures into understandable business terms, enabling non-technical users to easily access, analyze, and generate insights from data without needing deep technical expertise.
**Key Feature of Databrain's Semantic Layer:**
**Example:** Users can search for "Customer Name" instead of using technical identifiers like `"customer_id."`\
**Context:** It simplifies data access for everyone, making it easier to interpret and analyze.
* In the **"Data Studio"** page of Databrain, navigate to the **"Semantic Layer"** section.
* Click on datamart name for which you want to create the semantic layer.
1. Click on the **"Generate with AI"** icon to automatically view table information.
2. Click on **"Column Info"** tab
3. For each column:
* Add relevant synonyms
* Select appropriate data type
* Include any column-specific notes or constraints
### Synonyms in the Semantic Layer
> **Table Synonyms**\
> **Example:** If your datamart has a table named "Customer Data," appropriate synonyms might include "Client Information," "Customer Records," or "User Profiles."
>
> **Context:** Synonyms help users find the table using different terminologies they may be familiar with, improving accessibility and usability.
> **Column Synonyms**\
> **Example:** For a column labeled "Order Date," synonyms could be "Purchase Date," "Transaction Date," or "Sale Date."
>
> **Context:** By providing synonyms for columns, users can query data more intuitively, using terms that resonate with their understanding of the dataset.
***
> **Functionality:** Users can define relationships between tables, including cardinality (one-to-one, one-to-many), directly within the semantic layer.
> **Context:** This capability ensures that the data model accurately reflects real-world relationships, which is crucial for accurate reporting and analysis. By clearly defining how different datasets relate to each other, users can perform more meaningful analyses.
> **Example:** In a sales database, a one-to-many relationship can be established between a "Customers" table and an "Orders" table, allowing analysts to easily understand that each customer can place multiple orders.
* Access **"Definitions"** tab
* Create analytical questions:
* Click **"+ Definitions"** to add new questions
* Use search functionality to find existing definitions
* Create a definition by clicking on **"+ Definitions"** icon and then export the definitions using the **"Export"** button
***
> **Functionality:** Users can create analytical questions and definitions that are easily searchable within the semantic layer.
> **Context:** This feature streamlines the process of generating insights by allowing users to formulate queries based on predefined definitions rather than starting from scratch each time. It fosters consistency in reporting across the organization.
> **Example:** An analyst might define a metric called "Total Revenue," which aggregates sales from various sources. Other users can then search for this definition when creating their reports, ensuring everyone uses the same calculation method.
After creating the semantic layer, you can perform 3 actions:
* Lab
* Playground
* Sample Set
### Lab
* Synthetic Query - Generate and test queries, and validate query outcomes
* Logs - Review chat mode questions and track query history
* Evals - Add evaluation criteria and monitor performance
### Playground
Access the search bar to test LLM responses and view the results.
### Sample Set
Create sample datasets for the created datamart.
> **Functionality**: The Lab feature provides an environment where users can generate synthetic queries and validate their results against expected outcomes.
> **Context**: This integrated testing capability allows analysts to experiment with different queries safely without affecting live data or reports. It also helps ensure that the semantic layer functions correctly before deploying it for broader use.
> **Example**: An analyst can create a synthetic query to calculate total sales for the last quarter and verify that the results match their expectations before using it in a dashboard or report.
## Programmatic Access
You can also manage the semantic layer programmatically using the Semantic Layer API. This is useful for automating setup across environments, managing semantic metadata in CI/CD pipelines, or bulk-updating descriptions and synonyms.
Full CRUD API for managing semantic layer metadata via REST
Programmatically add descriptions, synonyms, and column types
# Elastic APM Integration
Source: https://docs.usedatabrain.com/guides/elastic-apm-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to Elastic APM
# Integrating Databrain with Elastic APM
This guide explains how to send OpenTelemetry traces, metrics, and logs from your self-hosted Databrain instance to Elastic APM (Application Performance Monitoring).
## Why Elastic APM?
Elastic APM is ideal if you're already using the Elastic Stack (ELK):
* **Unified Platform**: APM data alongside logs and metrics in Kibana
* **OpenTelemetry Support**: Native OTLP ingestion
* **Powerful Querying**: Kibana's full search capabilities
* **Flexible Deployment**: Cloud or self-hosted options
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Elastic Stack 8.0+ (Elasticsearch, Kibana, APM Server)
* APM Server configured for OpenTelemetry
## Option 1: Elastic Cloud (Easiest)
### 1. Set Up Elastic Cloud
1. Sign up for [Elastic Cloud](https://cloud.elastic.co/)
2. Create a deployment (includes Elasticsearch, Kibana, and APM)
3. Note your:
* **Cloud ID**
* **APM endpoint**: `https://.apm..cloud.es.io`
* **Secret token** or **API key**
### 2. Configure Databrain
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# Elastic Cloud APM endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=https://.apm..cloud.es.io
# Elastic APM authentication (use secret token OR API key)
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer YOUR_SECRET_TOKEN
# Service name (appears in Kibana)
OTEL_SERVICE_NAME=databrain-api
# Optional: Set environment
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.version=1.0.0
# Optional: Enable debug logging
LOG_LEVEL=info
```
### 3. Docker Compose Configuration
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://${ELASTIC_DEPLOYMENT_ID}.apm.${ELASTIC_REGION}.cloud.es.io"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "Authorization=Bearer ${ELASTIC_APM_SECRET_TOKEN}"
OTEL_RESOURCE_ATTRIBUTES: "deployment.environment=production,service.version=1.0.0"
LOG_LEVEL: "info"
```
Store credentials in `.env`:
```bash theme={"dark"}
# .env
ELASTIC_DEPLOYMENT_ID=abc123def456
ELASTIC_REGION=us-east-1
ELASTIC_APM_SECRET_TOKEN=your_secret_token_here
```
## Option 2: Self-Hosted Elastic Stack
### 1. Deploy Elastic Stack with Docker Compose
```yaml theme={"dark"}
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=true
- ELASTIC_PASSWORD=changeme
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
networks:
- elastic
restart: unless-stopped
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
container_name: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=changeme
ports:
- "5601:5601"
networks:
- elastic
depends_on:
- elasticsearch
restart: unless-stopped
apm-server:
image: docker.elastic.co/apm/apm-server:8.11.0
container_name: apm-server
command: >
apm-server -e
-E apm-server.rum.enabled=true
-E setup.kibana.host=kibana:5601
-E setup.template.settings.index.number_of_replicas=0
-E apm-server.kibana.enabled=true
-E apm-server.kibana.host=kibana:5601
-E output.elasticsearch.hosts=["elasticsearch:9200"]
-E output.elasticsearch.username=elastic
-E output.elasticsearch.password=changeme
-E apm-server.secret_token=my_secret_token
-E apm-server.auth.secret_token=my_secret_token
ports:
- "8200:8200"
networks:
- elastic
- databrain
depends_on:
- elasticsearch
- kibana
restart: unless-stopped
filebeat:
image: docker.elastic.co/beats/filebeat:8.11.0
container_name: filebeat
user: root
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- elastic
depends_on:
- elasticsearch
restart: unless-stopped
networks:
elastic:
driver: bridge
databrain:
external: true
volumes:
elasticsearch-data:
```
### 2. Configure APM Server for OpenTelemetry
Create `apm-server.yml`:
```yaml theme={"dark"}
apm-server:
host: "0.0.0.0:8200"
# OpenTelemetry configuration
rum:
enabled: true
# Authentication
auth:
secret_token: "my_secret_token"
# Kibana integration
kibana:
enabled: true
host: "http://kibana:5601"
# Elasticsearch output
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
username: "elastic"
password: "changeme"
# Index lifecycle management
setup.ilm:
enabled: true
# Kibana dashboards
setup.dashboards:
enabled: true
# Logging
logging.level: info
logging.to_files: true
```
### 3. Configure Filebeat for Log Ingestion
Create `filebeat.yml`:
```yaml theme={"dark"}
filebeat.inputs:
- type: container
paths:
- '/var/lib/docker/containers/*/*.log'
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
- decode_json_fields:
fields: ["message"]
target: ""
overwrite_keys: true
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
username: "elastic"
password: "changeme"
setup.kibana:
host: "http://kibana:5601"
```
### 4. Start Elastic Stack
```bash theme={"dark"}
docker compose up -d
# Wait for Elasticsearch to be ready
docker logs elasticsearch -f
# Initialize Kibana (first time only)
docker exec -it kibana curl -X POST \
"http://localhost:5601/api/saved_objects/_bulk_get" \
-H "kbn-xsrf: true" \
-H "Content-Type: application/json"
```
### 5. Configure Databrain for Self-Hosted APM
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://apm-server:8200"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "Authorization=Bearer my_secret_token"
LOG_LEVEL: "info"
networks:
- databrain
- elastic
```
## Option 3: Using Elastic APM Agent (Alternative)
If you prefer the native Elastic APM agent over OpenTelemetry:
```bash theme={"dark"}
npm install elastic-apm-node --save
```
Then configure in your application:
```typescript theme={"dark"}
// src/index.ts (at the very top, before other imports)
import apm from 'elastic-apm-node';
if (process.env.ELASTIC_APM_ACTIVE === 'true') {
apm.start({
serviceName: process.env.ELASTIC_APM_SERVICE_NAME || 'databrain-api',
serverUrl: process.env.ELASTIC_APM_SERVER_URL,
secretToken: process.env.ELASTIC_APM_SECRET_TOKEN,
environment: process.env.ELASTIC_APM_ENVIRONMENT || 'production',
logLevel: 'info',
});
}
// ... rest of your application imports and code
```
Environment variables:
```bash theme={"dark"}
ELASTIC_APM_ACTIVE=true
ELASTIC_APM_SERVER_URL=http://apm-server:8200
ELASTIC_APM_SECRET_TOKEN=my_secret_token
ELASTIC_APM_SERVICE_NAME=databrain-api
ELASTIC_APM_ENVIRONMENT=production
```
## Kubernetes Deployment
### Deploy Elastic Cloud on Kubernetes (ECK)
```bash theme={"dark"}
# Install ECK operator
kubectl create -f https://download.elastic.co/downloads/eck/2.10.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/2.10.0/operator.yaml
# Deploy Elasticsearch
cat < 5% for 5 minutes
* **Actions**: Send to Slack/Email/PagerDuty
#### High Latency Alert
* **Rule type**: APM
* **Service**: databrain-api
* **Transaction type**: request
* **Alert when**: Latency threshold is exceeded
* **Threshold**: P95 > 2000ms for 5 minutes
#### Service Down Alert
* **Rule type**: Uptime
* **Monitor**: databrain-api
* **Alert when**: Service is down
* **Check frequency**: Every 1 minute
## Machine Learning (X-Pack)
If you have an Elastic license, enable ML anomaly detection:
1. Go to **Machine Learning** → **Anomaly Detection**
2. Create job for APM:
* **Job type**: APM
* **Service**: databrain-api
* **Analyze**: Response times and throughput
3. ML will automatically detect:
* Unusual latency spikes
* Traffic anomalies
* Error rate changes
## Troubleshooting
| Issue | Solution |
| ------------------ | ------------------------------------------------------------ |
| No data in Kibana | Check APM Server logs: `docker logs apm-server` |
| 401 Unauthorized | Verify secret token matches between Databrain and APM Server |
| Connection refused | Check network connectivity and firewall rules |
| Missing logs | Ensure Filebeat is running and configured correctly |
| High disk usage | Configure ILM (Index Lifecycle Management) policies |
### Debug APM Server
```bash theme={"dark"}
# Check APM Server logs
docker logs apm-server -f
# Check Elasticsearch connectivity
docker exec apm-server curl -u elastic:changeme http://elasticsearch:9200/_cluster/health
# Verify APM Server is receiving data
curl -H "Authorization: Bearer my_secret_token" \
http://localhost:8200/intake/v2/rum/events
```
### Check Elasticsearch Indices
```bash theme={"dark"}
# List APM indices
curl -u elastic:changeme http://localhost:9200/_cat/indices/apm-*
# Check document count
curl -u elastic:changeme http://localhost:9200/apm-*/_count
```
## Index Lifecycle Management (ILM)
Configure ILM to manage disk usage:
1. Go to **Stack Management** → **Index Lifecycle Policies**
2. Edit APM policies:
**APM Traces** (apm-*-transaction, apm-*-span):
* Hot phase: 1 day
* Warm phase: 7 days
* Delete phase: 30 days
**APM Metrics**:
* Hot phase: 3 days
* Warm phase: 14 days
* Delete phase: 90 days
**APM Errors**:
* Hot phase: 7 days
* Warm phase: 30 days
* Delete phase: 90 days
## Best Practices
### 1. Use Index Templates
Customize APM index templates for better performance:
```json theme={"dark"}
PUT _index_template/apm-custom
{
"index_patterns": ["apm-*"],
"priority": 500,
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "5s"
}
}
}
```
### 2. Enable Cross-Cluster Search
For multi-region deployments, use cross-cluster search to aggregate data.
### 3. Use APM Correlations
Let Elastic automatically find correlations between slow transactions and attributes:
1. Go to **APM** → **databrain-api** → **Latency correlations**
2. View attributes that correlate with slow requests
## Cost Optimization
For Elastic Cloud:
* **Optimize data retention**: Use ILM to delete old data
* **Reduce sampling**: Not all traces need to be kept
* **Use smaller instance sizes**: Start small, scale as needed
For self-hosted:
* **Use hot-warm architecture**: Move old data to cheaper storage
* **Enable compression**: Reduce storage by 50-70%
* **Optimize shard size**: 20-50GB per shard is ideal
## Support
* **Elastic Documentation**: [https://www.elastic.co/guide/en/apm/](https://www.elastic.co/guide/en/apm/)
* **Elastic Forum**: [https://discuss.elastic.co/](https://discuss.elastic.co/)
* **Elastic Support**: Available for paid subscriptions
For Databrain configuration issues, contact your Databrain support team.
# Custom SQL Console
Source: https://docs.usedatabrain.com/guides/features/custom-sql-console
### 1. **Access the Custom SQL**
On the **Create Metric** page, select the **"Custom Query"** option.
### 2. **Writing SQL Scripts**
* Enter your SQL code and click **"Run Query"** to generate the chart.
* (Optional) Use the **"Format Query with AI"** option to ensure proper formatting of your query.
* **Query Result** displays the data returned for your SQL query. This data can be downloaded as a CSV file if required.
### 3. **Usage Example**
Below is an example SQL code to visualize the value and quantity of all orders based on the products ordered.
```sql theme={"dark"}
SELECT
AVG("main_procurement_mgmnt_data"."order_value") AS "Avg Order Value",
AVG("main_procurement_mgmnt_data"."order_quantity") AS "Avg Order Quantity",
"main_procurement_mgmnt_data"."product" AS "Product"
FROM
"main"."procurement_mgmnt_data" AS "main_procurement_mgmnt_data"
GROUP BY
"Product"
LIMIT
100
```
### 4. **Output of the above SQL Code**
# Custom SQL Query Guidelines
Source: https://docs.usedatabrain.com/guides/features/custom-sql-query-guidelines
This guide provides best practices for writing well-structured SQL queries to improve readability, maintainability, and performance.
### Formatting Instructions
1. Use consistent indentation (2 or 4 spaces) for nested clauses.
2. Place each major SQL clause (`SELECT`, `FROM`, `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`) on a new line.
3. Write SQL keywords in uppercase for clarity.
4. Align columns, conditions, and `JOIN` clauses vertically when appropriate.
5. Use aliases for all column names, table names, subqueries, and join tables with the `AS` keyword.
6. Choose descriptive and meaningful aliases that accurately represent the data.
7. List each column on a separate line in the `SELECT` clause when selecting multiple columns.
8. Ensure proper spacing around operators and commas.
9. Use table aliases for all table references to improve query readability.
10. For database tenancy, replace all schema references with `{{DATABASE_NAME}}`.
To apply these guidelines to different SQL environments, refer to the sections below:
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column, table, and subquery names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
\*\*Example Use \*\*
**Case**
```
SELECT
SUM("listing_data"."totalprice") AS "sum_of_totalprice", -- ✔ Column Alias with Double Quotes
"public_category"."catname" AS "catname", -- ✔ Column Alias with Double Quotes
"public_event"."eventname" AS "eventname" -- ✔ Column Alias with Double Quotes
FROM
"{{DATABASE_NAME}}"."category" AS "public_category" -- ✔ Table Alias with Double Quotes and Database Reference
INNER JOIN "{{DATABASE_NAME}}"."event" AS "public_event" -- ✔ Join Table Alias with Double Quotes and Database Reference
ON "public_category"."catid" = "public_event"."catid"
INNER JOIN (
SELECT
"listing"."eventid" AS "eventid", -- ✔ Column Alias with Double Quotes
"listing"."totalprice" AS "totalprice" -- ✔ Column Alias with Double Quotes
FROM
"{{DATABASE_NAME}}"."listing" AS "listing" -- ✔ Table Alias with Double Quotes and Database Reference
) AS "listing_data"
ON "public_event"."eventid" = "listing_data"."eventid"
GROUP BY
"public_category"."catname",
"public_event"."eventname"
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
**Example Use Case**
```
SELECT
SUM("databrain_dev2_demo_sales"."quantity sold") AS "sum of quantity sold", -- ✔ Column Alias with Double Quotes
"databrain_dev2_demo_sales"."client name" AS "client name" -- ✔ Column Alias with Double Quotes
FROM
"databrain_dev2"."demo_sales" AS databrain_dev2_demo_sales -- ✔ Table Alias (No Quotes)
INNER JOIN (
SELECT
"customer id",
"sales representative id"
FROM "databrain_dev2"."customer_data"
) AS databrain_dev2_customer_data -- ✔ Subquery Alias (No Quotes)
ON "databrain_dev2_demo_sales"."client name" = "databrain_dev2_customer_data"."customer id"
GROUP BY
"databrain_dev2_demo_sales"."client name"
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`` ` ``**)**
Always use **backticks** for column names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
```
SELECT
SUM(`databrain_dev2_demo_sales`.`quantity sold`) AS `sum of quantity sold`, -- Column Alias with Backtiks
`databrain_dev2_demo_sales`.`client name` AS `client name` -- Column Alias with Backtiks
FROM
`databrain_dev2`.`demo_sales` AS databrain_dev2_demo_sales -- Table Alias (NO BACKTICKS)
INNER JOIN (
SELECT
`customer id`,
`sales representative id`
FROM `databrain_dev2`.`customer_data`
) AS databrain_dev2_customer_data -- Subquery Alias (NO BACKTICKS)
ON `databrain_dev2_demo_sales`.`client name` = `databrain_dev2_customer_data`.`customer id`
GROUP BY
`databrain_dev2_demo_sales`.`client name`
```
\*\*Guideline 1: \*\*Use clear and consistent formatting
\*\*Guideline 2: \*\*Write precise queries
\*\*Guideline 3: \*\*Utilize column aliases
**Example Use Case**
```
SELECT
c.customer_id,
CONCAT(c.last_name, ', ', c.first_name) AS customer_name, -- ✔ Using column alias
a.phone,
f.title AS rented_film -- ✔ Using column alias
FROM
rental r
INNER JOIN customer c ON r.customer_id = c.customer_id -- ✔ Clear formatting with JOIN on new line
INNER JOIN address a ON c.address_id = a.address_id -- ✔ Consistent indentation
INNER JOIN inventory i ON r.inventory_id = i.inventory_id
INNER JOIN film f ON i.film_id = f.film_id
WHERE
r.return_date IS NULL -- ✔ Precise filtering
AND r.rental_date + INTERVAL f.rental_duration DAY < CURRENT_DATE() -- ✔ Specific condition
ORDER BY
c.last_name, c.first_name -- ✔ Major clause on new line
LIMIT 5; -- ✔ Precise result set size
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column, table, and subquery names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
**Example Use Case**
```
SELECT
COUNT("public_posts"."user_id") AS "count of user_id", -- Column Alias with Double Quotes
"public_users"."username" AS "username"
FROM
"public"."users" AS "public_users" -- Table Alias with Double Quotes & Database Reference
INNER JOIN (
SELECT
"user_id",
"id" AS "post_id"
FROM "public"."posts"
) AS "public_posts" -- Subquery Alias with Double Quotes
ON "public_users"."id" = "public_posts"."user_id"
GROUP BY
"public_users"."username"
```
**Guideline 1: Use proper syntax for MongoDB collections and fields**
When querying MongoDB with SQL, wrap collection names and field names in square brackets to avoid syntax errors.
**Guideline 2: Utilize projections to return only necessary dat**a
This improves query performance by limiting the amount of data transferred and processed.
**Guideline 3: Leverage indexing for frequently queried fields**
Create indexes on commonly searched fields to significantly enhance query performance
```
SELECT [first_name], [last_name], [address.city], [transactions]
FROM [Customers]
WHERE [author_name] = 'John Doe'
ORDER BY [timestamp] DESC
LIMIT 10
```
**Guideline 1: Use Aliases for column names**
**Guideline 2: Do not use schema names**
```
SELECT
"first_name" AS "fname",
"last_name" AS "lname",
"city" AS "City"
FROM "customers"
WHERE "created_at" BETWEEN '2025-01-01' AND '2025-03-20'
AND "status" = 'active'
ORDER BY "first_name", "last_name" DESC
LIMIT 10
```
\*\*Guideline 1: \*\*Use specific column names instead of SELECT \*
This reduces the amount of data processed and transferred, speeding up queries.
\*\*Guideline 2: \*\*Utilize WHERE clauses to filter rows early
This reduces the number of rows processed in later stages of the query, improving performance.
**Guideline 3: Implement proper indexing**
Create indexes on frequently queried columns to drastically improve query performance.
```
SELECT o.order_id, c.customer_name, o.order_total
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.order_date >= '2025-01-01' AND o.order_date <= '2025-03-20'
AND c.region = 'North America'
ORDER BY o.order_date DESC
LIMIT 10
```
\*\*Guideline 1: Use Clear and Consistent Aliases for Columns and Tables \*\*
Use descriptive and consistent aliases (with `AS`) for column and table names to improve readability and simplify column references.
**Guideline 2: Enclose Identifiers in Backticks**
Use backticks around column and table names, especially if they contain spaces, special characters, or case sensitivity to avoid parsing errors.
```
SELECT
COUNT(`default_demo_sales`.`customer id`) AS `count of customer id`,
`default_demo_sales`.`store name` AS `store name`,
`default_demo_sales`.`product category` AS `product category`
FROM
`default`.`demo_sales` AS `default_demo_sales`
GROUP BY
`store name`,
`product category`
limit
100
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column, table, and subquery names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
**Example Use Case**
```
SELECT
TOP 100 "dbn_sql_table"."name" AS "name",
"dbn_sql_table"."available" AS "available"
FROM
(
SELECT
TOP 100 "dbo_person"."name" AS "name", -- ✔ Column Alias with Double Quotes
"dbo_pizza_topping"."available" AS "available" -- ✔ Column Alias with Double Quotes
FROM
"dbo"."person" AS "dbo_person" -- ✔ Table Alias with Double Quotes & Database Reference
INNER JOIN (
SELECT
"id",
"available"
FROM
"dbo"."pizza_topping"
) AS "dbo_pizza_topping" -- Subquery Alias
ON "dbo_person"."person_id" = "dbo_pizza_topping"."id"
) AS "dbn_sql_table"
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column, table, and subquery names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
**Example Use Case**
```
SELECT
"main_orders"."order_id" AS "Order ID", -- ✔ Column Alias & Double Quotes
"main_customers"."first_name" AS "First Name", -- ✔ Column Alias & Double Quotes
"main_customers"."last_name" AS "Last Name", -- ✔ Column Alias & Double Quotes
"main_coffees"."name" AS "Coffee Name", -- ✔ Column Alias & Double Quotes
"main_orders"."quantity" AS "Quantity" -- ✔ Column Alias & Double Quotes
FROM
"main"."orders" AS "main_orders" -- ✔ Table Alias, Database Reference & Double Quotes
JOIN "main"."customers" AS "main_customers" -- ✔ Join Table Alias, Database Reference & Double Quotes
ON "main_orders"."customer_id" = "main_customers"."customer_id"
JOIN "main"."coffees" AS "main_coffees" -- ✔ Join Table Alias, Database Reference & Double Quotes
ON "main_orders"."coffee_id" = "main_coffees"."coffee_id"
JOIN (
SELECT
"main_orders"."customer_id" AS "customer_id", -- ✔ Column Alias & Double Quotes
SUM("main_orders"."quantity" * "main_coffees"."price") AS "Amount Spent" -- ✔ Column Alias & Double Quotes
FROM
"main"."orders" AS "main_orders" -- ✔ Table Alias, Database Reference & Double Quotes
JOIN "main"."coffees" AS "main_coffees" -- ✔ Join Table Alias, Database Reference & Double Quotes
ON "main_orders"."coffee_id" = "main_coffees"."coffee_id"
GROUP BY
"main_orders"."customer_id"
) AS "sq" -- ✔ Subquery Alias & Double Quotes
ON "main_orders"."customer_id" = "sq"."customer_id"
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Double Quotes (**`"`**)**
Always use **double quotes** for column, table, and subquery names to avoid conflicts with reserved keywords and case-sensitive identifiers.
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
**Example Use Case**
```
SELECT
SUM("public_levels"."maxpoints") AS "sum of maxpoints", -- ✔ Column Alias with Double Quotes
"public_games"."title" AS "title", -- ✔ Column Alias with Double Quotes
COUNT("public_rankings"."playerid") AS "num_players" -- ✔ Column Alias with Double Quotes
FROM
"public"."games" AS "public_games" -- ✔ Table Alias with Double Quotes & Database Reference
INNER JOIN "public"."levels" AS "public_levels" -- ✔ Join Table Alias with Double Quotes & Database Reference
ON "public_games"."gameid" = "public_levels"."gameid"
INNER JOIN (
SELECT DISTINCT "gameid", "playerid"
FROM "public"."rankings"
WHERE "totalscore" > 0
) AS "public_rankings" -- Subquery with Alias
ON "public_games"."gameid" = "public_rankings"."gameid"
GROUP BY
"public_games"."title"
```
**Guideline 1: Use Aliases for Readability**
Always use **aliases** for column names, table names, subqueries, and join tables using the `AS` keyword. Aliases improve readability and make queries more concise.
**Guideline 2: Enclose Identifiers in Backticks (**`` ` ``**)**
Database names, table names, and column names should be enclosed in **backticks (\`).**
**Guideline 3: Reference Tables with the Database Name**
Always **prefix tables** with the database and schema name to ensure clarity, especially in multi-schema databases.
```
SELECT
SUM(`public_levels`.`maxpoints`) AS `sum_of_maxpoints`, -- ✔ Column Alias with Backticks
`public_games`.`title` AS `title`, -- ✔ Column Alias with Backticks
COUNT(`public_rankings`.`playerid`) AS `num_players` -- ✔ Column Alias with Backticks
FROM
`public`.`games` AS `public_games` -- ✔ Table Alias with Backticks & Database Reference
INNER JOIN `public`.`levels` AS `public_levels` -- ✔ Join Table Alias with Backticks & Database Reference
ON `public_games`.`gameid` = `public_levels`.`gameid`
INNER JOIN (
SELECT DISTINCT `gameid`, `playerid`
FROM `public`.`rankings`
WHERE `totalscore` > 0
) AS `public_rankings` -- Subquery with Alias
ON `public_games`.`gameid` = `public_rankings`.`gameid`
GROUP BY
`public_games`.`title`;
```
\*\*Guideline 1: Use Clear and Consistent Aliases for Columns and Tables \*\*
Use descriptive and consistent aliases (with `AS`) for column and table names to improve readability and simplify column references.
**Guideline 2: Enclose Identifiers in Backticks**
Use backticks around column and table names, especially if they contain spaces, special characters, or case sensitivity to avoid parsing errors.
```
SELECT
`store_state` AS `store_state`,
`store_city` AS `store_city`,
`store_name` AS `store_name`,
SUM(`product_stock_level`) AS `sum_of_product_stock_level`
FROM
`demo_sales_dot` AS `demo_sales_dot_demo_sales_dot`
GROUP BY
`store_state`,
`store_city`,
`store_name`
LIMIT
100
```
To automatically correct and format your SQL query, click the **“Format Query with AI”** icon. This converts your SQL into DataBrain’s preferred format, ensuring proper syntax, clear indentation, and better readability.
# Python Editor Console
Source: https://docs.usedatabrain.com/guides/features/python-editor-console
## Introduction
This document provides detailed guidelines on using the integrated Python editor console within our platform. The editor is pre-configured with essential libraries and functionalities to assist in executing Python scripts effectively, particularly for data querying and handling secrets.
## Where to find the Python Editor Console?
* In the **Create Metric** page, click on the **"Custom Query"** option located at the top left side of the page.
* Then, choose **`> Python`** from the dropdown in the **`> Query Editor`** panel to access our Python Editor Console.
## Pre-installed Libraries
* **Requests Module**: The `requests` library is readily available and pre-imported for HTTP requests.\
You do not need to import it again in your scripts.
```python theme={"dark"}
import requests # This module is already available in the scope
```
## Working with Variables
To integrate dynamic data within your scripts, you can utilize predefined variables and data structures:
* **Client ID**: Use the variable `client_id` which should be a string representing the client identifier.
* **Metric Filters**: This variable `metric_filters` allows for the filtering of data based on various criteria. The structure of `metric_filters` is defined as follows:
```python theme={"dark"}
from typing import Dict, Optional, Union
import datetime
class DateDict:
startDate: datetime.date
endDate: datetime.date
# MetricFilters type annotation
MetricFilters = Dict[str, Union[DateDict, str, int]]
```
The `metric_filters` variable can include filters of types `STRING`, `DATE`, and `NUMBER`, uniquely identified by a filter name:
* **STRING**: A plain string value.
* **DATE**: A dictionary containing `startDate`and `endDate`, both of `datetime.date` type.
* **NUMBER**: An integer value.
**When is metric\_filters populated?**\
`metric_filters` is populated only when (1) the metric's SQL query **actually uses** that filter variable (e.g. in a WHERE clause), and (2) the metric is run **in a dashboard context** where that filter is applied and the user has selected a value. If you see empty `{}` even when a filter is selected, check that the metric's SQL references the filter variable by the exact name, and that you are running from a dashboard view with the filter applied—not from a standalone console or a metric that does not use the filter.
### Handling Secrets
Secrets are stored and accessed via the `secrets` dictionary. This allows secure storage and retrieval of sensitive data such as API keys or database credentials. You can set up your secrets in the **Home Page → Settings Tab → Secrets**.
```python theme={"dark"}
url = secrets['BASE_URL'] # Accessing the base URL stored in secrets
res = requests.get(url).json() # Making a GET request using the retrieved URL
```
### Storing Results
To store or output data from your script, assign your data to the `result`variable. This variable should be an array of objects (or a list of dictionaries in Python terms):
```python theme={"dark"}
result = [{'key': 'value'}, ...] # An example assignment to the result variable
result = requests.get('SOME URL').json() # Storing JSON response from a GET request
```
### Usage Example
Here’s are some quick examples demonstrating how to utilize these capabilities:
```python theme={"dark"}
country_population = {
'USA': 331000000,
'India': 1380000000,
'China': 1430000000,
'Brazil': 212600000,
'Nigeria': 206000000
}
result = [{'country': country, 'population': population} for country, population in country_population.items()]
```
```python theme={"dark"}
# Assuming client_id and metric_filters are predefined
client_id = '12345'
metric_filters = {'salesDate': {'startDate': datetime.date(2021, 1, 1), 'endDate': datetime.date(2021, 12, 31)}}
# Accessing a secret
api_url = secrets['API_URL']
# Making a GET request
response = requests.get(f"{api_url}/data?client_id={client_id}").json()
# Assigning response to result
result = response
```
This guide should help you effectively utilize the Python editor console for your data handling needs. The capabilities outlined here are designed to enhance the security, flexibility, and efficiency of your data manipulation tasks.
# Python Query Guidelines
Source: https://docs.usedatabrain.com/guides/features/python-query-guidelines
Best practices for writing clean, maintainable, and production-ready Python queries in Databrain.
Before writing your Python query, note the following runtime assumptions:
1. The `requests` module is already available in scope.
2. The following variables are available:
* `client_id` → string
* `metric_filters` → filter configuration object
3. Secrets are available through:
* `secrets["SECRET_NAME"]`
4. The final output must be assigned to a variable named `result`.
5. The output must be:
* an array of objects
* or a list of dictionaries
## Metric Filters Structure
Use the following structure when working with metric filters in your query:
```python theme={"dark"}
from typing import Dict, Union
import datetime
class DateDict:
startDate: datetime.date
endDate: datetime.date
MetricFilters = Dict[str, Union[DateDict, str, int]]
```
## Formatting Instructions
1. Use consistent indentation (4 spaces).
2. Follow PEP8 naming conventions.
3. Use descriptive variable names.
4. Avoid hardcoded values; use variables and secrets instead.
5. Add whitespace between logical blocks.
6. Use helper variables to improve readability.
7. Handle filters dynamically instead of hardcoding them.
8. Avoid unnecessary global variables.
9. Use exception handling for API calls when possible.
10. Always assign output to the `result` variable.
## Core Usage Guidelines
### Guideline 1: Import `requests`
The `requests` module is already available and does not need installation, but you should still import it for clarity:
```python theme={"dark"}
import requests
```
### Guideline 2: Use Runtime Variables
Use the available runtime variables instead of hardcoding values:
```python theme={"dark"}
payload = {
"clientId": client_id,
}
```
### Guideline 3: Use Metric Filters Dynamically
Handle `metric_filters` generically based on type to support both date ranges and simple values:
```python theme={"dark"}
query_filters = {}
for key, value in metric_filters.items():
if isinstance(value, dict):
query_filters[key] = {
"startDate": value["startDate"].isoformat(),
"endDate": value["endDate"].isoformat(),
}
else:
query_filters[key] = value
```
### Guideline 4: Use Secrets Securely
Always retrieve sensitive information using `secrets`:
```python theme={"dark"}
base_url = secrets["BASE_URL"]
api_key = secrets["API_KEY"]
```
### Guideline 5: Structure API Calls Clearly
Build headers and API calls in a clear, readable way:
```python theme={"dark"}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
response = requests.get(base_url, headers=headers, params=query_filters)
data = response.json()
```
### Guideline 6: Transform Data Before Returning
Ensure your output matches the required format before assigning it to `result`:
```python theme={"dark"}
result = [
{
"key": item["name"],
"value": item["value"],
}
for item in data
]
```
## Output Requirements
Your script **must** end by assigning to `result` using one of the following patterns:
```python theme={"dark"}
result = [{"key": "value"}, ...]
```
or:
```python theme={"dark"}
result = requests.get("SOME_URL").json()
```
# Dashboard Filter
Source: https://docs.usedatabrain.com/guides/filters/dashboard-filter
In this page we will explain you how you can create filters for the dashboard metrics
### Creating a Dashboard Filter in DataBrain
To add a dashboard filter, click on the **"+"** sign located below the dashboard's name. Start by selecting the datatype for the filter, which will influence the available filter option types—auto, manual, or custom. Note that the option type may vary based on the selected datatype.
#### Customizations Based on Datatype:
* **Filter Variant**: Choose between single select, multi-select, or search options for how users can interact with the filter.
* **Select Default Value**: Automatically select a default value or allow users to choose one. This setting depends on the datatype.
* **Scope to Client**: Filter options will be tailored based on the client. This ensures that filter choices are relevant to a specific client’s data context.
* **Label Column Setup**: Configure a label column that displays descriptive labels for the values being filtered. This enhances readability and user understanding of what each filter value represents.
***
### Dependent Filters
Use dependent filters when the available options in one filter should be constrained by the selection in another filter (for example, **Store City** depending on **Store State**).
#### Columns from Same Table
Create two filters (**Store State** and **Store City**) on the same dataset, and configure **Store City** to depend on **Store State**.
**Store State**
**Store City depends on Store State**
#### Columns from Different Tables
When the top-level and dependent filters use columns from different tables, configure the dependency using a custom SQL query that joins the tables.
**Step 1: Configure the Top-Level Filter**
Set up the first-level filter as you normally would.
**Step 2: Configure the Dependent (Second-Level) Filter**
For the second-level filter (which needs to depend on the first filter), select **Custom** as the filter type and write the SQL in the following format:
```sql theme={"dark"}
SELECT
Concat_ws(
' ',
"main_customers"."first_name",
"main_customers"."last_name"
) AS "name", /* Label for this filter */
"main_customers"."customer_id" AS "customer_id", /* Column for this filter */
"main_coffees"."coffee_id" AS "coffee_id" /* Connecting column between Level 1 and Level 2 */
```
```sql theme={"dark"}
FROM
"main"."coffees" AS "main_coffees"
INNER JOIN "main"."orders" AS "main_orders"
ON "main_coffees"."coffee_id" = "main_orders"."coffee_id"
INNER JOIN "main"."customers" AS "main_customers"
ON "main_orders"."customer_id" = "main_customers"."customer_id"
```
Make sure the query includes the connecting column between Level 1 and Level 2.
The necessary joins are added to establish the relationship between the two filter tables.
**Step 3: Configure Dependency**
In the filter setup, you will see that the column from Level 1 is part of the above query.
* In **Advanced Options**, under **Depend On**, type the connecting column from Filter 1 to ensure linkage.
This ensures that Filter 2 is correctly dependent on Filter 1.
***
#### Applying the Filter:
Once the filter settings are configured, decide where to apply these filters within the dashboard:
* **Direct Apply**: Immediately apply the filter to the dashboard elements.
* **Variable for Custom SQL**: Obtain a variable that can be used in your custom SQL queries, allowing for more tailored data interactions.
For a detailed guide on Variable Apply On, kindly refer the below link:
View detailed guide on how to use Variable Apply On for filters.
* **Custom SQL**: Directly write the left-hand side (LHS) equals the right-hand side (RHS) condition in the WHERE clause of your SQL query.
After setting up the filters and their application, click 'Save' to finalize and activate them on the dashboard. This process enhances data interaction, making your dashboard more dynamic and suited to specific analytical needs.
# Metric Filter
Source: https://docs.usedatabrain.com/guides/filters/metric-filter
A metric-level filter is a metric-specific filter that can be applied to a particular metric only and cannot reuse for other metrics.
### Creating a Metric Filter in DataBrain
To add a filter to a specific metric card, navigate to the create/update metric page. Click on the **"+"** sign located below the icons for grouping, sorting, and funneling. This process will initiate the setup for applying a filter directly to an individual metric card.
#### Setup Process:
The setup for a metric filter follows the same guidelines as setting up a dashboard filter, with the primary difference being the scope of application—here, the filter is applied to a single metric card instead of the entire dashboard.
#### Customizations Based on Datatype:
* **Filter Variant**: Choose from single select, multi-select, or search options to define how users interact with the filter.
* **Select Default Value**: Optionally auto-select a default value based on the datatype, or allow manual selection.
* **Scope to Client**: Ensure filter options are tailored based on the client, making them relevant to the specific data context.
* **Label Column Setup**: Set up a label column to display descriptive labels for the values being filtered, enhancing user understanding.
***
### Dependent Filters
**Dependent Filters**: Create dependencies between filters, such as linking a ‘State’ filter to a ‘Country’ filter, to maintain contextual relevance.
#### Columns from Same Table
Create two filters (**Store State** and **Store City**) and configure **Store City** to depend on **Store State**.
**Store State**
**Store City depends on Store State**
#### Columns from Different Tables
**Step 1: Configure the Top-Level Filter**
Set up the first-level filter as you normally would.
**Step 2: Configure the Dependent (Second-Level) Filter**
For the second-level filter (which needs to depend on the first filter), select the appropriate option type and write the SQL in the following format:
```sql theme={"dark"}
SELECT
Concat_ws(
' ',
"main_customers"."first_name",
"main_customers"."last_name"
) AS "name", /* Label for this filter */
"main_customers"."customer_id" AS "customer_id", /* Column for this filter */
"main_coffees"."coffee_id" AS "coffee_id" /* Connecting column between Level 1 and Level 2 */
```
```sql theme={"dark"}
FROM
"main"."coffees" AS "main_coffees"
INNER JOIN "main"."orders" AS "main_orders"
ON "main_coffees"."coffee_id" = "main_orders"."coffee_id"
INNER JOIN "main"."customers" AS "main_customers"
ON "main_orders"."customer_id" = "main_customers"."customer_id"
```
Make sure the query includes the connecting column between Level 1 and Level 2 to facilitate the Depends On configuration.
The necessary joins are added to establish the relationship between the two filter tables.
**Step 3: Configure Dependency**
In the filter setup, you will see that the column from Level 1 is part of the above query.
* In **Advanced Options**, under **Depends On**, choose the Level 1 filter and specify the connecting column from Filter 1 to ensure linkage.
Now, this should ensure that Filter 2 is dependent on Filter 1.
***
#### Applying the Filter:
Choose how to implement the filter on the metric card:
* **Direct Apply**: Apply the filter directly to the metric card for immediate effect.
* **Variable for Custom SQL**: Use a variable from the filter setup in your custom SQL queries for more tailored interactions within the metric.
For a detailed guide on how to use Variable Apply for metric filters.
* **Custom SQL**: Write custom SQL directly, specifying conditions in the WHERE clause to integrate the filter into data queries.
For a detailed guide on applying metric filters using Custom SQL.
After configuring the filter settings, finalize by clicking 'Save'. This action applies the filter to the selected metric card, enhancing its interactivity and relevance to specific data insights. This targeted approach allows for precise data filtering on individual metrics, optimizing the analytical capabilities of each metric card within the dashboard.
# What is Databrain?
Source: https://docs.usedatabrain.com/guides/getting-started-with-databrain/what-is-databrain
> Databrain is a single SDK that lets SaaS companies build customer facing analytics and reporting 10X faster, without a data or dev ops team. Databrain's value lies in helping engineering and product teams stay focused on core features without needing to constantly servicing additional BI features from their customers. With Databrain's dashboards, SaaS companies can go to market faster and unlock new revenue by building & launching enterprise-grade reporting & analytics.
# Grafana Cloud Integration
Source: https://docs.usedatabrain.com/guides/grafana-cloud-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to Grafana Cloud
# Integrating Databrain with Grafana Cloud
This guide explains how to send OpenTelemetry traces, metrics, and logs from your self-hosted Databrain instance to Grafana Cloud.
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Grafana Cloud account (free tier available)
* Grafana Cloud API token
## What You'll Get
Grafana Cloud provides three integrated observability products:
| Product | Purpose | What It Shows |
| ----------------- | ------------------- | ---------------------------------------------- |
| **Grafana Tempo** | Distributed tracing | Request traces with spans and timing |
| **Grafana Loki** | Log aggregation | Structured logs with trace correlation |
| **Prometheus** | Metrics | Request rates, latency histograms, error rates |
## Configuration
### 1. Get Your Grafana Cloud Credentials
1. Log into [Grafana Cloud](https://grafana.com/auth/sign-in/)
2. Navigate to your stack (e.g., `yourstack.grafana.net`)
3. Go to **Connections** → **Add new connection** → **OpenTelemetry**
4. Note the following:
* **Tempo endpoint**: `tempo-.grafana.net:443`
* **Prometheus endpoint**: `prometheus-.grafana.net:443`
* **Loki endpoint**: `logs-.grafana.net`
* **Instance ID**: Your unique instance identifier
* **API Token**: Generate one under **Access Policies**
### 2. Using Grafana Alloy (Recommended)
Grafana Alloy is the easiest way to send telemetry to Grafana Cloud. It replaces the generic OpenTelemetry Collector.
#### Docker Compose Configuration
```yaml theme={"dark"}
services:
grafana-alloy:
image: grafana/alloy:latest
restart: always
volumes:
- ./alloy-config.alloy:/etc/alloy/config.alloy
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "12345:12345" # Alloy UI
environment:
- GRAFANA_CLOUD_TEMPO_ENDPOINT=tempo-us-central1.grafana.net:443
- GRAFANA_CLOUD_PROMETHEUS_ENDPOINT=prometheus-us-central1.grafana.net/api/prom/push
- GRAFANA_CLOUD_LOKI_ENDPOINT=logs-prod-us-central1.grafana.net/loki/api/v1/push
- GRAFANA_CLOUD_INSTANCE_ID=123456
- GRAFANA_CLOUD_API_KEY=${GRAFANA_CLOUD_API_KEY}
networks:
- databrain
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://grafana-alloy:4318"
OTEL_SERVICE_NAME: "databrain-api"
LOG_LEVEL: "info"
depends_on:
- grafana-alloy
```
#### Alloy Configuration
Create `alloy-config.alloy`:
```hcl theme={"dark"}
// OTLP Receiver
otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
traces = [otelcol.processor.batch.default.input]
metrics = [otelcol.processor.batch.default.input]
logs = [otelcol.processor.batch.default.input]
}
}
// Batch Processor
otelcol.processor.batch "default" {
timeout = "1s"
send_batch_size = 1024
output {
traces = [otelcol.exporter.otlp.tempo.input]
metrics = [otelcol.exporter.prometheus.default.input]
logs = [otelcol.exporter.loki.default.input]
}
}
// Tempo (Traces) Exporter
otelcol.exporter.otlp "tempo" {
client {
endpoint = env("GRAFANA_CLOUD_TEMPO_ENDPOINT")
auth = otelcol.auth.basic.grafana_cloud.handler
}
}
// Prometheus (Metrics) Exporter
otelcol.exporter.prometheus "default" {
forward_to = [prometheus.remote_write.grafana_cloud.receiver]
}
prometheus.remote_write "grafana_cloud" {
endpoint {
url = "https://${env("GRAFANA_CLOUD_PROMETHEUS_ENDPOINT")}"
basic_auth {
username = env("GRAFANA_CLOUD_INSTANCE_ID")
password = env("GRAFANA_CLOUD_API_KEY")
}
}
}
// Loki (Logs) Exporter
otelcol.exporter.loki "default" {
forward_to = [loki.write.grafana_cloud.receiver]
}
loki.write "grafana_cloud" {
endpoint {
url = "https://${env("GRAFANA_CLOUD_LOKI_ENDPOINT")}"
basic_auth {
username = env("GRAFANA_CLOUD_INSTANCE_ID")
password = env("GRAFANA_CLOUD_API_KEY")
}
}
}
// Basic Auth
otelcol.auth.basic "grafana_cloud" {
username = env("GRAFANA_CLOUD_INSTANCE_ID")
password = env("GRAFANA_CLOUD_API_KEY")
}
```
### 3. Alternative: Direct OTLP to Grafana Cloud
You can also send data directly without Alloy (less flexible):
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://tempo-us-central1.grafana.net:443"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "authorization=Basic $(echo -n '${GRAFANA_INSTANCE_ID}:${GRAFANA_API_KEY}' | base64)"
```
**Note**: This sends traces only. For metrics and logs, use Alloy.
### 4. Kubernetes with Grafana Agent
For Kubernetes, use the Grafana Agent Operator:
```yaml theme={"dark"}
apiVersion: v1
kind: Secret
metadata:
name: grafana-cloud-credentials
namespace: monitoring
type: Opaque
stringData:
instance-id: "123456"
api-key: "your-grafana-cloud-api-key"
---
apiVersion: monitoring.grafana.com/v1alpha1
kind: GrafanaAgent
metadata:
name: grafana-agent
namespace: monitoring
spec:
image: grafana/agent:latest
integrations:
selector:
matchLabels:
agent: grafana-agent
logs:
instanceSelector:
matchLabels:
agent: grafana-agent
metrics:
instanceSelector:
matchLabels:
agent: grafana-agent
---
apiVersion: monitoring.grafana.com/v1alpha1
kind: Integration
metadata:
name: opentelemetry
namespace: monitoring
spec:
name: otel
type: otel
config:
receivers:
otlp:
protocols:
http:
endpoint: "0.0.0.0:4318"
grpc:
endpoint: "0.0.0.0:4317"
exporters:
otlp/tempo:
endpoint: "tempo-us-central1.grafana.net:443"
auth:
authenticator: basicauth/grafana_cloud
prometheusremotewrite:
endpoint: "https://prometheus-us-central1.grafana.net/api/prom/push"
basic_auth:
username: "123456"
password: "${GRAFANA_API_KEY}"
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp/tempo]
metrics:
receivers: [otlp]
exporters: [prometheusremotewrite]
```
## Verification
### 1. Check Alloy Status
Visit the Alloy UI: `http://localhost:12345`
You should see:
* Active OTLP receivers
* Successful exports to Grafana Cloud
### 2. Generate Test Traffic
```bash theme={"dark"}
curl -X GET "https://your-databrain-instance.com/api/health"
```
### 3. View in Grafana Cloud
#### Tempo (Traces)
1. Go to **Explore** in Grafana
2. Select **Tempo** as the data source
3. Query: `{service.name="databrain-api"}`
4. You should see traces within 1-2 minutes
#### Prometheus (Metrics)
1. Go to **Explore**
2. Select **Prometheus** as the data source
3. Query: `rate(http_server_duration_milliseconds_count{service_name="databrain-api"}[5m])`
#### Loki (Logs)
1. Go to **Explore**
2. Select **Loki** as the data source
3. Query: `{service_name="databrain-api"}`
4. Click on any log to see correlated traces
## Creating Dashboards
### Pre-built Dashboard
Import the OpenTelemetry APM dashboard:
1. Go to **Dashboards** → **New** → **Import**
2. Use dashboard ID: `19419` (OpenTelemetry APM)
3. Select your Tempo and Prometheus data sources
4. Filter by `service_name = databrain-api`
### Custom Dashboard Example
Create a new dashboard with these panels:
**Request Rate:**
```promql theme={"dark"}
rate(http_server_duration_milliseconds_count{service_name="databrain-api"}[5m])
```
**Average Latency:**
```promql theme={"dark"}
rate(http_server_duration_milliseconds_sum{service_name="databrain-api"}[5m])
/
rate(http_server_duration_milliseconds_count{service_name="databrain-api"}[5m])
```
**Error Rate:**
```promql theme={"dark"}
rate(http_server_duration_milliseconds_count{service_name="databrain-api",http_status_code=~"5.."}[5m])
```
**P95 Latency:**
```promql theme={"dark"}
histogram_quantile(0.95,
rate(http_server_duration_milliseconds_bucket{service_name="databrain-api"}[5m])
)
```
## Setting Up Alerts
### Grafana Alerting
Create alert rules in Grafana:
**High Error Rate:**
1. Go to **Alerting** → **Alert rules** → **New alert rule**
2. Query:
```promql theme={"dark"}
(rate(http_server_duration_milliseconds_count{service_name="databrain-api",http_status_code=~"5.."}[5m])
/
rate(http_server_duration_milliseconds_count{service_name="databrain-api"}[5m]))
> 0.05
```
3. Threshold: Alert when value > 0.05 (5% errors)
4. Add notification channel (email, Slack, PagerDuty)
**High Latency:**
```promql theme={"dark"}
histogram_quantile(0.95,
rate(http_server_duration_milliseconds_bucket{service_name="databrain-api"}[5m])
) > 2000
```
## Trace Exemplars
Link metrics to traces using exemplars:
```yaml theme={"dark"}
# In alloy-config.alloy, add to Prometheus exporter
prometheus.remote_write "grafana_cloud" {
endpoint {
url = "https://${env("GRAFANA_CLOUD_PROMETHEUS_ENDPOINT")}"
basic_auth {
username = env("GRAFANA_CLOUD_INSTANCE_ID")
password = env("GRAFANA_CLOUD_API_KEY")
}
# Enable exemplars
send_exemplars = true
}
}
```
Now when viewing metrics, you can click on data points to see example traces.
## LogQL Queries
Use LogQL to query structured logs in Loki:
**All errors:**
```logql theme={"dark"}
{service_name="databrain-api"} | json | level="error"
```
**Slow requests (>1s):**
```logql theme={"dark"}
{service_name="databrain-api"} | json | duration > 1000
```
**Logs for specific user:**
```logql theme={"dark"}
{service_name="databrain-api"} | json | userId="123"
```
**Logs with trace context:**
```logql theme={"dark"}
{service_name="databrain-api"} | json | trace_id!=""
```
## Troubleshooting
| Issue | Solution |
| ------------------------ | --------------------------------------------- |
| No data in Grafana Cloud | Check Alloy logs: `docker logs grafana-alloy` |
| 401 Unauthorized | Verify Instance ID and API Key are correct |
| Connection timeout | Check firewall allows outbound HTTPS (443) |
| Missing traces in Tempo | Wait 2-3 minutes for ingestion delay |
| High costs | Implement sampling in Alloy configuration |
### Debug Alloy
Check Alloy logs:
```bash theme={"dark"}
docker logs grafana-alloy | grep -i error
```
View Alloy UI metrics:
```
http://localhost:12345/
```
### Test Connectivity
```bash theme={"dark"}
# Test Tempo endpoint
curl -v https://tempo-us-central1.grafana.net:443
# Test with auth
curl -u "${INSTANCE_ID}:${API_KEY}" \
https://tempo-us-central1.grafana.net:443/status
```
## Cost Optimization
Grafana Cloud free tier includes:
* **Tempo**: 50 GB traces/month
* **Loki**: 50 GB logs/month
* **Prometheus**: 10k active series
**Tips to stay within limits:**
1. **Sampling**: Sample traces in Alloy
```hcl theme={"dark"}
otelcol.processor.probabilistic_sampler "default" {
sampling_percentage = 10 // Sample 10%
output {
traces = [otelcol.exporter.otlp.tempo.input]
}
}
```
2. **Filter low-value logs**: Exclude health checks
```hcl theme={"dark"}
otelcol.processor.filter "exclude_healthchecks" {
traces {
span = ["attributes[\"http.target\"] == \"/health\""]
}
}
```
3. **Set retention**: Adjust in Grafana Cloud settings
* Tempo: Default 7 days
* Loki: Default 30 days
* Prometheus: Default 13 months
## Best Practices
### 1. Use Service Graph
Enable service graph in Tempo to visualize service dependencies:
1. Go to **Tempo** → **Service Graph**
2. View request flow between services
3. Identify bottlenecks and failures
### 2. Correlate Logs with Traces
When logging, Winston automatically includes trace context:
```json theme={"dark"}
{
"level": "info",
"message": "Processing order",
"orderId": "123",
"trace_id": "abc123",
"span_id": "def456"
}
```
In Loki, click the trace ID to jump to the full trace in Tempo.
### 3. Use Grafana Oncall
Integrate with Grafana Oncall for advanced alert management:
* On-call rotations
* Escalation policies
* Alert grouping and deduplication
## Support
* **Grafana Community**: [https://community.grafana.com/](https://community.grafana.com/)
* **Grafana Cloud Support**: Available for paid plans
* **Documentation**: [https://grafana.com/docs/grafana-cloud/](https://grafana.com/docs/grafana-cloud/)
* **Alloy Docs**: [https://grafana.com/docs/alloy/](https://grafana.com/docs/alloy/)
For Databrain configuration issues, contact your Databrain support team.
# Honeycomb Integration
Source: https://docs.usedatabrain.com/guides/honeycomb-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to Honeycomb
# Integrating Databrain with Honeycomb
This guide explains how to send OpenTelemetry traces and events from your self-hosted Databrain instance to Honeycomb.
## Why Honeycomb?
Honeycomb is purpose-built for OpenTelemetry and excels at:
* **High-cardinality data**: Query on any attribute combination
* **BubbleUp**: Automatically surface anomalies and outliers
* **Distributed tracing**: Full request lifecycle visibility
* **Real-time analysis**: Sub-second query performance
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Honeycomb account (free tier available)
* Honeycomb API key
## Configuration
### 1. Get Your Honeycomb API Key
1. Log into [Honeycomb](https://ui.honeycomb.io/)
2. Go to **Account** → **Team Settings** → **API Keys**
3. Create a new API key or copy an existing one
4. Note your **dataset name** (or create a new one)
### 2. Configure Databrain Environment Variables
Honeycomb supports OpenTelemetry natively, making configuration simple:
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# Honeycomb OTLP endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443
# Honeycomb API key
OTEL_EXPORTER_OTLP_HEADERS=x-honeycomb-team=YOUR_API_KEY_HERE
# Service name (appears in Honeycomb)
OTEL_SERVICE_NAME=databrain-api
# Optional: Honeycomb dataset (defaults to service name)
HONEYCOMB_DATASET=databrain-production
# Optional: Enable debug logging
LOG_LEVEL=info
```
### 3. Docker Compose Configuration
Update your `docker-compose.yml`:
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://api.honeycomb.io:443"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "x-honeycomb-team=${HONEYCOMB_API_KEY}"
HONEYCOMB_DATASET: "databrain-production"
LOG_LEVEL: "info"
```
**Security**: Store your API key in `.env`:
```bash theme={"dark"}
# .env
HONEYCOMB_API_KEY=your_honeycomb_api_key_here
```
### 4. Kubernetes Configuration
```yaml theme={"dark"}
apiVersion: v1
kind: Secret
metadata:
name: honeycomb-secret
type: Opaque
stringData:
api-key: your_honeycomb_api_key_here
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: databrain-backend
spec:
template:
spec:
containers:
- name: backend
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://api.honeycomb.io:443"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
- name: HONEYCOMB_API_KEY
valueFrom:
secretKeyRef:
name: honeycomb-secret
key: api-key
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "x-honeycomb-team=$(HONEYCOMB_API_KEY)"
- name: HONEYCOMB_DATASET
value: "databrain-production"
```
## Alternative: Using OpenTelemetry Collector
For advanced features like sampling and enrichment:
### Docker Compose with Collector
```yaml theme={"dark"}
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
environment:
HONEYCOMB_API_KEY: "${HONEYCOMB_API_KEY}"
HONEYCOMB_DATASET: "databrain-production"
networks:
- databrain
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4318"
OTEL_SERVICE_NAME: "databrain-api"
depends_on:
- otel-collector
```
### Collector Configuration for Honeycomb
Create `otel-collector-config.yaml`:
```yaml theme={"dark"}
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
timeout: 1s
send_batch_size: 1024
# Add resource attributes
resource:
attributes:
- key: deployment.environment
value: production
action: upsert
- key: service.version
value: 1.0.0
action: upsert
# Tail-based sampling (only send interesting traces)
tail_sampling:
decision_wait: 10s
num_traces: 100
policies:
# Always sample errors
- name: errors
type: status_code
status_code:
status_codes: [ERROR]
# Sample slow requests
- name: slow-requests
type: latency
latency:
threshold_ms: 1000
# Probabilistic sampling for everything else
- name: baseline
type: probabilistic
probabilistic:
sampling_percentage: 10
exporters:
otlp:
endpoint: "api.honeycomb.io:443"
headers:
"x-honeycomb-team": "${HONEYCOMB_API_KEY}"
"x-honeycomb-dataset": "${HONEYCOMB_DATASET}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, resource, tail_sampling]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch, resource]
exporters: [otlp]
```
## What Gets Sent to Honeycomb
| Data Type | Description |
| ----------- | --------------------------------------------------- |
| **Traces** | Full request traces with all spans and timing |
| **Spans** | Individual operations (DB queries, API calls, etc.) |
| **Events** | Structured logs that appear as trace events |
| **Metrics** | Request rates, latencies, error counts |
## Verification
### 1. Restart Databrain
```bash theme={"dark"}
docker compose restart databrainbackend
# or
kubectl rollout restart deployment/databrain-backend
```
### 2. Generate Test Traffic
```bash theme={"dark"}
# Simple health check
curl https://your-databrain-instance.com/api/health
# More complex request
curl -X POST "https://your-databrain-instance.com/api/v2/metric/execute" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"metricId": "test-123"}'
```
### 3. View in Honeycomb
1. Go to [Honeycomb UI](https://ui.honeycomb.io/)
2. Select your dataset (e.g., `databrain-production`)
3. You should see traces within seconds (Honeycomb is real-time!)
4. Click on **Recent Traces** to explore
### 4. Check Backend Logs
Look for:
```json theme={"dark"}
{
"level": "info",
"message": "[Telemetry] OpenTelemetry initialized - service: databrain-api, endpoint: https://api.honeycomb.io:443"
}
```
## Using Honeycomb Features
### 1. BubbleUp - Find Anomalies
BubbleUp automatically identifies what makes slow or failing requests different:
1. In Honeycomb, go to your dataset
2. Click **New Query**
3. Filter: `WHERE service.name = databrain-api`
4. Visualize: `HEATMAP(duration_ms)`
5. Click on slow requests cluster
6. Click **BubbleUp** → Honeycomb shows which attributes correlate with slowness
### 2. Tracing Waterfall
View full request lifecycle:
1. Click on any trace
2. See the waterfall view with all spans
3. Identify bottlenecks (database queries, external APIs)
4. Click on spans to see attributes
### 3. High-Cardinality Queries
Query on any attribute combination:
```
WHERE service.name = databrain-api
AND http.status_code >= 500
AND userId EXISTS
GROUP BY userId, http.route
CALCULATE COUNT, P95(duration_ms)
```
### 4. Time-based Comparison
Compare performance across time periods:
1. Set time range (e.g., last hour)
2. Click **Compare to** → **Previous period**
3. See what changed (requests, latency, errors)
### 5. Service Map
Visualize service dependencies:
1. Go to **Service Map** (if enabled)
2. See how databrain-api connects to PostgreSQL, Redis, Hasura, etc.
3. Click on connections to see request rates and error rates
## Example Queries
### Slowest Endpoints
```
WHERE service.name = databrain-api
AND span.kind = server
GROUP BY http.route
CALCULATE P95(duration_ms), COUNT
ORDER BY P95(duration_ms) DESC
```
### Error Analysis
```
WHERE service.name = databrain-api
AND status.code = ERROR
GROUP BY error.type, http.route
CALCULATE COUNT
```
### User Experience Analysis
```
WHERE service.name = databrain-api
AND userId EXISTS
GROUP BY userId
CALCULATE P95(duration_ms), COUNT
ORDER BY COUNT DESC
```
### Database Query Performance
```
WHERE service.name = databrain-api
AND db.system = postgresql
GROUP BY db.statement
CALCULATE P95(duration_ms), COUNT
ORDER BY P95(duration_ms) DESC
```
### Compare Error Rates Over Time
```
WHERE service.name = databrain-api
GROUP BY status.code
CALCULATE COUNT
COMPARE TO 1 hour ago
```
## Creating Triggers (Alerts)
Set up alerts in Honeycomb:
### High Error Rate
1. Go to **Triggers** → **New Trigger**
2. Query:
```
WHERE service.name = databrain-api
AND status.code = ERROR
CALCULATE COUNT
```
3. Threshold: Alert when `COUNT > 10` per minute
4. Add recipient (email, Slack, PagerDuty)
### High Latency
```
WHERE service.name = databrain-api
AND span.kind = server
CALCULATE P95(duration_ms)
```
Threshold: Alert when `P95(duration_ms) > 2000`
### Anomaly Detection
Use Honeycomb's **Anomaly Detection** trigger:
* Automatically learns normal behavior
* Alerts on statistical anomalies
* No manual threshold setting required
## Boards (Dashboards)
Create custom boards in Honeycomb:
### Service Health Board
1. **Request Rate**
```
WHERE service.name = databrain-api
CALCULATE COUNT
```
2. **Error Rate**
```
WHERE service.name = databrain-api
CALCULATE COUNT(status.code = ERROR) / COUNT
```
3. **Latency Heatmap**
```
WHERE service.name = databrain-api
HEATMAP(duration_ms)
```
4. **Top Endpoints by Traffic**
```
WHERE service.name = databrain-api
GROUP BY http.route
CALCULATE COUNT
```
### Database Performance Board
1. **Query Latency**
```
WHERE db.system = postgresql
HEATMAP(duration_ms)
```
2. **Slowest Queries**
```
WHERE db.system = postgresql
GROUP BY db.statement
CALCULATE P95(duration_ms)
ORDER BY P95(duration_ms) DESC
LIMIT 10
```
## Markers (Deploy Events)
Track deployments with markers:
```bash theme={"dark"}
# After deploying
curl https://api.honeycomb.io/1/markers/databrain-production \
-X POST \
-H "X-Honeycomb-Team: ${HONEYCOMB_API_KEY}" \
-d '{
"message": "Deployed v1.2.3",
"type": "deploy",
"url": "https://github.com/yourorg/databrain/releases/v1.2.3"
}'
```
Markers appear as vertical lines in time-series graphs, making it easy to correlate performance changes with deployments.
## SLOs (Service Level Objectives)
Create SLOs in Honeycomb:
1. Go to **SLOs** → **New SLO**
2. Define SLI (Service Level Indicator):
**Example: Availability SLO (99.9%)**
```
Denominator: COUNT (all requests)
WHERE service.name = databrain-api
Numerator: COUNT (successful requests)
WHERE service.name = databrain-api
AND http.status_code < 500
```
3. Set target: 99.9% over 30 days
4. Track SLO compliance and error budgets
## Troubleshooting
| Issue | Solution |
| --------------------- | ------------------------------------------------------ |
| No data in Honeycomb | Verify API key is correct and has write permissions |
| 401 Unauthorized | Check `x-honeycomb-team` header contains valid API key |
| Data in wrong dataset | Set `HONEYCOMB_DATASET` explicitly |
| Missing attributes | Ensure Winston logger includes metadata in logs |
| High ingestion costs | Implement tail-based sampling in collector |
### Debug Mode
Enable verbose logging:
```bash theme={"dark"}
LOG_LEVEL=debug
OTEL_LOG_LEVEL=debug
```
Check logs for export confirmations.
### Test API Key
```bash theme={"dark"}
curl https://api.honeycomb.io/1/auth \
-H "X-Honeycomb-Team: ${HONEYCOMB_API_KEY}"
```
Should return team information if valid.
## Cost Optimization
Honeycomb pricing is based on **event volume** (spans/events per month).
**Free tier**: 20M events/month
**Optimization strategies**:
1. **Tail-based sampling**: Only send interesting traces (errors, slow requests)
2. **Filter health checks**: Exclude `/health` endpoint
3. **Sample high-throughput endpoints**: Sample 10% of common endpoints
4. **Set retention**: Adjust in Honeycomb settings (default 60 days)
### Sampling Configuration
In collector config:
```yaml theme={"dark"}
processors:
tail_sampling:
policies:
- name: errors
type: status_code
status_code: {status_codes: [ERROR]}
- name: slow
type: latency
latency: {threshold_ms: 1000}
- name: sample-baseline
type: probabilistic
probabilistic: {sampling_percentage: 5}
```
This keeps:
* 100% of errors
* 100% of slow requests (>1s)
* 5% of everything else
## Best Practices
### 1. Use Wide Events
Include rich context in your logs:
```typescript theme={"dark"}
logger.info('Order processed', {
orderId: '12345',
userId: 'user-789',
amount: 99.99,
currency: 'USD',
paymentMethod: 'credit_card',
processingTime: 245,
region: 'us-east-1'
});
```
All these attributes become queryable in Honeycomb.
### 2. Add Custom Instrumentation
For critical business logic, add custom spans:
```typescript theme={"dark"}
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('databrain-business-logic');
async function processOrder(orderId: string) {
const span = tracer.startSpan('processOrder');
span.setAttribute('orderId', orderId);
try {
// Your business logic
span.addEvent('Order validated');
// ...
span.setStatus({ code: SpanStatusCode.OK });
} catch (error) {
span.recordException(error);
span.setStatus({ code: SpanStatusCode.ERROR });
throw error;
} finally {
span.end();
}
}
```
### 3. Use Derived Columns
Create computed columns in Honeycomb:
* **Error rate**: `COUNT_DISTINCT(status.code = ERROR) / COUNT_DISTINCT(trace.id)`
* **Apdex score**: Custom formula for user satisfaction
* **Business KPIs**: Revenue per request, conversion rate, etc.
## Support
* **Honeycomb Documentation**: [https://docs.honeycomb.io/](https://docs.honeycomb.io/)
* **Honeycomb Community**: [https://www.honeycomb.io/community](https://www.honeycomb.io/community)
* **Honeycomb Support**: Available via in-app chat or email
For Databrain configuration issues, contact your Databrain support team.
# Get an guest token
Source: https://docs.usedatabrain.com/guides/integrating-plugin/get-a-guest-token
This page will help you to get a guest token which you can use to access the dashboard metrics in your app using the databrain plugin.
Go to the Databrain app settings and then click on the API Token tab.
Find the API Key which has permission to access metrics and dashboards.
Open your Postman App and send a POST request to the URL -\
`https://api.usedatabrain.com/api/v2/guest-token/create`
Click on the Authorization tab, select type as Bearer Token, and paste the API Key copied from the Databrain App’s API Token tab.
In the Body tab of Postman, choose raw and JSON.\
You’ll need a `clientId` which should come from your user’s session—since this API will be called from your app ideally.
The minimum required JSON structure is:
```json theme={"dark"}
{
"dataAppName": "your data app name",
"clientId": "Your client or user Id for which you are creating this guest token"
}
```
If you want to add some Row Level of Security settings then in params you can also add another key “rlsSettings” It is an array of objects which has “metricId” - the id of the metric you want to have rls settings enabled for along with the key “values” which is an object of rls condition name and its value pair filter for the particular metric.
Now our new json body structure would be -
```json theme={"dark"}
{
"dataAppName": "your data app name",
"clientId": "Your client or user Id for which you are creating this guest token",
"params": {
"rlsSettings": [
{
"metricId": "The id of the metric you want to have rls filters",
"values": {
"paid_orders": true,
"amount": 500
}
}
]
}
}
```
If you use SQL query to generate the metric data and want to add metric filters but don't want end users to use them then you can add **appFilters**.
Please refer to this article to know more about app filters.
Learn how to use app-level filters to restrict data visibility at runtime.
To add app filters it's the same process as rls settings. Here you have to add another key "appFilters" and then you can specify the value same as rls settings.
```json theme={"dark"}
{
"dataAppName": "your data app name",
"clientId": "Your client or user Id for which you are creating this guest token",
"params": {
"appFilters": [
{
"metricId": "The id of the metric you want to have app filters",
"values": {
"paid_orders": true,
"amount": 500,
"country": ["USA", "CANADA"]
}
}
]
}
}
```
Click on the **Send** button in Postman. In the response, you will receive the generated token.\
Copy this token and use it within your Databrain plugin configuration.
# Get an auth token
Source: https://docs.usedatabrain.com/guides/integrating-plugin/get-an-auth-token
This page will help you get an auth token and use it to call databrain apis.
Go to the **Settings** page then in the **"Embed Settings"** tab, click on **"Generate api token"** button.
In the popup modal give a name to the API Token, then provide an optional description of why you are creating this token.
Provide the necessary permissions to the token from the dropdown list. Then click on **"Generate API Key"** button.
You will be able to view the newly created API key in the table, then click on the copy icon.
Now you can use this API Key as a Bearer Token Authorization header and call the Databrain APIs from your app.
Yahoo! You have successfully created the API Key which you use to connect Databrain APIs from your app.
# Kloudfuse integration
Source: https://docs.usedatabrain.com/guides/kloudfuse-integration
# Integrating Databrain with Kloudfuse
This guide explains how to send OpenTelemetry traces and metrics from your self-hosted Databrain instance to Kloudfuse.
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Kloudfuse account with OTLP ingestion enabled
* Your Kloudfuse OTLP endpoint URL
## Configuration
### 1. Get Your Kloudfuse OTLP Endpoint
In your Kloudfuse console, locate your OTLP ingestion endpoint. It typically follows this format:
```
https://.kloudfuse.io/otlp
```
Or if using the Kloudfuse collector deployed in your cluster:
```
http://kfuse-otel-collector.kloudfuse.svc.cluster.local:4318
```
### 2. Configure Databrain Environment Variables
Add these environment variables to your Databrain backend service:
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# Kloudfuse OTLP endpoint (HTTP)
OTEL_EXPORTER_OTLP_ENDPOINT=https://.kloudfuse.io/otlp
# Service name (appears in Kloudfuse UI)
OTEL_SERVICE_NAME=databrain-api
# Optional: Set log level for debugging
LOG_LEVEL=info
```
### 3. Docker Compose Configuration
Update your `docker-compose.yml`:
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://.kloudfuse.io/otlp"
OTEL_SERVICE_NAME: "databrain-api"
LOG_LEVEL: "info"
```
### 4. Kubernetes Configuration
If deploying on Kubernetes, add to your deployment:
```yaml theme={"dark"}
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://kfuse-otel-collector.kloudfuse.svc.cluster.local:4318"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
```
## What Gets Sent to Kloudfuse
Once configured, Databrain automatically sends:
| Telemetry Type | Description |
| -------------- | -------------------------------------------------------- |
| **Traces** | API request spans with timing, status codes, and errors |
| **Metrics** | Request latency histograms, error rates, throughput |
| **Logs** | Correlated logs with trace context (trace\_id, span\_id) |
## Verification
1. **Restart Databrain** after configuration changes
2. **Make a few API requests** to generate telemetry
3. **Check Kloudfuse UI**:
* Navigate to **Traces** → filter by `service.name = databrain-api`
* Check **Metrics** for `http.server.duration` histograms
* View **Logs** correlated with trace IDs
## Troubleshooting
| Issue | Solution |
| -------------------- | ---------------------------------------------------------------- |
| No data in Kloudfuse | Verify `OTEL_ENABLED=true` and endpoint is reachable |
| Connection refused | Check network connectivity and firewall rules |
| 401/403 errors | Verify Kloudfuse API credentials if authentication is required |
| Missing traces | Ensure requests are being made; traces appear after \~30 seconds |
### Debug Mode
Enable debug logging to troubleshoot:
```bash theme={"dark"}
LOG_LEVEL=debug
```
Check Databrain logs for messages like:
```
OpenTelemetry initialized successfully
Exporting traces to: https://...
```
## Support
For Kloudfuse-specific issues, contact [Kloudfuse support](https://kloudfuse.com/support).
For Databrain configuration issues, contact your Databrain support team.
# Quick start
Source: https://docs.usedatabrain.com/guides/metric-component-upto-version-V0.11.15/quickstart
This will explain you how to use the databrain plugin and customization.
Note: This doc is deprecated for versions greater than v0.11.15
```bash theme={"dark"}
npm install @databrainhq/plugin
```
```js theme={"dark"}
import '@databrainhq/plugin/dist/style.css';
import { Metric } from '@databrainhq/plugin';
```
```jsx theme={"dark"}
```
```jsx theme={"dark"}
setFullScreen(false)} // optional callback
variant="card" // optional - card or fullscreen
width={500}
height={300}
style={style}
className={className}
chartColors={["red", "blue", "orange", "..."]} // default is recharts colors
theme={{
colors: {
background: "", primary: "", primaryLight: "", primaryDark: "",
secondary: "", secondaryLight: "", secondaryDark: "",
tertiary: "", tertiaryLight: "", tertiaryDark: "",
error: "", errorLight: "", errorDark: "",
warning: "", warningLight: "", warningDark: "",
dark: "", light: "",
gray50: "", gray100: "", gray200: "", gray300: "",
gray400: "", gray500: "", gray600: "", gray700: "",
gray800: "", gray900: ""
},
border: {
radiusNone: "0", radiusDefault: "5px", radiusSm: "2px",
radiusMd: "10px", radiusLg: "16px", radiusXl: "20px",
radius2xl: "24px", radius3xl: "30px", radiusFull: "50%"
},
typography: {
fontSize: "9px", fontFamily: "Inter",
fontWeightThin: 200, fontWeightLight: 300, fontWeightRegular: 400,
fontWeightSemibold: 500, fontWeightBold: 600,
colorPrimary: "", colorSecondary: "", colorTertiary: ""
},
breakpoint: {
xs: 360, sm: 512, md: 720, lg: 990, xl: 1280
},
metricLayoutCols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
shadow: {
primary: "", secondary: "", tertiary: ""
}
}}
/>
```
# AI Summary
Source: https://docs.usedatabrain.com/guides/metric/ai-summary
This guide provides a straightforward method for utilizing AI to generate concise summaries of metrics from your dashboard.
1. **View the Metric**
Open the dashboard and select the metric you want to explore in full screen mode.
2. **Generate AI Summary**
Click on the **AI Insights** icon next to the download option. The AI will display a summary of the metric.\
To copy the summary, simply click **Copy**.
# Overview
Source: https://docs.usedatabrain.com/guides/metric/apply-metric-filter
Metric filters refine the data displayed on your metric cards, offering a more focused analysis.
### 1. **Access Metric Filter Settings:**
Inside the metric page, click on the **"+"** button located above the chart.
### 2. **Metric Filters:**
* Set the **"Filter Name"** and choose the **"Filter Type"** from the dropdown.
* Specify the **"Datatype"**.
* Choose the **"Filter Variant"** from the dropdown.
* Select the desired table and column.
* If required, save the filter as a **"Variable Filter"**. This captures a variable's value for use in your SQL query.
**By integrating metric filters, you can ensure a more precise and tailored data representation in Databrain.**
You’ve successfully configured a Metric Filter in Databrain!\
Your visualization is now refined, enabling sharper, more targeted insights across your dataset.
# Metric Filter - Custom
Source: https://docs.usedatabrain.com/guides/metric/apply-metric-filter/metric-filter-custom
Create a Custom Dashboard/Metric Filter: Quick Instruction Manual
### Create a Metric Filter
Begin by creating a new metric filter within your dashboard.
### Write a Custom SQL Query
Create a SQL query to retrieve the data you need for dropdown options. For example:
```sql theme={"dark"}
SELECT
"country" AS "countryname"
FROM
"public"."table"
```
### Mention the Alias in the Option
In your filter options, refer to the alias `countryname` that you used in your SQL query.
***
### Navigate to "Apply On" Section
Go to the "Apply On" section of the dashboard filter settings.
***
### Assign Variable Name
* Assign a variable name, for example, `{{value}}`.
* Copy the variable `{{value}}` for use in your custom SQL query.
### Example Custom SQL Query with Variable Filter
1.Write Your Custom SQL:
Start by writing a basic SQL query without the filter.
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
```
2.Integrate the Variable Filter:
Modify your SQL to include the variable filter.
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
WHERE
"country" = {{value}}
```
3.Resulting SQL Generated:
The resulting SQL generated by the system will incorporate your variable filter in the final output.
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
(
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
WHERE
"country" = {{value}}
) AS "dbn_sql_table"
```
# Metric Filter - Variable
Source: https://docs.usedatabrain.com/guides/metric/apply-metric-filter/metric-filter-variable
Variable Filter in Metric Filter: Quick Instruction Manual
> Master dynamic filtering in Databrain with Variable Filters—your key to building flexible,
> interactive metrics. This guide demonstrates how to transform static SQL queries into dynamic
> data explorations, empowering users to filter complex datasets effortlessly.
### Using Variable Filter in Metric Filter with Custom SQL
#### Creating a Metric Filter with Variable Filter:
1. **Create Metric Filter**
2. In the **“Apply On”** section, choose **"Variable Filter"**.
3. **Assign Variable Name**:
* Assign a variable name, for example, `{{value}}`.
* Copy the variable `{{value}}` for use in your custom SQL query.
### Example Use Case: Dynamic Country Population Analysis
#### Scenario:
Imagine a dashboard where analysts can quickly filter population data for different countries—without needing to modify the underlying SQL query every time.
#### Purpose of Variable Filter:
**Where to use the variable:**\
Filter variables (e.g. `{{value}}`, `{{global_value}}`) are **only valid in the WHERE clause** of your metric's SQL (and in the filter's Apply on logic). Do **not** use them in SELECT, FROM, or GROUP BY—doing so will trigger: **Error: Filter or Client variables detected in the query.** There is no built-in way to "inspect" or display the current filter value in a metric.
#### Example Custom SQL Query with Variable Filter:
* **Custom SQL you write:**
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
```
* **Custom SQL added with Variable Filter:**
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
WHERE
"country" = {{value}}
```
Then the Generated SQL we generate would look like this:
* **Resulting SQL:**
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
(
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
WHERE
"country" = {{value}}
) AS "dbn_sql_table"
```
***
**Working:**
* The initial SQL query retrieves all country population data.
* The Variable Filter dynamically adds a condition using `{{value}}`.
* When a user selects a country from the dashboard, the filter updates the query.
* The results are filtered instantly based on the selected country.
# Archive/Unarchive Metric Card
Source: https://docs.usedatabrain.com/guides/metric/archive-unarchive-metric-card
Manage your dashboard by archiving unused metric cards and retrieving them when needed.
#### 1. Archiving a Metric Card
* **Open Full Screen:** Access the metric card in Full Screen Mode.
* **Archive the Card:** Click the `Archive` icon in the top right, next to the download icon, then select the **"Archive"** button to complete the archiving process.
#### 2. Unarchiving a Metric Card
* **Access Archived Metrics:** Go to the **"Settings"** page from the home screen and select **"Archived Metrics"**.
* **Select Workspace:** Use the dropdown at the top right to choose your desired workspace.
* **Restore Metric Card:** Find the archived card you want, then click **"Unarchive"** to return it to its original dashboard.
Archiving helps keep your dashboard organized, while the unarchive feature allows you to easily restore important metrics in Databrain.
You’ve successfully learned how to archive and unarchive metric cards!\
Your dashboards can now stay organized, streamlined, and clutter-free—while giving you full flexibility to restore metrics whenever needed.
# Complex Filter
Source: https://docs.usedatabrain.com/guides/metric/complex-filter
Complex Filter Feature: Quick Instruction Manual
### Accessing Complex Filter
1. Click on the filter (funnel) icon.
2. Select **"+ Add Filter"**.
3. Choose **"Complex Filter"** from the list.
4. A modal will appear to add the custom **WHERE** clause.
### Using Complex Filter without Custom SQL
* You can write complex filters for any table that is part of the dimensions/measures.
* Example columns in Dimensions/Measures: `"public_table1"."country"`, `"public_table2"."location"`, `"public_table1"."population"`
* For the above, below will be our generated SQL:
```sql theme={"dark"}
SELECT
"public_table1"."country" AS "country",
"public_table2"."location" AS "location",
"public_table1"."population" AS "population"
FROM
"public"."table1" AS "public_table1"
INNER JOIN "public"."table2" AS "public_table2" ON "public_table2"."code" = "public_table1"."code"
LIMIT 100
```
* Example Complex Filter that you can write:
```sql theme={"dark"}
"public_table2"."location" = UPPER("public_table1"."country")
"public_table1"."population" > 100000
```
### Using Complex Filter with Custom SQL
* When writing a custom SQL query, the complex filter can only address columns of the table `"dbn_sql_table"`.
* Example Custom SQL that you write:
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
```
* The SQL generated by us:
```sql theme={"dark"}
SELECT
"country" AS "country",
"population" AS "population"
FROM
(
SELECT
"country" AS "country",
"population" AS "population"
FROM
"public"."table"
) AS "dbn_sql_table"
```
**Example Complex Filter with Custom SQL:**
* Example Complex Filter that you can write:
```sql theme={"dark"}
"dbn_sql_table"."population" > 100000
"dbn_sql_table"."location" = 'Japan'
```
You’ve successfully applied a Complex Filter in Databrain! Your advanced filtering logic is now in effect, enabling deeper and more precise data analysis.
# Download Metric Card
Source: https://docs.usedatabrain.com/guides/metric/download-metric-card
Access and save your metric card data in various formats for offline analysis or sharing.
#### Downloading a Metric Card
1. **Open Full Screen Mode:** Access the metric card in Full Screen Mode.
2. **Initiate Download:** Click the **"Download"** icon in the top right corner.
3. **Select Download Type:** Choose your preferred format from the dropdown menu:
* **Download:** Get the tabulated data.
* **Download Without Filters:** Download the raw data.
* **Save as PNG:** Save the visualization as a PNG image.
With these options, you can easily access, save, and share your metric data beyond Databrain.
You’ve successfully downloaded your metric card!\
Your data is now available offline—ready for analysis, reporting, or sharing outside the platform.
# Download Underlying Data
Source: https://docs.usedatabrain.com/guides/metric/download-underlying-data
This guide provides a straightforward process for accessing and downloading underlying data from a dashboard, allowing users to analyse metrics in detail.
1. **Access Metric**\
Navigate to the dashboard and view the metric in full screen mode.
2. **Download Underlying Data**\
Click on **Download** icon to export the underlying data. You can choose whether to include or exclude any filters applied.
# Dynamic Property
Source: https://docs.usedatabrain.com/guides/metric/dynamic-property
This guide explains the process of using dynamic properties in metric creation. These properties can fetch dynamic values directly from the database, with dependencies on dashboard or metric filters.
### 1. Access Dynamic Property:
* In the metric creation page, click on **"\[X]"** icon near the sort icon.
* This will open the **"Dynamic Property"** panel on the right side of the screen.
* Then, click on **"+Property"** to add a dynamic property to your metric.
### 2. Configure Dynamic Property
Enter the Property Name and choose between the two Property Types: **"Auto"** or **"Custom"**
#### For Auto Property Type
* Choose the dataset and the column you want to consider.
* Then, select the dependencies: dashboard or metric filter type. *(Optional)*
* Finally, click on **"Create"**.
#### For Custom Property Type
* Enter your SQL query to choose your dynamic value and dependent columns, and select the column name.
* Then, select the dependencies: dashboard or metric filter type. *(Optional)*
* Finally, click on **"Create"**.
#### 3. Verify Property Creation
* Check the property listed in the **Dynamic Property** panel.
* Copy the property name format: `[[PropertyName]]` and close the panel.
#### 4. Use Dynamic Property in Metrics
In the **Formatting Options** of a metric, use the `[[PropertyName]]` format in:
* **Prefix**
* **Suffix**
This will dynamically update values based on selected inputs.
For more details, kindly refer the below link:
This guide provides a practical approach for utilizing Dynamic Property to dynamically display revenue in multiple currencies for different countries.
#### 5. Save Metric to Dashboard
* Click the **"Save to Dashboard"** button.
* Then, use the `[[PropertyName]]` format in:
* **Metric Title**
* **Metric Description**
* **Metric Long Description**, and
* **Footnote**
#### 6. View Dynamic Property
The dynamic property `[[Unit]]` shows different currency units based on the selected country.
You’ve successfully configured and applied Dynamic Properties in your metric!\
Your metrics now respond intelligently to filters and user selections, enabling dynamic, context-aware values across your dashboards.
# Edit a Metric
Source: https://docs.usedatabrain.com/guides/metric/edit-a-metric
This guide provides essential steps for effectively editing metrics in Databrain, allowing users to customize their dashboards to better reflect their data needs.
Navigate to your dashboard and open the metric you want to modify.
You can implement various updates, such as:
* **Add Customizations**
* **Change Chart Types**
* **Integrate Filters**
* **Apply Drill Down, Group By, and Sort Functionalities**
Click **"Save to Dashboard"** button on the top right corner to store the changes.
**These editing options ensure that your metrics in Databrain remain current and impactful.**
# Footnote and Long Description
Source: https://docs.usedatabrain.com/guides/metric/footnote-and-long-description
This guide provides essential instructions to enhance your dashboard cards with additional descriptive elements and to improve the overall communication and utility of your data visualizations.
### 1. Adding a Long Description and Footnote:
* On the metric creation page, click the **"Save to Dashboard"** button in the top right corner.
* In the **Long Description** field, enter a detailed description of the metric or add a link to redirect users to the required information.
* In the **Footnote** field, add any additional contextual information, links to redirect to the same existing page or a new page, or formatting options such as bold and italics for better customization.
* Click **"Save"** to save the metric to your dashboard.
### Adding text to footnote and long description:
### Adding links to footnote and long description:
You can include clickable links in the Long Description and Footnote fields to provide quick access to external pages.
### 2. Viewing the Changes:
* The long description will appear when hovering over the information icon next to the metric name.
* The footnote will display directly below the metric on your dashboard.
**Text result**
**Link result**
You’ve successfully added and customized footnotes and long descriptions for your metric!\
Your dashboard cards now provide richer context, clearer explanations, and easy access to supporting information.
# Group By
Source: https://docs.usedatabrain.com/guides/metric/group-by
This guide offers a straightforward method for organizing data by using the "Group By" feature, enhancing data analysis efficiency.
### 1. **Access Group By**
Click the "+" icon at the top of the metric and select the **"Group By"** button.
### 2. **Group By a single column**
Choose the column you want to group in the **“Series Column”** field.
### 3. **Group By multiple columns**
* Enable the toggle of **"Dynamic Options"** to group by multiple columns.
* If necessary, enable the **"Enable the Clear Option"** toggle.
* Select the columns you want to group from the **"Series Column"** drop-down.
### 4. **Apply Filters**
Use filters to view the dynamic changes in your grouped data.
You’ve successfully applied Group By to your metric!\
Your visualization now organizes data by the selected columns, enabling clearer comparisons and deeper segmented analysis.
# Joins , Filter, Sort, Group By
Source: https://docs.usedatabrain.com/guides/metric/joins-filter-sort-groupby
Enhance and refine your metrics using various functionalities available.
* **Activate Join**: Select your table, then drag and drop a dimension or metric. Click on the **"Joins"** icon.
* **Set Join Rule**: Choose two tables and connect columns using the **"ON"** clause.
* **Select Join**: Choose your preferred join (Inner, Left, Right, Full)
* **Finalize**: Click **"Apply Join"** to complete.
* **Access Filters**: Click the **"Filter"** icon at the top right.
* **Choose Filter Type**:
* **Simple Filter**: Select a column, set a condition, enter a value, and click "Apply Filter".
* **Complex Filter**: Write a custom SQL query to integrate directly into your SQL code.
* **Client Filter**: Choose a column (usually client ID) matching your data warehouse tenancy, then click "Apply Filter".
* **Access Sorting**: Click the **"Sort"** icon at the top right.
* **Configure Sorting**: Choose the column to sort by and select the order (ascending or descending).
* **Apply**: Click **"Apply Sort"** to arrange your data.
* In addition to the lexicographical order provided by SQL, you can sort the chart in any desired order using **"Complex Sort"** with custom SQL.
* **Initiate Grouping**: Click the **"Group By"** icon at the top right to group columns.
* **Select Columns**: Choose the columns you want to group by and click on **"Save"**.
Utilizing these features provides a customized and insightful perspective of your data in Databrain.
# Merge Metrics
Source: https://docs.usedatabrain.com/guides/metric/merge-metrics
This guide provides a straightforward approach to customize your dashboard layout more dynamically by merging metric cards. This enhances readability and streamlines related metrics.
1. **Access Layout Customization**
In the Dashboard page, click on **"Dashboard Settings"** in the top-right corner and select **"Customize Layout"** from the dropdown menu.
2. **Merge Metrics:**
* Then, click on the **"Merge Metrics"** button located at the bottom left corner of the metric card.
* In the **"Merge Metrics"** dialog box, select the metric you want to merge and choose the **"Dashboard Filters"** you want to add to the section.
* Finally, click **"Save"** to confirm the selection.
When merging metrics, the dashboard filter can serve as a section filter, refining the displayed data by applying specific criteria to that section of the dashboard.
For more details on section filter, kindly refer the below link:
3. **Publish the Layout:**
* Rearrange the metrics according to your choice.
* Click **"Save Layout"** to save your changes, then click **"Publish"** to finalize them.
* After publishing, you can view the merged metrics in the dashboard.
You’ve successfully merged your metrics and published the updated layout!\
Your dashboard is now more organized, readable, and optimized for cleaner insight discovery.
# Metric Expression for Single Value Card
Source: https://docs.usedatabrain.com/guides/metric/metric-expression-for-single-value-card
This guide is essential to enhance dashboards by leveraging Metric Expressions for single-value cards.
> Metric Expressions allow you to perform calculations using single-value card metrics by referencing their values with their **Metric IDs**.
> **Example:**
> We have two single value cards:
>
> * Sales with Metric ID `{{Sales_hwPED}}`, valued at **\$2.89B**
> * Profit with Metric ID `{{Profi_qjvSWB}}`, valued at **\$2.84B**
> To calculate the Sales Profitability Ratio, we can use a Metric Expression:
>
> * `ROUND({{Sales_hwPED}}/{{Profi_qjvSWB}}, 2)`\
> Output: A single-value card displaying **1.02**
> Alternatively using,\
> `{{Sales_hwPED}}` / `{{Profi_qjvSWB}}`\
> Output: A single-value card displaying\
> **2891075848.0202847 / 2840122818.152845**
***
### 1. **Access Elements**
Navigate to your dashboard and click on **"+ Elements"** button near the create metric button.
### 2. **Configure Metric Expression**
* Enter your suitable title and description for the metric expression.
* Choose the Element Type as **"Metric Expression"**.
* Select the metrics you want to include in the computation.
* In the **"Metric Expression"** text box, write the formula to be applied to the chosen single-value cards.
> Reference the value of a single-value card using its **Metric ID** like `{{metricid}}`
* Customize the appearance of the single-value card using font options such as **font family**, **font size**, and **font weight**.
* (Optional) Enable **"Merge Card to Background"** if you want to blend the metric into the dashboard background.
* Click **"Save"** to complete the setup.
### 3. **View the Metric Expression**
Once saved, your Metric Expression will be displayed on the dashboard, reflecting the computed value based on the selected metrics.
Metric Expression works only for single value cards!
You’ve successfully created a Metric Expression for your dashboard!\
Your single-value cards can now perform real-time calculations, enabling smarter comparisons and deeper analytical insights.
# Metric Summary
Source: https://docs.usedatabrain.com/guides/metric/metric-summary
This guide provides a straightforward process for creating metric summaries. These summaries can be added directly as text boxes within your dashboard, providing quick insights at a glance.
### 1. Navigate to Elements Section
Open your dashboard and click the **Elements** icon located next to the Add Metric button.
### 2. Add an Element
* Enter a title and description for your summary.
* Adjust the alignment of the title and description as needed.
* Select the relevant metrics from the dropdown to generate a combined summary, and input your question in the Summary Prompt.
* Configure the font styles for the summary: font family, font size, and font weight.
* Click **Save** to add the metric summary to your dashboard.
### 3. View Metric Summary
Your new metric summary will now be visible on the dashboard.
You’ve successfully created and added a Metric Summary to your dashboard!\
Your insights are now visible at a glance, enhancing clarity and decision-making across your workspace.
# Section Filters
Source: https://docs.usedatabrain.com/guides/metric/section-filters
This guide provides a straightforward approach to customizing your dashboard layout with section filters, allowing for a more tailored data analysis experience.
1. **Access Layout Customization:**
In the Dashboard page, click on **"Dashboard Settings"** in the top-right corner and select **"Customize Layout"** from the dropdown menu.
2. **Section Filters:**
* Then, click on the **"Merge Metrics"** button located at the bottom left corner of the metric card.
* In the **"Merge Metrics"** dialog box, choose the **"Dashboard Filters"** you want to add to the section.
* Finally, click **"Save"** to confirm the selection.
When you add dashboard filters to a section, they are automatically scoped to that section, meaning they will only affect the data within that specific section. This ensures a more focused and relevant view for your users.
3. **Publish the Layout:**
* Click **"Save Layout"** to save your changes, then click **"Publish"** to finalize them.
* After publishing, you can view the section filters in the dashboard.
You’ve successfully applied Section Filters to your dashboard!\
Your users can now interact with more targeted and context-specific filters, improving clarity and analytical precision.
# Switch X axis and Switch Y axis
Source: https://docs.usedatabrain.com/guides/metric/switch-x-axis-and-switch-y-axis
This guide provides a straightforward method to easily switch the X and Y axes in your data visualization, enhancing your ability to analyse and interpret data from different perspectives.
### 1. **Switch X Axis:**
Click on the "+" icon on top of the metric and click on **"Switch X Axis"** button.
Select any column from the drop-down to notice a change in X Axis.
### 2. **Switch Y Axis:**
Click on the "+" icon on top of the metric and click on "Switch Y Axis" button.
Select any column from the drop-down to notice a change in Y Axis.
You’ve successfully switched the X and Y axes in your metric!\
Your visualizations will now adapt dynamically, allowing deeper analysis from multiple perspectives.
# View Unpublished Metrics
Source: https://docs.usedatabrain.com/guides/metric/view-unpublished-metrics
Monitor and identify metrics that are in draft mode before they are published to dashboards. This guide provides step-by-step instructions to help you locate unpublished metrics in your workspace.
1. **From the `Home` page**, navigate to your desired workspace.
2. Click the **Metrics** tab in the main navigation area.
3. The complete list of metrics will be displayed in a table format:
* Each row shows the metric name, ID, associated dashboard, and last edited date.
* Any metrics marked as **'Unpublished'** in the Dashboard Name column indicate they have not been published to dashboards yet.
Regular monitoring of unpublished metrics helps maintain an organized workflow in your dashboard development process.
# New Relic Integration
Source: https://docs.usedatabrain.com/guides/newrelic-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to New Relic
# Integrating Databrain with New Relic
This guide explains how to send OpenTelemetry traces, metrics, and logs from your self-hosted Databrain instance to New Relic.
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* New Relic account (free tier available)
* New Relic License Key or Ingest Key
## Configuration
### 1. Get Your New Relic Ingest Key
1. Log into [New Relic](https://one.newrelic.com/)
2. Click on your name → **API Keys**
3. Copy your **Ingest - License** key
4. Note your account's data center (US or EU)
### 2. Determine Your OTLP Endpoint
| Data Center | OTLP HTTP Endpoint |
| ----------- | ------------------------------------ |
| **US** | `https://otlp.nr-data.net:4318` |
| **EU** | `https://otlp.eu01.nr-data.net:4318` |
### 3. Configure Databrain Environment Variables
Add these environment variables to your Databrain backend:
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# New Relic OTLP endpoint (US data center)
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net:4318
# Service name (appears in New Relic)
OTEL_SERVICE_NAME=databrain-api
# New Relic License Key (required)
OTEL_EXPORTER_OTLP_HEADERS=api-key=YOUR_LICENSE_KEY_HERE
# Optional: Set environment
NEW_RELIC_ENVIRONMENT=production
# Optional: Enable debug logging
LOG_LEVEL=info
```
### 4. Docker Compose Configuration
Update your `docker-compose.yml`:
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://otlp.nr-data.net:4318"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "api-key=${NEW_RELIC_LICENSE_KEY}"
NEW_RELIC_ENVIRONMENT: "production"
LOG_LEVEL: "info"
```
**Security**: Store your `NEW_RELIC_LICENSE_KEY` in a `.env` file:
```bash theme={"dark"}
# .env
NEW_RELIC_LICENSE_KEY=your_license_key_here
```
### 5. Kubernetes Configuration
For Kubernetes deployments:
```yaml theme={"dark"}
apiVersion: v1
kind: Secret
metadata:
name: newrelic-secret
type: Opaque
stringData:
license-key: your_license_key_here
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: databrain-backend
spec:
template:
spec:
containers:
- name: backend
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://otlp.nr-data.net:4318"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
- name: NEW_RELIC_LICENSE_KEY
valueFrom:
secretKeyRef:
name: newrelic-secret
key: license-key
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "api-key=$(NEW_RELIC_LICENSE_KEY)"
```
## Advanced: Using New Relic's OpenTelemetry Collector
For better control and additional features, deploy the New Relic OpenTelemetry Collector:
### Docker Compose with Collector
```yaml theme={"dark"}
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
environment:
NEW_RELIC_LICENSE_KEY: "${NEW_RELIC_LICENSE_KEY}"
networks:
- databrain
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector:4318"
OTEL_SERVICE_NAME: "databrain-api"
depends_on:
- otel-collector
```
### Collector Configuration
Create `otel-collector-config.yaml`:
```yaml theme={"dark"}
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
timeout: 1s
send_batch_size: 1024
# Add resource attributes
resource:
attributes:
- key: service.instance.id
from_attribute: host.name
action: upsert
# Add environment attribute
attributes:
actions:
- key: environment
value: production
action: upsert
exporters:
otlphttp:
endpoint: https://otlp.nr-data.net:4318
headers:
api-key: ${NEW_RELIC_LICENSE_KEY}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, resource, attributes]
exporters: [otlphttp]
metrics:
receivers: [otlp]
processors: [batch, resource, attributes]
exporters: [otlphttp]
logs:
receivers: [otlp]
processors: [batch, resource, attributes]
exporters: [otlphttp]
```
## What Gets Sent to New Relic
Once configured, Databrain automatically sends:
| Telemetry Type | New Relic Product | Description |
| -------------- | ------------------- | -------------------------------------------------------- |
| **Traces** | Distributed Tracing | API request spans with timing, status codes, and errors |
| **Metrics** | Metrics & Events | Request latency histograms, error rates, throughput |
| **Logs** | Logs | Correlated logs with trace context (trace\_id, span\_id) |
## Verification
### 1. Restart Databrain
```bash theme={"dark"}
docker compose restart databrainbackend
# or
kubectl rollout restart deployment/databrain-backend
```
### 2. Generate Test Traffic
```bash theme={"dark"}
# Health check
curl -X GET "https://your-databrain-instance.com/api/health"
# Sample API request
curl -X POST "https://your-databrain-instance.com/api/v2/metric/execute" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"metricId": "test-123"}'
```
### 3. Check New Relic UI
1. **Distributed Tracing**:
* Navigate to **APM & Services** → Select **databrain-api**
* Click **Distributed tracing**
* You should see traces within 1-2 minutes
2. **Service Map**:
* Go to **APM & Services** → **databrain-api** → **Service map**
* View dependencies and relationships
3. **Metrics**:
* Navigate to **Metrics & events**
* Query: `FROM Metric SELECT * WHERE service.name = 'databrain-api'`
4. **Logs**:
* Go to **Logs**
* Filter: `service.name = databrain-api`
* Click any log to see correlated traces
### 4. Check Backend Logs
Look for the initialization message:
```json theme={"dark"}
{
"level": "info",
"message": "[Telemetry] OpenTelemetry initialized - service: databrain-api, endpoint: https://otlp.nr-data.net:4318"
}
```
## Custom Attributes and Tags
Add custom attributes to all telemetry:
```yaml theme={"dark"}
# docker-compose.yml
environment:
OTEL_RESOURCE_ATTRIBUTES: "service.namespace=databrain,deployment.environment=production,team=backend"
```
These appear in New Relic as filterable attributes.
## New Relic Query Language (NRQL)
Use NRQL to create custom dashboards and alerts:
### Example Queries
**Average Response Time:**
```nrql theme={"dark"}
FROM Span SELECT average(duration.ms)
WHERE service.name = 'databrain-api'
AND span.kind = 'server'
FACET name SINCE 1 hour ago
```
**Error Rate:**
```nrql theme={"dark"}
FROM Span SELECT percentage(count(*), WHERE error.message IS NOT NULL)
WHERE service.name = 'databrain-api'
TIMESERIES SINCE 1 day ago
```
**Slowest Endpoints:**
```nrql theme={"dark"}
FROM Span SELECT percentile(duration.ms, 95)
WHERE service.name = 'databrain-api'
AND span.kind = 'server'
FACET name SINCE 1 hour ago
LIMIT 10
```
**Throughput:**
```nrql theme={"dark"}
FROM Span SELECT rate(count(*), 1 minute)
WHERE service.name = 'databrain-api'
AND span.kind = 'server'
TIMESERIES SINCE 1 hour ago
```
## Create Alerts
Set up alerts in New Relic:
### High Error Rate Alert
1. Go to **Alerts & AI** → **Alert conditions (policies)**
2. Create a new alert condition
3. Use NRQL query:
```nrql theme={"dark"}
FROM Span SELECT percentage(count(*), WHERE error.message IS NOT NULL)
WHERE service.name = 'databrain-api'
```
4. Set threshold: **Critical** when query returns value > 5 for at least 5 minutes
5. Add notification channel (email, Slack, PagerDuty, etc.)
### High Latency Alert
```nrql theme={"dark"}
FROM Span SELECT percentile(duration.ms, 95)
WHERE service.name = 'databrain-api'
AND span.kind = 'server'
```
**Threshold**: Critical when p95 latency > 2000ms for at least 5 minutes
## Troubleshooting
| Issue | Solution |
| ---------------------- | --------------------------------------------------------- |
| No data in New Relic | Verify `OTEL_ENABLED=true` and License Key is correct |
| 403 Forbidden | Check License Key has ingest permissions |
| Connection refused | Verify OTLP endpoint URL matches your data center (US/EU) |
| Missing traces | Wait 2-3 minutes; check backend logs for errors |
| High data ingest costs | Implement sampling in collector configuration |
### Debug Mode
Enable detailed logging:
```bash theme={"dark"}
LOG_LEVEL=debug
OTEL_LOG_LEVEL=debug
```
Check logs for:
* `[Telemetry] OpenTelemetry initialized`
* Connection errors to New Relic endpoint
* Trace export confirmations
### Verify Collector (if using)
Check collector logs:
```bash theme={"dark"}
docker logs otel-collector | grep -i "error\|failed"
```
Successful export logs:
```
Traces exported successfully to New Relic
```
## Dashboard Templates
New Relic provides pre-built dashboard templates for OpenTelemetry:
1. Go to **Dashboards** → **Import dashboard**
2. Search for "OpenTelemetry" templates
3. Import the "Service Performance" template
4. Customize filters to show `service.name = databrain-api`
## Best Practices
### 1. Use Sampling for High Traffic
Configure head-based sampling in the collector:
```yaml theme={"dark"}
processors:
probabilistic_sampler:
sampling_percentage: 10 # Sample 10% of traces
service:
pipelines:
traces:
processors: [probabilistic_sampler, batch]
```
### 2. Add Business Context
Include business-relevant attributes:
```typescript theme={"dark"}
import logger from 'utils/logger';
logger.info('Order processed', {
orderId: '12345',
userId: 'user-789',
amount: 99.99,
currency: 'USD'
});
```
These appear in New Relic logs and can be queried.
### 3. Use Service Levels (SLIs/SLOs)
Create SLIs in New Relic:
1. Go to **Service levels**
2. Define SLI: "95% of requests complete in \< 1s"
3. Track SLO compliance over time
## Pricing Considerations
New Relic pricing is based on:
* **Data Ingest**: GB of data ingested per month
* **User Seats**: Number of full platform users
**Free Tier**: 100 GB/month data ingest, 1 full platform user
**Cost Optimization**:
1. Use sampling (doesn't affect metrics accuracy)
2. Set appropriate data retention periods
3. Filter out low-value spans (health checks)
4. Use the collector for local aggregation
## Support
* **New Relic Documentation**: [https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/](https://docs.newrelic.com/docs/more-integrations/open-source-telemetry-integrations/opentelemetry/)
* **New Relic Support**: [https://support.newrelic.com/](https://support.newrelic.com/)
* **Community Forum**: [https://discuss.newrelic.com/](https://discuss.newrelic.com/)
For Databrain configuration issues, contact your Databrain support team.
# Observability Setup
Source: https://docs.usedatabrain.com/guides/observability-setup
Configure logging and OpenTelemetry for monitoring your self-hosted Databrain instance
# Observability Setup for Self-Hosted Deployments
This guide explains how to configure logging levels and enable OpenTelemetry for comprehensive observability in your self-hosted Databrain deployment.
## Log Level Configuration
Databrain supports configurable log levels to help with troubleshooting. By default, the log level is set to `info`.
### Available Log Levels
| Level | Description |
| ------- | ------------------------------------------------------ |
| `error` | Only error messages |
| `warn` | Warnings and errors |
| `info` | Informational messages, warnings, and errors (default) |
| `debug` | All messages including detailed debug information |
### Configuration
Add to your `.env` file:
```bash theme={"dark"}
LOG_LEVEL=info
```
To enable debug logging for troubleshooting:
```bash theme={"dark"}
LOG_LEVEL=debug
```
## OpenTelemetry Integration
Databrain supports OpenTelemetry (OTel) for distributed tracing and metrics. This enables you to:
* Track API latency for all endpoints
* Monitor error rates
* See processing time breakdowns (database queries, external API calls, etc.)
* Correlate logs with traces for easier debugging
### Prerequisites
To use OpenTelemetry, you need an OTLP-compatible collector or backend. Popular options include:
* **Self-hosted**: [SigNoz](https://signoz.io/), [Jaeger](https://www.jaegertracing.io/), [Grafana Tempo](https://grafana.com/oss/tempo/)
* **Cloud**: Datadog, New Relic, Honeycomb, or any OTLP-compatible backend
### Configuration
Add these environment variables to your `.env` file:
```bash theme={"dark"}
# Enable OpenTelemetry (disabled by default)
OTEL_ENABLED=true
# Your OTLP collector endpoint
OTEL_EXPORTER_OTLP_ENDPOINT=http://your-collector:4318
# Service name for traces (optional, defaults to databrain-api)
OTEL_SERVICE_NAME=databrain-api
```
### Docker Compose Setup
If you want to run an OpenTelemetry Collector alongside Databrain, uncomment the collector service in your `docker-compose.yml`:
```yaml theme={"dark"}
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
restart: always
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
volumes:
- ./otel-config.yaml:/etc/otelcol/config.yaml
networks:
- datab
```
Then update your backend environment:
```bash theme={"dark"}
OTEL_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
```
### Example: Collector Configuration for Jaeger
Create an `otel-config.yaml` file:
```yaml theme={"dark"}
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
send_batch_size: 1024
exporters:
jaeger:
endpoint: jaeger:14250
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
```
## What Gets Instrumented
When OpenTelemetry is enabled, Databrain automatically instruments:
| Component | What's Tracked |
| -------------- | ------------------------------------------------ |
| HTTP Requests | Incoming API requests with latency, status codes |
| Express Routes | Route-level timing and errors |
| PostgreSQL | Database query duration and errors |
| Redis | Cache operations timing |
| Outgoing HTTP | External API calls (Hasura, Keycloak, etc.) |
### Example Trace
A typical API request trace shows:
```
GET /api/v2/metric/execute (1,247ms)
├── middleware.auth (12ms)
│ └── HTTP POST keycloak/auth/verify (10ms)
├── getMetricConfig (45ms)
│ └── HTTP POST hasura/v1/graphql (43ms)
├── buildQuery (8ms)
├── executeQuery (1,150ms)
│ └── PostgreSQL Query (1,148ms)
└── formatResponse (32ms)
```
## Troubleshooting
### Logs Not Appearing at Expected Level
1. Verify `LOG_LEVEL` is set correctly in your `.env`
2. Restart the backend service after changing the value
3. Log levels are case-insensitive (`DEBUG`, `debug`, `Debug` all work)
### OpenTelemetry Not Working
1. Verify `OTEL_ENABLED=true` (must be exactly `true`)
2. Check that `OTEL_EXPORTER_OTLP_ENDPOINT` is reachable from the backend container
3. Check backend logs for `[Telemetry] OpenTelemetry initialized` message
4. If you see `OTEL_ENABLED=true but OTEL_EXPORTER_OTLP_ENDPOINT not set`, configure the endpoint
### High Overhead Concerns
OpenTelemetry adds minimal overhead when enabled. If you experience performance issues:
1. Ensure your collector can handle the volume
2. Consider sampling in the collector configuration
3. Disable OTel temporarily by setting `OTEL_ENABLED=false`
## Structured Logging
Databrain uses Winston for structured, JSON-formatted logging. All logs include:
* **Timestamp**: ISO format with milliseconds
* **Level**: error, warn, info, or debug
* **Message**: Human-readable description
* **Metadata**: Structured data as key-value pairs
* **Trace Context**: When OpenTelemetry is enabled, includes `trace_id` and `span_id`
### Example Log Output
```json theme={"dark"}
{
"level": "info",
"message": "API request completed",
"timestamp": "2026-02-03 10:30:45.123",
"method": "POST",
"url": "/api/v2/metric/execute",
"statusCode": 200,
"duration": 1247,
"userId": "123",
"trace_id": "1a2b3c4d5e6f7g8h",
"span_id": "9i0j1k2l3m4n"
}
```
### Usage in Code
```typescript theme={"dark"}
import logger from 'utils/logger';
// Good - structured logging
logger.info('User logged in', { userId: '123', method: 'oauth' });
logger.error('Database error', { error: err.message, query: sqlQuery });
// Avoid - unstructured logging
console.log('User 123 logged in'); // ❌ Don't use console.log
```
## Default Behavior (No Configuration Required)
If you don't configure any observability settings:
* Log level defaults to `info`
* OpenTelemetry is disabled (zero overhead)
* Logs output to stdout in JSON format
* Structured logging with Winston is always enabled
This maintains backward compatibility with existing deployments.
# Add a Data Source
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/add-a-data-source
Data sources in Databrain enable users to fetch and manage data from various platforms efficiently. This guide walks you through the simple process of adding and configuring a new data source.
What is a Data Source in Databrain?
A datasource in Databrain is a connection configuration that enables secure access to your organization's data warehouses and databases. It serves as a bridge between Databrain's analytics platform and your data storage systems.
Key Benefits of adding a Data Source in Databrain
* **Centralized Data Management:** Access all your data sources from a single platform
* **Secure Connectivity:** Enterprise-grade security with encrypted connections
* **Real-time Analysis:** Direct connection to your data warehouse enables real-time analytics
* **Scalable Architecture:** Support for high-volume data processing and multiple concurrent users
**Note:**
Ensure the Databrain IP Address is whitelisted. Kindly refer the below link:
Navigate to the **"Data Studio"** page, located near the "**Home**" page and click on the **"+ Datasource"** button in the "**Datasources**" tab.
For details related to tenancy level, kindly refer the below link:
For a detailed guide on connecting to various data sources, please refer the below link:
# Choosing the Right Tenancy Model for Your Data
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/choosing-the-right-tenancy-model-for-your-data
Every team stores client data differently. Some keep everything in one big table, others prefer separate schemas, and some even go as far as spinning up a database per client. The way your data is structured determines which tenancy model you should choose in Databrain.
This guide will help you decide. The first step is to understand how tenancy levels work.
## Understanding Tenancy Levels
A tenancy level represents a layer at which client data is separated and organized. You might separate data at the table level, schema level, or even across databases. The more levels you introduce, the more control and isolation you can achieve.
* One level of tenancy: Clients are separated at a single layer (e.g., by table or schema).
* Multi-level tenancy: Clients are separated across two or more layers (e.g., schema + table, or database + schema + table).
With this in mind, let’s walk through the different setups.
## One Level of Tenancy
If your setup has only one level of tenancy, here’s how your data might look:
### Start with your tables
Ask yourself:
**Do all your clients live in a single table?**
* If yes, your data has a `client_id` (or similar) column to mark which row belongs to which client.
* Example: One `orders` table where every record is tagged with the client it belongs to.
* This maps to Single Table Tenancy — a shared database, shared table setup.
Read this guide on how to set up table tenancy: [Configure Table Tenancy](https://docs.usedatabrain.com/guides/datasources/configure-tenants)
If not, let’s move on.
### Organized by schema?
**Do you group client data by schema inside a single database?**
* If you use one shared schema and rely on a `client_id` column
* Example: A project management platform where all companies' contacts, deals, and activities live in one schema, but each row is tagged with a company ID.
* This maps to Single Schema Tenancy.
* If you create a dedicated schema for each client
* Example: A payroll system where each company has its own schema (`client1.employees`, `client2.employees`), keeping the payroll data fully separated.
* This maps to Multi Schema Tenancy.
If not, let’s step up a level.
### Full database per client?
**Do you provision a separate database for each client?**
* On MSSQL, this usually means one server with multiple client databases
* Example: An HR management platform for enterprises, where each enterprise customer gets their own MSSQL database (`db_client1`, `db_client2`), all on the same server.
* This maps to Multi Database MSSQL Tenancy.
To enable this in Databrain: when creating your MSSQL datasource, check “Enable Multiple Databases” and select Multi Database Tenancy.
[Add a Datasource](https://docs.usedatabrain.com/guides/quick-start/add-a-data-source)
* On Postgres or BigQuery, this often means spinning up one database per client
* Example: A fintech platform where each client has their own Postgres database instance for compliance and isolation.
* This maps to Multi Datasource (Hybrid Tenancy).
Read more on [Hybrid Tenancy using Databrain](https://www.usedatabrain.com/blog/multi-tenant-analytics)
If not, let’s check the simplest option.
### One shared connection?
**Do all clients share one single database connection?**
* If yes, you’re on Single Datasource Tenancy.
* Example: A chatbot where all client conversations are stored in the same database, separated by a client identifier. A `client_id` column ensures each company only views their own conversations.
## Multi-Level Tenancy
If your setup requires more than one layer of separation, you fall into multi-level tenancy. This setup gives you finer control by combining multiple levels such as schema, table, and database.
Here are the common patterns:
### Do you separate clients by schema and refine with table tenancy?
* Example: A reporting tool where each client’s data is grouped under schemas, but within each schema, tables restrict access to different departments (e.g., sales vs. finance).
* This maps to Datasource → Schema → Table Tenancy.
* In Databrain, this refinement is managed by [App Filter](https://docs.usedatabrain.com/guides/filters/app-filter) — a feature that applies table-level restrictions inside the platform.
### Do you separate clients by multiple levels of tables?
* Example: A marketing analytics platform where each client has its own set of tables, and another level of tables to further restrict by campaign or region.
* This maps to Datasource → Table Tenancy Level 1 → Table Tenancy Level 2.
### Do you use MSSQL with schemas and table tenancy?
* Example: An MSSQL deployment where each client database has multiple schemas (e.g., HR, payroll, support), and tables refine access by team or role.
* This maps to MSSQL Database → Schema → Table Tenancy.
### Do you use MSSQL with multiple levels of tables?
* Example: An MSSQL deployment with client-level databases, each with shared tables for operations, refined by another level of tables for country-level access.
* This maps to MSSQL Database → Table Tenancy Level 1 → Table Tenancy Level 2.
### Do you need the highest level of isolation across all layers?
* Example: A multinational platform where each client has its own database, schemas divide regions (e.g., North America, Europe), tables separate domains (e.g., employees, payroll, performance), and another level of tables ensure only certain roles (e.g., HR manager vs. finance lead) can access specific slices of the data.
* This maps to Datasource → Database → Schema/Table → Table Tenancy.
***
With this flow, you can match your current data setup to the tenancy model that fits. Start by identifying how many layers of separation you currently have. Then, see whether you’re working with tables, schemas, databases, or datasources, and whether you need an additional row level tenancy fine-grained control.
Once you know where you land, Databrain takes care of the rest.
* [Add a Datasource](https://docs.usedatabrain.com/guides/quick-start/add-a-data-source)
* [Configure Tenants](https://docs.usedatabrain.com/guides/datasources/configure-tenants)
* [Create a Workspace](https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-workspace)
* [Create a Dashboard](https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-dashboard)
* [Create a Metric](https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric)
* [App Filter](https://docs.usedatabrain.com/guides/filters/app-filter)
# Create a Dashboard
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-dashboard
This guide provides a straightforward process for creating a private workspace. This feature enhances privacy and allows for focused work without visibility constraints.
On the **Home** page, click on the **"+ Dashboard"** button located below your account name.
* In the **"Dashboard Name"** field, enter a suitable title for your new dashboard.
* In the **"Dashboard ID"** field, input a unique ID for the dashboard.
* Finally, click **"Save"** to create the dashboard.
Your dashboard is now created and can be viewed in the **"Dashboards"** section!
Your dashboard has been successfully created and is now available in your workspace for further customization and metric building.
# Create a Metric
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric
Metrics offer detailed insights and visualization of your data within a dashboard. This guide provides a step-by-step process to create a Metric in Databrain.
> **What is a Metric in Databrain?**\
> A metric is a configurable analytical component that enables you to visualize and analyze your data through various chart types. It serves as a building block for dashboards, allowing you to create comprehensive data visualizations by combining multiple metrics.
* Select the dashboard where you intend to add the metric.
* For the first metric, click the "+ Metric" button.
* Inside the metric creation page, select the desired table from your database schema.
* Drag and Drop columns into Dimensions and Measures as required.
* Choose an aggregation method for the Measure: `COUNT ROW`, `AVG`, `SUM`, `COUNT`, `COUNT DISTINCT`, `MAX`, `MIN`, or `Original Value`.
* Choose a visualization from the Charts icon.
* Use Joins, Group by, Filters, Sort, and Dynamic Property from the toolbar to enhance your metric.
* Adjust chart settings via the Settings icon.
* For chart-specific setup instructions, see [Chart Setup guides](/guides/visualizations-actions-and-appearance/chart-setup/overview).
For a detailed guide on Dynamic Property, refer to the section below:\
Dynamic Property
* After creating your metric, you can save it to a dashboard or as a draft.
* Once satisfied with the chart, click "Save to Dashboard" on the top right.
* Choose the dashboard where the metric should be stored.
* Provide a Metric Name, Metric ID, and a brief Description.
* If needed, add a long description or footnote and toggle the option for end users to archive metrics.
* Finally, click "Save" to publish the metric to your dashboard.
For more details on long descriptions and footnotes:\
Footnote and Long Description
* Add Metric to Dashboard: Select a dashboard name from the dropdown menu and click "Save" to integrate your metric into the chosen dashboard. Your metric will appear in the selected dashboard!
* Save Metric as Draft: Leave the dashboard selection empty and click "Save" to create an unpublished metric. Draft metrics can be added to dashboards at a later time.
For more details on saving a metric as a Draft:
You’ve successfully created a metric in Databrain!\
Your new metric is now ready for visualization, analysis, and integration into dashboards.
# AI Copilot
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric/ai-copilot
AI Copilot helps users turn a plain-language analytics question into a working Databrain metric.
AI Copilot helps users turn a plain-language analytics question into a working Databrain metric. It is available inside the metric creation workflow and can generate SQL, execute the query, suggest a visualization, map dimensions and measures, and keep the conversation available through session history.
## Prerequisites
Before using AI Copilot, make sure the workspace has:
* A connected data source or datamart with schema access.
* At least one LLM configured in Databrain under **Settings > LLMs** **> +LLM**
* At least one model selected under **Workspace Settings > AI Copilot LLM**.
* Access to the metric creation page.
* Permission to update workspace settings, if you are configuring the feature.
The **LLM Settings** field is used for Chat Mode and Metric Summary. The **AI Copilot LLM** field is used for AI Copilot and the custom SQL editor.
## Steps to setup AI Copilot:
## 1. Enable AI Copilot
1. Open the workspace where you want to use AI Copilot.
2. Click the workspace settings icon.
3. In **Workspace Settings**, open the **General** tab.
4. Under **Creator Settings**, select **Power Mode**.
5. In **AI Copilot LLM**, select one or more LLMs.
6. Click **Save**.
If no global LLM exists, Databrain prompts the user to configure one from **LLM Settings**. If a global LLM exists but no workspace model is selected for AI Copilot, Databrain prompts the user to update **Workspace Settings**.
## 2. Open AI Copilot
1. Go to the metric creation page.
2. Confirm the correct workspace, data source or datamart, and client context.
3. Click **AI Copilot** in the top-right of the metric builder.
AI Copilot opens as a right-side panel. The panel shows suggested questions when enough schema, history, memory, or example context is available.
## 3. Ask a question
Type a business question in natural language. For best results, include the metric, grouping, filter, and time period when relevant.
Examples:
* `Show total users by subscription type`
* `Trend of revenue by month for the last 6 months`
* `Top 5 customers by order value`
* `How is product demand segmented across different subscription models?`
If multiple AI Copilot LLMs are enabled for the workspace, use the model selector in the input area to choose the model for the request.
After you submit the question, AI Copilot:
1. Validates that the prompt is an analytics/data question.
2. Uses the workspace or datamart schema, table relationships, examples, memory, and prior conversation context.
3. Generates SQL through the selected LLM.
4. Executes the SQL through Databrain.
5. Returns a chart-ready response with SQL, metadata, reasoning, dimensions, and measures.
## 4. Review the result
AI Copilot displays the generated metric in the main chart area and shows the explanation in the Copilot panel.
Review the following before saving:
* **Chart output**: Confirms whether the generated result answers the question.
* **Dimensions**: Shows the grouping fields used in the metric.
* **Measures**: Shows the aggregated values used in the metric.
* **Reasoning**: Explains why Copilot selected the tables, columns, and aggregation.
* **Tables Used**: Lists the source tables used by the generated SQL.
* **Columns Used**: Lists the source columns used by the generated SQL.
* **SQL Query**: Shows the generated SQL. Expand this section to inspect the query.
In the SQL section, use the edit icon to open the generated SQL in the editor. You can adjust the query before applying or saving the metric.
## Use the context window indicator
The context window indicator shows how much of the selected model's context window has been used in the current Copilot session.
Hover over the indicator to view:
* **Input** tokens used by prompts and context.
* **Output** tokens used by model responses.
* The selected model's total context window.
If the context window becomes full, Databrain disables the Copilot input and asks you to start a new session. Use this when the conversation has become too long or when you want to switch to a different analysis topic.
## Use Copilot history
AI Copilot keeps session history so users can continue prior analysis without starting from scratch.
From the Copilot panel, you can:
* Start a new session using the plus icon.
* Open history using the timer icon.
* Reopen a previous session.
* Rename a session.
* Archive a session you no longer need.
Sessions are scoped to the user and workspace context. When reopened, Databrain restores the previous questions and responses so follow-up questions can continue from the same analytical thread.
## Best practices
* Use business-friendly but specific questions.
* Include dimensions, measures, filters, and date ranges when known.
* Review SQL before saving production metrics.
* Use separate sessions for unrelated analysis topics.
## Related resources
* [LLM Connectors](https://docs.usedatabrain.com/developer-docs/helpers/llm-connectors)
* [AI Copilot for Embedded Analytics](https://www.usedatabrain.com/blog/ai-copilot-for-embedded-analytics)
# Create a Metric using Chat Mode
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric/create-a-metric-using-chat-mode
This guide offers a streamlined process for creating a metric using Chat Mode, making it easy for users to visualize and customize their data effectively.
> Databrain's chat mode is an intuitive, conversational interface that allows users to create metrics and visualizations using natural language queries
**Key Benefits:**
* **Natural Language Interaction** — Users can simply type questions about their data in plain English, making it accessible to non-technical users.
* **Automated Insights Generation** — The chat mode responds to queries and also generates visualizations and detailed explanations automatically, streamlining the process of data analysis and reducing manual report generation time.
- Select the dashboard where you intend to add the metric.
- For the first metric, click the **+ Metric** button.
Provide an appropriate question based on the metric you want to create, and click on the **→** icon.
* Choose your preferred visualization from the "Charts" icon.
* Customize your graph using the options available in the "Appearances" icon.
* (Optional) Use **Summarize** to view the AI-generated interpretation, and **SQL** to view the SQL query behind the visualization.
* Click on **Save**.
Fill in the necessary details for your metric and click on the **Save** button.
You’ve successfully created a metric using Chat Mode in Databrain!\
Your visualization, summary, and configuration are now saved — enabling faster, more intuitive analysis powered by natural language.
# Create a Metric using Custom SQL
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric/create-a-metric-using-custom-sql
This guide provides a step-by-step approach to utilizing custom SQL for creating metrics, which can enhance your data analysis capabilities.
On the **Create Metric** page, select the **"Custom Query"** option.
In the **Query Editor**, enter your custom SQL query.
Use the **"Format Query with AI"** option to align with Databrain's best practices.
Click **"Run Query"** to execute.
Once the query runs, review the **Query Result** section to view your raw SQL output in a table.
You can download the results as CSV if needed.
Click **Use Results >** to proceed. You can save it in the following ways:
**1. Table Chart**
Click **"Use as Table Chart"**, configure additional settings, and save it to your dashboard.
**2. Table Chart with Dynamic Table Property**
This automatically adjusts to the latest structure of your SQL query result — ideal for evolving datasets using `SELECT *`.
**3. Publish as Custom Dataset**
Provide a dataset name, choose a schema, and click **Save**.
**4. New Chart**
Select your preferred chart type, configure it, and save.
At any point, you can switch between the **Chart Builder** and the **Query Editor**.
Make changes to your SQL and immediately view updated results in both areas.
You’ve successfully created a metric using Custom SQL in Databrain!\
Your query-driven metric is now active, giving you full control over data transformation, advanced logic, and custom visualizations directly from your SQL output.
# Create Calculated Fields
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric/create-custom-columns
This guide offers a straightforward approach to creating custom columns by utilizing calculated fields and SQL queries, enabling users to tailor their data analysis to specific needs.
**Purpose of Custom Columns:**
**Custom columns** in Databrain enable users to create and save new data fields derived from their existing data. These columns are mathematically calculated, transformed, or altered to suit specific business needs. Once created, they can be reused across all metrics and analyses.
**Example Use Cases:**
* **Combining fields:** Merge first and last names into a "Full Name" column for consistent use across datasets.
* **Standardizing calculations:** Create a "Net Revenue" column by subtracting refunds and discounts from total sales, ensuring consistent formulas across reports.
* **Defining business-specific KPIs:** Calculate "Customer Lifetime Value" based on purchase frequency, average order value, and customer lifespan to track business performance.
### 1. Access Calculated Field
In the metric creation page, hover over the **"Measures"** area and click on the **"+fx"** icon.
### Databrain offers two methods for creating custom columns
#### Quick Field — for simple calculations
**Use Cases:**
* Simple mathematical operations (e.g., addition, subtraction)
* Basic business metrics (e.g., profit margins, conversion rates)
* Standardized calculations across reports
### Method 1: Quick Field
* **Column Selection**: Choose your input columns.
* **Data Configuration**: Set data type and then choose aggregate function.
* **Operation Selection**: Pick a mathematical operator (`+`, `-`, `*`, `/`).
* Assign an alias for the calculated field and click on **"Save"** to save the calculated field.
### Method 2: Complex Field
* In the **Metric Creation** page, hover over the **Measures** area and click on the **"+fx"** icon.
* Select the target table name, then enter your SQL query in the code area.
* Follow the syntax:\
`“schemaName_tableName”.“columnName”`
* Replace `"schemaName_tableName"` with your actual schema and table names.
* (Optional) Use the **“Format Query with AI”** option to align with Databrain’s best practices.
* Assign an alias to the query in the \*\*"Query Name" \*\*field and click **"Add"**.
* Finally, click **"Save to Dashboard"**.
Once saved, the custom column is added to the specified table (e.g., `demo_sales`) and is ready for use in any metric or analysis.
Here is an illustration of generated SQL after adding the Custom SQL Column:
# Create a Private Workspace
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-private-workspace
This guide provides a straightforward process for creating a private workspace. This feature enhances privacy and allows for focused work without visibility constraints.
* **Enhanced Security:** Only invited members can access the workspace
* **Controlled Visibility:** Your work remains hidden from the general organization
* **Focused Environment:** Work on sensitive projects
* **Testing Ground:** Safely experiment with metrics before making them public
On the Home page, click the + button located near the Workspaces drop-down menu.
Enter a title in the Workspace Name field.
Under Select Data Connection, choose either Data Source or Data Mart.
In the Select Data Mart or Select Data Source field, pick the appropriate option.
Toggle on the Private Workspace setting.
Your private workspace will now appear in the Private section of the Home page.
You’ve successfully created a Private Workspace in Databrain!\
Your workspace is now secure and visible only to invited members, providing a safe environment to experiment, analyze, and collaborate on sensitive projects.
# Create a Workspace
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-workspace
This guide provides a detailed process for creating a new workspace within the application. Follow these steps to set up a workspace tailored to your specific needs.
> A **workspace** in Databrain is a dedicated environment where teams can organize and manage their data analytics projects. It serves as a collaborative space where team members can create, share, and analyze metrics specific to their department or project needs.
On the Home page, click the + button located near the Workspaces drop-down menu.
In the Workspace name field, input a title such as Product Management.\
Under Select Data Connection, choose from the available options: Data Mart, Data Source, or Multi Data Source.
In Select DataSource/DataMart, select the relevant Data Source or Data Mart name from the dropdown.\
Then, click Save to create the workspace.
Once saved, your workspace is successfully created and listed under Workspaces on the left navigation panel.
You’ve successfully created a new workspace in Databrain!\
Your workspace is now ready for use — start adding dashboards, metrics, and visualizations to collaborate and analyze data efficiently with your team.
# Explore Data
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/explore-data
This guide provides a overview of how to explore and manage data within the platform. It is used to easily navigate and familiarize with your tables with sort, filter, and search functionalities.
## Access Explore Data
Navigate to the Home page and click the **"Explore Data"** button located next to the **"+ Dashboard"** button.
## View Data Tables
* Select your desired table from the left navigation panel.
* Tables are organized under the **"main"** section for easy access.
### Table Operations
1. **Sort Data**
* Click the arrow icon (↑↓) next to any column header to sort in ascending or descending order.
2. **Customize Columns**
* Use the column selector to show/hide specific columns.
* Click **"Select All"** for quick column management.
3. **Download Data**
* Click the download icon (↓) in the top-right corner to export data as CSV.
4. **Navigation**
* Use the pagination controls at the bottom to move between pages.
5. **Search Records**
* Use the search bar at the top to filter data across all columns.
You’ve successfully explored and managed your data in Databrain!\
You can now sort, filter, search, and export tables effortlessly — giving you complete control and visibility over your data for faster analysis.
# Forgot password? Recover your Databrain Account
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/forgot-password-recover-your-databrain-account
This guide offers a straightforward solution for users who have forgotten their Databrain account password, ensuring quick access to their accounts.
In the login page, click on the **"Forgot password?"** button.
Enter your registered mail ID and click on **"Send Reset Link"** button.
Navigate to the link shared to your registered mail ID by clicking on the **"Reset Password"** button.
Enter your new password and click on **"Reset Password"** to change your password.
Login to your account with the new password!
# Google Sign In Setup for Self-hosted app
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/google-sign-in-setup-for-self-hosted-app
This guide provides essential instructions for accessing your Databrain account effortlessly using Google Sign-In for self-hosted app.
Follow the steps mentioned in this link to create a Google OAuth Client:
[https://www.balbooa.com/help/gridbox-documentation/integrations/other/google-client-id](https://www.balbooa.com/help/gridbox-documentation/integrations/other/google-client-id)
**Authorized JavaScript origins:**
```text theme={"dark"}
{YOUR_SELFHOSTED_APP_URL}
eg: https://selfhosted-abc-org.centralindia.cloudapp.azure.com
```
**Authorized redirect URIs:**
```text theme={"dark"}
{YOUR_SELFHOSTED_APP_URL}/users/sign-in
eg: https://selfhosted-abc-org.centralindia.cloudapp.azure.com/users/sign-in
```
```text theme={"dark"}
{YOUR_SELFHOSTED_APP_URL}/users/sign-up
eg: https://selfhosted-abc-org.centralindia.cloudapp.azure.com/users/sign-up
```
After the OAuth client is created, copy the Client ID and Client Secret.
Add the environment variable to your backend environment configuration:
```env theme={"dark"}
GOOGLE_OAUTH_CLIENT_ID = {YOUR_GOOGLE_OAUTH_CLIENT_ID}
eg: GOOGLE_OAUTH_CLIENT_ID = 694528862847-u9...nnibb.apps.googleusercontent.com
```
# How to Invite Users?
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/how-to-invite-users
Learn how to invite users and configure email settings in both app and self-hosted environments.
## App Environment
### 1. Inviting a User
In the app environment, an admin can invite users with or without configuring email settings.\
In both cases, the invited user will receive an email notification with a secure login link.
* **If email settings are configured:**\
The invitation email will be sent using your configured email service.
* **If email settings are not configured:**\
Databrain will automatically send the invitation email.
1. Navigate to the **"Invite User"** section.
2. Enter the user’s email address.
3. Assign a role — Developer, Editor, or Viewer and select the workspaces the user should have access to.
4. Click **"Invite"** to complete the process.
***
### 2. Logging In
The invited user will receive an email containing a login link.\
By clicking the link, they can log in and access their Databrain account.
***
## Self-Hosted Environment
In a self-hosted environment, the admin must configure email settings before inviting users.\
This ensures that invitation emails are delivered successfully.
### 1. Configuring Email Settings
1. Navigate to the **"Settings"** page.
2. In the **"Embed Settings"** section, configure the required email settings.
3. Click **"Authenticate"** to save and validate the configuration.
***
### 2. Inviting a User
After the email settings are configured:
1. Navigate to the **"Invite User"** section.
2. Enter the user’s email address.
3. Assign a role — Developer, Editor, or Viewer and select the workspaces the user should have access to.
4. Click **"Invite"** to complete the process.
***
### 3. Logging In
The invited user will receive an email containing the login link.\
They can click the link and log in to access their Databrain account.
# Onboarding
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/onboarding
Welcome to Databrain
Check out the below article if you haven't signed up already.
After creating your workspace, you have set up a datasource to your account.
Demo Data: You can also use the Demo Workspace where we have connected our demo database for you to explore our app with.
Connect Your Own Data: If you prefer to use your data, we offer connections in:
Redshift
Snowflake
Databricks
S3
BigQuery
MySQL
PostgreSQL
MongoDB
Elastic Search
ClickHouse
MSSQL
You can create your own dashboard or use our Demo Dashboard to get started.
For more info on connecting your own DataSource, refer the below articles.
# Sign-In
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/sign-in
This guide provides essential instructions for accessing your Databrain account effortlessly.
Enter your login credentials and click on **"Continue ->"**
Your Databrain account is ready to use!
# Sign-Up
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/sign-up
This guide provides a straightforward process for signing up for Databrain.
Click on the **"Start Building"** button to get started with Databrain.
Configure Sign Up
* Enter your name and click on **"Continue".**
* Fill out the details and click on **"Create Account"** button.
Navigate to the link shared to your registered mail id by clicking on the **"Verify Email"** button.
Your DataBrain account is now ready to use!
# SSO Login
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/sso-login
To enable Single Sign-On (SSO) for your application, you can integrate either a SAML or OIDC Identity Provider (IdP).
Navigate to "Settings" page and "\> MFA & SSO Settings" section
In the "SSO Settings" section, enable the toggle and click on "+Idp"
You can choose either "Saml" or "Oidc" Idp
For Saml configuration, please refer the below link:
For Oidc configuration, please refer the below link:
# Oidc Identity Provider (Idp)
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/sso-login/oidc-identity-provider-idp
Navigate to **MFA\&SSO Settings** section on **Settings** page.
Enable **SSO.**
Click on **Save** button.
Click on **+IDP** button.
In the **New IDP** form fill the following details:
* **Provider Type:** Choose **OIDC** provider
* **Alias:** Choose unique id for the IDP. *eg:* oidc-idp-1
* **Sign-In Redirect URI:** Copy this and use this endpoint as redirect uri to create a application in Identity provider(Okta).
* **Logout Redirect URI:** Copy this and use this endpoint as post logout redirect URIs that can be sent by the Service Provider(Databrain App) in the logout request to Identity Provider(Okta).
* **Display Name:** Choose any name for your IDP.
* **Issuer:** Enter your Identity Provider's **Issuer(ID)**. In Okta, you can get it from the configuration link which looks like [https://dev-61653336-admin.okta.com/.well-known/openid-configuration](https://dev-61653336-admin.okta.com/.well-known/openid-configuration) eg: [https://dev-61653336.okta.com](https://dev-61653336.okta.com/)
* **Authorization Url:** Enter your Identity provider's **Authorization Endpoint**. In Okta, you can get it from the configuration link which looks like [https://dev-61653336-admin.okta.com/.well-known/openid-configuration](https://dev-61653336-admin.okta.com/.well-known/openid-configuration) eg: [https://dev-61653336.okta.com/oauth2/v1/authorize](https://dev-61653336.okta.com/oauth2/v1/authorize)
* **Token Url:** Enter your Identity provider's **Token Endpoint**. In Okta, you can get it from the configuration link which looks like [https://dev-61653336-admin.okta.com/.well-known/openid-configuration](https://dev-61653336-admin.okta.com/.well-known/openid-configuration) eg: [https://dev-61653336.okta.com/oauth2/v1/token](https://dev-61653336.okta.com/oauth2/v1/token)
* **Logout Url:** Enter your Identity provider's **Logout Endpoint**. In Okta, you can get it from the configuration link which looks like [https://dev-61653336-admin.okta.com/.well-known/openid-configuration](https://dev-61653336-admin.okta.com/.well-known/openid-configuration) eg: [https://dev-61653336.okta.com/oauth2/v1/logout](https://dev-61653336.okta.com/oauth2/v1/logout)
* **Client ID:** Enter the **Client ID**of your Identity Provider application.
eg: 0oaodey86daNSpLoL5\*\*
Click on **Create IDP** button.
# Saml Identity Provider (Idp)
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/sso-login/saml-identity-provider-idp
Navigate to **MFA\&SSO Settings** section on **Settings** page.
Enable **SSO.**
Click on **Save** button.
Click on **+IDP** button.
In the **New IDP** form fill the following details:
* **Provider Type:** Choose **SAML** provider
* **Alias:** Choose unique id for the IDP. *eg:* saml-idp-1
* **Redirect URI:** Copy this and use this endpoint as redirect uri to create your Identity provider application.
* **SP Entity ID/Issuer:** This will be the **ID** of the Service Provider(Databrain App) for this particular IDP. Use it to create your Identity Provider application.
* If your Identity Provider requires signature certificate of Service Provider(Databrain App) then click on **Download Signature Certificate** button and use it to create your Identity Provider application.
* **Display name:** Choose any name for your IDP.
* **Idp Entity ID/ Issuer:** Enter your Identity Provider application's **ID**. In Okta, you can get it from Applications-> Your Application-> Sign On -> View SAML setup instructions. eg: [http://www.okta.com/exkgbjqawotEyuxvX5d7](http://www.okta.com/exkgbjqawotEyuxvX5d7)
* **SSO Url:** Enter your Identity provider application's **Single Sign On Url**. In Okta, you can get it from Applications-> Your Application-> Sign On -> View SAML setup instructions. eg: [https://dev-61653336.okta.com/app/dev-61653336\_samldb\_1/exkgbjqawotEyuxvX5d7/sso/saml](https://dev-61653336.okta.com/app/dev-61653336_samldb_1/exkgbjqawotEyuxvX5d7/sso/saml)
* **Logout Url:** Enter your Identity provider application's **Single Logout Url**. In Okta, you can get it from Applications-> Your Application-> Sign On -> View SAML setup instructions. eg: [https://dev-61653336.okta.com/app/dev-61653336\_samldb\_1/exkgbjqawotEyuxvX5d7/slo/saml](https://dev-61653336.okta.com/app/dev-61653336_samldb_1/exkgbjqawotEyuxvX5d7/slo/saml)
Click on **Create IDP** button.
# Workspace Settings
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/workspace-settings
This guide provides essential insights on customizing your workspace settings effectively. This ensures optional accessibility and control over your data.
### 1. Access Workspace Settings
Click on the **"Settings"** icon adjacent to your workspace in the **"Home"** page.
# Cache Settings
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/workspace-settings/cache-settings
## Cache Settings
DataBrain supports query result caching to reduce database load and improve dashboard performance. You can either use **DataBrain's managed cache** or **bring your own Redis/Elasticache** instance.
Cache is configured per workspace. Each workspace can independently choose its caching mode and settings.
***
## Caching Modes
**Best for:** Teams that want fast setup without managing Redis infrastructure.
DataBrain provides a managed Redis instance. You only need to enable it and set a TTL — no host, port, or password configuration required.
**How it works:**
1. Toggle **"Cache Settings"** to enable caching
2. Enable the **"Databrain Caching"** option
3. Set your desired cache expiration (in seconds)
4. Click **Save**
With DataBrain Caching, cached query results are stored in DataBrain's managed Redis instance. If data residency is a concern, consider using Bring Your Own Cache instead.
**Best for:** Teams with data residency requirements, or who want full control over their caching infrastructure.
Connect your own Redis or AWS Elasticache instance. Cached query results stay in **your** infrastructure — DataBrain never stores them.
**How it works:**
1. Toggle **"Cache Settings"** to enable caching
2. Leave the **"Databrain Caching"** option **disabled**
3. Enter your Redis connection details (host, port, password)
4. Set your desired cache expiration (in seconds)
5. Click **Save** — DataBrain will validate the connection before saving
DataBrain validates your Redis credentials by writing and reading a test key. If validation fails, double-check your host, port, password, and network accessibility.
***
## Configuration Reference
Navigate to **Workspace Settings → Cache Settings** to configure caching.
### Settings
| Setting | Description | Required | Default |
| --------------------------- | -------------------------------------------- | --------- | ------------------ |
| **Cache Settings toggle** | Enable or disable caching for this workspace | Yes | Disabled |
| **Databrain Caching** | Use DataBrain's managed Redis instance | No | Disabled |
| **Host** | Redis/Elasticache endpoint (BYOC only) | BYOC only | — |
| **Port** | Redis port (BYOC only) | BYOC only | `6379` |
| **Access Key / AUTH Token** | Redis password or AUTH token (BYOC only) | BYOC only | — |
| **Cache Expiration** | Time-to-live for cached results, in seconds | Yes | `86400` (24 hours) |
***
## How Caching Works
When caching is enabled, this is the query execution flow:
A query is generated based on the metric definition, applied filters, and row-level security rules.
DataBrain checks the configured Redis instance for a cached result matching the query.
The **cache key** includes:
* Database name
* Datasource ID
* Generated SQL query
* Applied filters
* Workspace ID
This ensures that different tenants, filters, and queries produce separate cache entries.
If a matching cached result exists and has not expired, it is returned immediately — no database query is executed.
If no cache entry exists (or it has expired), DataBrain executes the query against your database. Successful results are cached with the configured TTL for future requests.
### Graceful Degradation
If the Redis connection fails or times out (5-second connection timeout), DataBrain **does not block the query**. The query executes directly against your database and results are returned without caching. Cache errors are logged but never prevent dashboard functionality.
***
## TTL Recommendations
Choose a cache expiration based on your data freshness requirements:
| Use Case | Recommended TTL | Notes |
| ---------------------------- | ---------------------- | ----------------------------------------- |
| **Real-time dashboards** | `60` – `300` (1–5 min) | For data that changes frequently |
| **Hourly reporting** | `3600` (1 hour) | Good balance of freshness and performance |
| **Daily reporting** | `86400` (24 hours) | Default. Best for data updated nightly |
| **Static / historical data** | `604800` (7 days) | For data that rarely changes |
Start with a higher TTL (e.g., 1 hour) and reduce it only if users report stale data. Higher cache hit rates significantly reduce database load.
***
## BYOC Setup Guide
### Prerequisites
* A running Redis 5.0+ or AWS Elasticache (Redis) instance
* Network connectivity from DataBrain's cloud to your Redis instance
* Redis AUTH password (recommended for security)
### Network Requirements
Your Redis instance must be accessible from DataBrain's cloud over the network. DataBrain connects directly to the host and port you provide — there is no SSH tunneling or special proxy for Redis connections.
Never expose Redis on a public endpoint without AUTH enabled. Always use a strong password.
**To allow connectivity:**
* Whitelist DataBrain's IP address in your Redis instance's security group (see [Allow Access to our IP](/guides/datasources/allow-access-to-our-ip) for the current IP)
* Ensure your Redis port (default `6379`) is open for inbound connections from DataBrain's IP
* If your Redis is in a private network that is not reachable from the public internet, contact DataBrain support to discuss connectivity options
**TLS/SSL:** The Redis client currently connects without TLS encryption. If your Redis instance requires encryption in transit, contact DataBrain support to discuss options.
### Step-by-Step Setup
Set up a Redis instance that is reachable from DataBrain's cloud. This could be:
* **Redis Cloud** (publicly accessible by default)
* **Self-managed Redis** on a public-facing server (e.g., EC2 with a public IP)
* **AWS Elasticache** (requires network configuration — contact support if your instance is in a private subnet)
Note the **host**, **port**, and **AUTH password**.
Whitelist DataBrain's IP address in your Redis instance's security group or firewall rules:
* **Inbound rule**: Allow TCP on your Redis port (default `6379`) from DataBrain's IP
* See [Allow Access to our IP](/guides/datasources/allow-access-to-our-ip) for the current IP address
1. Go to **Workspace Settings → Cache Settings**
2. Toggle **Cache Settings** to enabled
3. Leave **Databrain Caching** disabled
4. Enter your **Host** (e.g., `my-redis.example.com`)
5. Enter your **Port** (e.g., `6379`)
6. Enter your **Access Key / AUTH Token**
7. Set **Cache Expiration** in seconds
8. Click **Save**
DataBrain will automatically validate the connection by writing and reading a test key. If the save succeeds, your BYOC cache is active.
Load a dashboard and check that subsequent loads are faster — the response metadata will show `"cached": true` for cache hits.
***
## Cache Invalidation
DataBrain provides several ways to manage cached data:
| Method | Scope | How |
| -------------------------- | ------------------------ | ----------------------------------------------------------------------------- |
| **TTL expiration** | Per key | Automatic — keys expire based on your configured TTL |
| **Reset cache** | Entire workspace | Use the **Reset Cache** option in Workspace Settings to flush all cached data |
| **Pattern-based deletion** | Per datasource/workspace | Automatic when datasource configuration changes |
If you update your underlying data (e.g., a nightly ETL load), you can reset the cache to ensure users see fresh data immediately. Otherwise, the TTL will handle expiration automatically.
***
## Self-Hosted Deployment
For self-hosted DataBrain deployments, Redis is configured via environment variables:
```bash theme={"dark"}
# Redis Configuration
REDIS_HOST=your-redis-host # Required: Redis server hostname
REDIS_PORT=6379 # Required: Redis server port (default: 6379)
REDIS_PASSWORD=your-password # Optional: Redis AUTH password
```
These environment variables configure the DataBrain-managed cache mode. Workspaces that enable "Databrain Caching" will use this Redis instance. Workspaces using BYOC will connect to their own specified Redis instance regardless of these environment variables.
Complete self-hosted deployment guide
***
## Security
| Concern | How it's addressed |
| ---------------------------- | -------------------------------------------------------------------------------------------- |
| **Credential storage** | Your Redis host, port, and AUTH token are stored AES-256 encrypted in DataBrain's PostgreSQL |
| **Data residency (BYOC)** | Cached query results are stored in **your** Redis instance, not DataBrain's infrastructure |
| **Data residency (Managed)** | Cached query results are stored in DataBrain's managed Redis instance |
| **Connection security** | Redis AUTH password is used for authentication |
| **Failure handling** | Cache failures never block queries — DataBrain falls back to direct database execution |
Full security and data residency documentation
***
## Frequently Asked Questions
**DataBrain Caching** uses a Redis instance managed by DataBrain. You don't need to provision or manage any infrastructure — just enable it and set a TTL.
**Bring Your Own Cache (BYOC)** lets you connect your own Redis or Elasticache instance. Cached data stays in your infrastructure, giving you full control over data residency, eviction policies, and scaling.
Only **query results** (JSON format) are cached. Cache keys include the query hash, datasource ID, filters, and workspace ID — ensuring tenant isolation. Dashboard definitions, metric configurations, and user data are never stored in Redis.
DataBrain degrades gracefully. If the Redis connection fails or times out, queries execute directly against your database. Users will experience slightly slower load times (no cache hits) but dashboards will continue to work. Cache errors are logged for monitoring.
Yes. Each workspace has independent cache settings. One workspace can use DataBrain Caching while another uses BYOC with a different Redis instance.
Load a dashboard, then reload it. The second load should be noticeably faster. The API response metadata includes a `"cached"` field that indicates whether results came from cache.
DataBrain uses the `ioredis` client and is compatible with Redis 5.0 and above, including AWS Elasticache (Redis mode) and Redis Cloud.
Yes. Cache keys include the full query (which already has RLS applied) plus filters and workspace ID. Different tenants with different RLS rules will have separate cache entries.
# Configure General Settings
Source: https://docs.usedatabrain.com/guides/onboarding-and-configuration/workspace-settings/general-settings
### Configure General Settings
In the **General** section, you can update key workspace preferences.
#### Edit Workspace Name
Give your workspace a meaningful name that reflects your project or team.
#### Creator Settings
Choose your preferred creation mode:
* **Power Mode**: Enables drag-and-drop functionality or the option to write custom queries.\
Select your data connection type (**Data Source**) and choose the specific Data Source from the dropdown menu.
* **Chat Mode**: Allows users to explore data using keyword-based search. Select your preferred **Datamart**.
#### LLM Settings
Choose the preferred **LLM (Large Language Model)** to be used in Chat Mode and Metric Summary.\
You can also enable **Metric Suggestion**, which uses the LLM to suggest metrics during creation.
#### Theme Settings
Set specific themes for your workspace to personalize its appearance.
#### Delete the Workspace
If needed, you can delete the workspace.
Once configured, click **Save** to apply the changes.
You’ve successfully configured your workspace settings in Databrain!\
Your preferences, creation modes, and themes are now applied — enabling a personalized and efficient workspace experience.
# Email Settings for Scheduled Reports
Source: https://docs.usedatabrain.com/guides/preview-of-dashboards/email-settings-for-scheduled-reports
Configure email settings that appear during scheduled reports
### Access **Email Settings**
* Navigate to the **"Settings"** page, adjacent to the **"Data Studio"** page.
* Go to the **`> Embed Settings`** section on the left and click on the **"Email Settings"** tab.
* Enable the toggle switch **"Enabled"** and fill in your SMTP credentials.
* Finally, click the **"Authenticate"** button.
# Scheduled Reports for End User
Source: https://docs.usedatabrain.com/guides/preview-of-dashboards/scheduled-reports-for-end-user
This guide provides a straightforward process for setting up scheduled email reports, ensuring that users can easily automate their reporting needs
Please refer the below guide if email settings is not configured.
Please refer this guide if email settings are not configured.
### 1. Generate the preview link:
* Navigate to your dashboard and click on **"Share"** icon.
* Turn on the **"Schedule Email Reports"** toggle and click on the **"Generate Link"** button
* Click on **"Preview"** button.
### 2. The dashboard will be displayed and click on **"Scheduled Reports"**
### 3. Create Schedule Email Reports:
* Enter the required details and click on **"Save"**
* Finally, the schedule email reports will be shared to your email ID.
# Add Data Source → Build Dashboards & Metrics
Source: https://docs.usedatabrain.com/guides/quick-start/add-a-data-source
This tutorial guides you through the initial Databrain setup workflow — connecting your database, configuring tenants, and creating dashboards and metrics to visualize your data.
Before starting, ensure your database and tenancy configuration are ready.
## Before you begin
* If your database is hosted privately, [whitelist Databrain's IP](https://docs.usedatabrain.com/guides/datasources/allow-access-to-our-ip) so Databrain can connect securely.
* Decide your tenancy configuration: [Choosing the Right Tenancy Model for Your Data](https://docs.usedatabrain.com/guides/onboarding-and-configuration/choosing-the-right-tenancy-model-for-your-data).
1. Sign in to your Databrain workspace.
2. Go to **Data Studio → Data Sources → + Data Source**.
3. Choose your database type (Postgres, MySQL, BigQuery, Snowflake, Redshift, etc.).
4. Enter connection details:
* Host / IP
* Port
* Database name
* Schema (if applicable)
* Username & password or key-based credentials
5. (Optional) Configure SSL options if your DB requires encrypted connections.
6. Click **Authenticate** to confirm the process.
Reference: [**Add a Data Source**](https://docs.usedatabrain.com/guides/onboarding-and-configuration/add-a-data-source)
1. Choose your tenancy level:
* **Database**: Use this when each client’s data is stored at the database level (each client has its own database).
* **Table**: Use this when client data is stored as rows identified by an ID column in a single table.\
Select the table housing your client or organization data and choose the Primary Key column (e.g., `id`, `user_id`, `org_id`).
2. Create a workspace linked with the connected data source.
Reference: [**Configure Tenants**](https://docs.usedatabrain.com/guides/datasources/configure-tenants)
1. Click **+ Dashboard**.
2. Enter a suitable name (e.g., *Revenue Overview*) and click **Create**.
3. Open the created dashboard and click **+ Metric**.
4. Drag and drop columns into dimensions and measures or write a SQL query.\
Adjust chart types and settings, then click **Save to Dashboard**.
5. Configure additional details and click **Save**.
References: [**Create a Dashboard**](https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-dashboard), [**Create a Metric**](https://docs.usedatabrain.com/guides/onboarding-and-configuration/create-a-metric)
You’ve now completed the initial Databrain setup - your workspace is connected, tenants are configured, and your first dashboard and metrics are created!
# SigNoz Integration
Source: https://docs.usedatabrain.com/guides/signoz-integration
Send OpenTelemetry traces, metrics, and logs from Databrain to SigNoz (open-source observability)
# Integrating Databrain with SigNoz
This guide explains how to send OpenTelemetry traces, metrics, and logs from your self-hosted Databrain instance to SigNoz, an open-source observability platform.
## Why SigNoz?
SigNoz is a great choice for self-hosted observability:
* **100% Open Source**: No vendor lock-in
* **OpenTelemetry Native**: Built specifically for OTel
* **All-in-One**: Traces, metrics, and logs in a single platform
* **Cost-Effective**: Self-hosted means no per-event pricing
* **Easy to Deploy**: Docker Compose or Kubernetes deployment
## Prerequisites
* Databrain self-hosted version with OpenTelemetry support
* Docker and Docker Compose (for SigNoz installation)
* 4GB+ RAM for SigNoz (8GB recommended for production)
## Option 1: SigNoz Cloud (Easiest)
If you prefer a managed solution, use SigNoz Cloud:
### 1. Sign Up for SigNoz Cloud
1. Go to [https://signoz.io/teams/](https://signoz.io/teams/)
2. Create a free account
3. Note your **ingestion endpoint** and **ingestion key**
### 2. Configure Databrain
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# SigNoz Cloud endpoint (adjust for your region)
OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443
# SigNoz ingestion key
OTEL_EXPORTER_OTLP_HEADERS=signoz-access-token=YOUR_INGESTION_KEY
# Service name
OTEL_SERVICE_NAME=databrain-api
# Optional: Enable debug logging
LOG_LEVEL=info
```
### 3. Docker Compose Configuration
```yaml theme={"dark"}
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "https://ingest.{region}.signoz.cloud:443"
OTEL_SERVICE_NAME: "databrain-api"
OTEL_EXPORTER_OTLP_HEADERS: "signoz-access-token=${SIGNOZ_INGESTION_KEY}"
LOG_LEVEL: "info"
```
## Option 2: Self-Hosted SigNoz (Recommended for Production)
### 1. Install SigNoz
#### Using Docker Compose (Quick Start)
```bash theme={"dark"}
# Clone SigNoz repository
git clone -b main https://github.com/SigNoz/signoz.git
cd signoz/deploy/
# Start SigNoz
docker compose -f docker/clickhouse-setup/docker-compose.yaml up -d
```
This starts:
* **SigNoz UI**: [http://localhost:3301](http://localhost:3301)
* **OTLP Receiver (gRPC)**: localhost:4317
* **OTLP Receiver (HTTP)**: localhost:4318
* **ClickHouse**: For data storage
* **Query Service**: For querying data
#### Using Docker Compose (Custom Network)
If Databrain is on the same Docker network:
```yaml theme={"dark"}
# signoz-docker-compose.yaml
version: "3.8"
networks:
databrain:
external: true
signoz:
name: signoz
services:
clickhouse:
image: clickhouse/clickhouse-server:23.7.3-alpine
container_name: signoz-clickhouse
volumes:
- ./clickhouse-config.xml:/etc/clickhouse-server/config.d/config.xml
- ./clickhouse-users.xml:/etc/clickhouse-server/users.d/users.xml
- signoz-data:/var/lib/clickhouse/
networks:
- signoz
restart: on-failure
otel-collector:
image: signoz/signoz-otel-collector:0.88.11
container_name: signoz-otel-collector
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
networks:
- signoz
- databrain
depends_on:
- clickhouse
restart: on-failure
query-service:
image: signoz/query-service:0.38.0
container_name: signoz-query-service
command: ["-config=/root/config/prometheus.yml"]
volumes:
- ./prometheus.yml:/root/config/prometheus.yml
environment:
- ClickHouseUrl=tcp://clickhouse:9000
networks:
- signoz
depends_on:
- clickhouse
restart: on-failure
frontend:
image: signoz/frontend:0.38.0
container_name: signoz-frontend
ports:
- "3301:3301"
environment:
- FRONTEND_API_ENDPOINT=http://query-service:8080
networks:
- signoz
depends_on:
- query-service
restart: on-failure
volumes:
signoz-data:
```
### 2. Configure Databrain for Self-Hosted SigNoz
#### Same Docker Network
```yaml theme={"dark"}
# docker-compose.yml
services:
databrainbackend:
environment:
OTEL_ENABLED: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://signoz-otel-collector:4318"
OTEL_SERVICE_NAME: "databrain-api"
LOG_LEVEL: "info"
networks:
- databrain
- signoz
networks:
databrain:
signoz:
external: true
```
#### Separate Hosts
If SigNoz is on a different host:
```bash theme={"dark"}
# Enable OpenTelemetry
OTEL_ENABLED=true
# SigNoz OTLP endpoint (adjust host)
OTEL_EXPORTER_OTLP_ENDPOINT=http://signoz-host:4318
# Service name
OTEL_SERVICE_NAME=databrain-api
```
### 3. Kubernetes Deployment
#### Deploy SigNoz on Kubernetes
```bash theme={"dark"}
# Add SigNoz Helm repo
helm repo add signoz https://charts.signoz.io
helm repo update
# Create namespace
kubectl create namespace signoz
# Install SigNoz
helm install signoz signoz/signoz -n signoz \
--set clickhouse.persistence.size=50Gi \
--set frontend.ingress.enabled=true \
--set frontend.ingress.hosts[0].host=signoz.your-domain.com
```
#### Configure Databrain
```yaml theme={"dark"}
apiVersion: apps/v1
kind: Deployment
metadata:
name: databrain-backend
spec:
template:
spec:
containers:
- name: backend
env:
- name: OTEL_ENABLED
value: "true"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://signoz-otel-collector.signoz.svc.cluster.local:4318"
- name: OTEL_SERVICE_NAME
value: "databrain-api"
- name: LOG_LEVEL
value: "info"
```
## What Gets Sent to SigNoz
| Telemetry Type | Description |
| -------------- | ---------------------------------------------- |
| **Traces** | Full distributed traces with all spans |
| **Metrics** | Request rates, latency histograms, error rates |
| **Logs** | Structured logs with trace correlation |
All three are integrated in SigNoz's unified interface.
## Verification
### 1. Check SigNoz is Running
```bash theme={"dark"}
# Check containers
docker ps | grep signoz
# Check OTLP receiver is listening
curl http://localhost:4318/v1/traces
# Should return 405 Method Not Allowed (endpoint exists but expects POST)
```
### 2. Restart Databrain
```bash theme={"dark"}
docker compose restart databrainbackend
```
### 3. Generate Test Traffic
```bash theme={"dark"}
# Health check
curl https://your-databrain-instance.com/api/health
# Sample request
curl -X POST "https://your-databrain-instance.com/api/v2/metric/execute" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"metricId": "test-123"}'
```
### 4. View in SigNoz UI
1. Open SigNoz: [http://localhost:3301](http://localhost:3301) (or your configured URL)
2. Go to **Services** → You should see `databrain-api`
3. Click on service to see metrics:
* Request rate (requests per second)
* Error rate (%)
* Latency (p50, p90, p95, p99)
* Apdex score
4. Go to **Traces** → Filter by `serviceName=databrain-api`
5. Click on any trace to see the full waterfall view
### 5. Check Logs
1. Go to **Logs** tab
2. Filter: `service_name = databrain-api`
3. Click on any log entry
4. See **Related Traces** section for correlated traces
## SigNoz Features
### 1. Service Dashboard
The service dashboard shows:
* **RED metrics**: Rate, Errors, Duration
* **Apdex score**: User satisfaction metric
* **Operations**: Individual endpoint performance
* **Database calls**: Query performance breakdown
* **External calls**: Downstream service latency
### 2. Traces Explorer
Advanced trace filtering:
```
serviceName = databrain-api
AND duration > 1000ms
AND statusCode >= 500
```
**Available filters**:
* Service name
* Operation name
* HTTP status code
* Duration
* Error status
* Custom tags (userId, metricId, etc.)
### 3. Service Map
Visualize service dependencies:
1. Go to **Service Map**
2. See databrain-api and its dependencies:
* PostgreSQL
* Redis
* Hasura
* Keycloak
* S3
3. Click on connections to see request rates and error rates
### 4. Logs Management
SigNoz provides powerful log querying:
**Query examples**:
```
service_name = databrain-api AND level = error
service_name = databrain-api AND userId = 123
service_name = databrain-api AND duration > 1000
```
**Log to trace correlation**:
* Click on any log → see **Trace** button
* Jump directly to the trace that generated this log
### 5. Alerts
Create alerts in SigNoz:
#### High Error Rate Alert
1. Go to **Alerts** → **New Alert**
2. Alert Type: **Metrics Alert**
3. Metric Query:
```
A: error_count = count(signoz_latency_bucket{service_name="databrain-api", status_code=~"5.."})
B: total_count = count(signoz_latency_bucket{service_name="databrain-api"})
Formula: (A / B) * 100
```
4. Condition: `> 5` (5% error rate)
5. For: `5 minutes`
6. Add notification channel (Slack, email, webhook)
#### High Latency Alert
1. Metric Query:
```
histogram_quantile(0.95,
sum by (le)(rate(signoz_latency_bucket{service_name="databrain-api"}[5m]))
)
```
2. Condition: `> 2000` (2 seconds)
3. For: `5 minutes`
### 6. Dashboards
Create custom dashboards:
1. Go to **Dashboards** → **New Dashboard**
2. Add panels:
**Request Rate Panel**:
```
rate(signoz_calls_total{service_name="databrain-api"}[5m])
```
**Error Rate Panel**:
```
rate(signoz_calls_total{service_name="databrain-api", status_code=~"5.."}[5m])
/
rate(signoz_calls_total{service_name="databrain-api"}[5m])
```
**Latency Distribution Panel**:
```
histogram_quantile(0.50, sum(rate(signoz_latency_bucket[5m])) by (le))
histogram_quantile(0.95, sum(rate(signoz_latency_bucket[5m])) by (le))
histogram_quantile(0.99, sum(rate(signoz_latency_bucket[5m])) by (le))
```
**Database Query Latency**:
```
histogram_quantile(0.95,
sum(rate(signoz_latency_bucket{
service_name="databrain-api",
db_system="postgresql"
}[5m])) by (le)
)
```
## Advanced Configuration
### Sampling
Add sampling to the OTel collector config:
```yaml theme={"dark"}
# otel-collector-config.yaml
processors:
# Tail-based sampling
tail_sampling:
decision_wait: 10s
num_traces: 100
policies:
# Always keep errors
- name: error-policy
type: status_code
status_code:
status_codes: [ERROR]
# Keep slow requests
- name: latency-policy
type: latency
latency:
threshold_ms: 1000
# Sample 10% of normal traffic
- name: probabilistic-policy
type: probabilistic
probabilistic:
sampling_percentage: 10
service:
pipelines:
traces:
receivers: [otlp]
processors: [tail_sampling, batch]
exporters: [clickhouse]
```
### Resource Attributes
Add custom resource attributes:
```yaml theme={"dark"}
processors:
resource:
attributes:
- key: deployment.environment
value: production
action: upsert
- key: cloud.provider
value: aws
action: upsert
- key: cloud.region
value: us-east-1
action: upsert
```
## Troubleshooting
| Issue | Solution |
| ------------------------ | -------------------------------------------------------------- |
| No data in SigNoz | Check OTel collector logs: `docker logs signoz-otel-collector` |
| Cannot connect to SigNoz | Verify networks and firewall rules |
| Missing logs | Ensure Winston is configured with JSON format |
| High disk usage | Adjust ClickHouse retention settings |
| Slow queries | Increase ClickHouse resources or add indexes |
### Debug SigNoz Collector
```bash theme={"dark"}
# Check collector logs
docker logs signoz-otel-collector -f
# Check for OTLP receiver
docker logs signoz-otel-collector | grep "OTLP receiver"
# Should see:
# OTLP receiver started on 0.0.0.0:4317
# OTLP receiver started on 0.0.0.0:4318
```
### Debug Databrain Connection
```bash theme={"dark"}
# Test connectivity from Databrain container
docker exec databrain-backend curl -v http://signoz-otel-collector:4318/v1/traces
```
### Check ClickHouse
```bash theme={"dark"}
# Connect to ClickHouse
docker exec -it signoz-clickhouse clickhouse-client
# Check traces table
SELECT count() FROM signoz_traces.signoz_index_v2;
# Check for recent traces
SELECT timestamp, serviceName, name FROM signoz_traces.signoz_index_v2
ORDER BY timestamp DESC LIMIT 10;
```
## Data Retention
Configure retention in ClickHouse:
```sql theme={"dark"}
-- Connect to ClickHouse
docker exec -it signoz-clickhouse clickhouse-client
-- Set 30-day retention for traces
ALTER TABLE signoz_traces.signoz_index_v2
MODIFY TTL toDateTime(timestamp) + INTERVAL 30 DAY;
-- Set 90-day retention for metrics
ALTER TABLE signoz_metrics.distributed_samples_v2
MODIFY TTL toDateTime(timestamp) + INTERVAL 90 DAY;
```
Or configure in `clickhouse-config.xml`:
```xml theme={"dark"}
1
```
## Performance Tuning
### For High Traffic (>10K requests/minute)
1. **Increase ClickHouse resources**:
```yaml theme={"dark"}
clickhouse:
resources:
limits:
memory: 8Gi
cpu: 4
```
2. **Batch processing**:
```yaml theme={"dark"}
processors:
batch:
timeout: 10s
send_batch_size: 10000
```
3. **Use buffer**:
```yaml theme={"dark"}
processors:
memory_limiter:
limit_mib: 512
spike_limit_mib: 128
check_interval: 5s
```
## Backup and Restore
### Backup ClickHouse Data
```bash theme={"dark"}
# Stop SigNoz
docker compose down
# Backup data directory
tar -czf signoz-backup-$(date +%Y%m%d).tar.gz \
./deploy/docker/clickhouse-setup/data/
# Restart SigNoz
docker compose up -d
```
### Restore from Backup
```bash theme={"dark"}
# Stop SigNoz
docker compose down
# Restore data
tar -xzf signoz-backup-20260203.tar.gz -C ./deploy/docker/clickhouse-setup/
# Restart
docker compose up -d
```
## Upgrading SigNoz
```bash theme={"dark"}
cd signoz/deploy/
# Pull latest images
docker compose -f docker/clickhouse-setup/docker-compose.yaml pull
# Restart with new images
docker compose -f docker/clickhouse-setup/docker-compose.yaml up -d
```
## Community & Support
* **Documentation**: [https://signoz.io/docs/](https://signoz.io/docs/)
* **Slack Community**: [https://signoz.io/slack](https://signoz.io/slack)
* **GitHub**: [https://github.com/SigNoz/signoz](https://github.com/SigNoz/signoz)
* **GitHub Discussions**: [https://github.com/SigNoz/signoz/discussions](https://github.com/SigNoz/signoz/discussions)
For Databrain configuration issues, contact your Databrain support team.
# Creating a theme
Source: https://docs.usedatabrain.com/guides/themeing-and-customization/creating-a-theme
You can create a theme to choose how the Databrain Plugin in your application should look like
1. **Access UI Theming:**
* Click on the **"Settings"** tab near the Data Studio tab.
* In the **"Embed Settings"** section, select **"UI Theming"** from the settings menu tabs and click on **"+ Add New Theme".**
2. **Configure Basic Theme & Dashboard Settings:**
* Enter Theme Name in text field and set a suitable Font Family.
* Choose your desired dashboard and metric background colors.
* Use the **Disable Dashboard Minimap** toggle to hide the dashboard minimap and progress header in the app. The minimap is enabled by default in the app.
3. **Configure Card Settings:**
* Enter card border, card description and card title details.
* Choose relevant colors for the card title and card description.
The metric card title supports a **text color** ("Card Title Text Color") but not its own background color. To change the color behind the title, use **"Metric Card Background Color"** — it applies to the whole card, title included. There is no separate title-background setting; pairing a contrasting card background with a title text color is the supported way to make the title stand out.
4. **Configure Underlying Data Settings :**
* Choose the Color options for the header and content.
5. **Configure Chart Settings :**
* Enter the Font family and choose the color for the Chart title.
* Choose the Font and colour options for Chart tooltip.
**Chart palettes and why palette selection can appear greyed out.** The theme's chart config defines the available palettes (`chart.palettes`, each `{ name, colors }`), which of them are selectable in chart settings (`chart.paletteOptions`, a list of palette names), and the default (`chart.selected`). If `paletteOptions` is empty or lists none of the defined palettes, the palette picker in chart settings shows "Palette Options not yet configured" and cannot be changed — the dashboard-level theme is the source of truth. To unlock palette selection, add the palette names you want selectable to `paletteOptions`. In embedded dashboards the same can be supplied via the `chartPaletteOptions` and `chartColors` component options.
6. **Configure Date Picker :**
* Choose the **Date Picker Format** from the dropdown options (e.g. `MM/DD/YYYY`, `DD-MM-YYYY`, `Mon DD, YYYY`). This controls how dates display in date pickers across the dashboard. In embed code, the same setting is the theme config key `general.datePickerFormat`.
* Finally, click **"Save Theme"** to save your created theme.
7. **View your created theme in the UI Theming page**
You have succesfully created your Dashboard theme in Databrain !
# View the theme in action
Source: https://docs.usedatabrain.com/guides/themeing-and-customization/view-the-theme-in-action
In this article, we will see how to check whether your saved theme is working or not.
## Viewing Saved Theme in Action
Add the Databrain Plugin to your project. I am assuming that you have already installed the plugin in your app. Please refer to this link to know how to install and use it in your project if you haven’t done it yet.
Click here to learn how to install and integrate the Databrain Plugin into your app.
Go to the page where you have added the Databrain Plugin.
And that's how you can see your saved theme in action.
# Building Charts in Databrain
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/building-charts-in-databrain
A guide to creating the right visualization for your data.
**A guide to creating the right visualization for your data**
Welcome! This guide helps you build charts in Databrain quickly and confidently. Whether you're tracking a single number, comparing categories, or building interactive dashboards, you'll find the right approach here with step-by-step instructions, real examples, and visuals for each scenario.
### **How charts work**
Every chart in Databrain is built from two ingredients:
* **Dimensions**: what you group by (dates, regions, categories)
* **Measures**: the numbers you calculate (Count, Sum, Average)
To build any chart:
1. Start with the problem statement\
A good Databrain chart is not chosen by chart name first. Start with the sentence you are trying to answer: Are we on track? What\
changed? Where is the issue? Which segment is different? Which records need action? Once that sentence is clear, the chart type\
usually becomes obvious.
2. Build the metric shape\
Every chart starts with dimensions and measures. Dimensions answer "by what" - by month, region, segment, status, product,\
customer, country. Measures answer "how much" - revenue, count, average duration, conversion rate, spend, margin, or score.
3. Turn the metric into an experience\
The chart is only the first layer. In Databrain, the same metric can become much more useful with Group By, drill down, switch axes,\
chart click action, dashboard filters, metric filters, app filters, forecasting, downloads, and AI Summary. That feature stack is what turns a static visual into a guided analytics workflow.
### **Quick chart picker**
| If you require | Use these Databrain charts | Why |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **One important number** | [Single Value](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/single-value), Gauge V2, Progress Bar V2, Linear Gauge V2 | Use for KPI status, target progress, quota, SLA, utilization, health score, or progress |
| **Compare categories** | Bar (Stack, Horizontal Stack), [Hybrid Bar](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/hybrid-bar) | Use dimensions such as region, product, status, customer tier, or sales rep. |
| **Trend over time** | Line, Area, Stacked Area | Use a date dimension and one or more measures. Add forecasting when the question is forward-looking. |
| **Part of a total** | Pie, Doughnut, Rose, Stacked Area, [Hierarchical Map](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/tree-map) | Use only when the number of categories is small enough for users to read. |
| **Detailed records** | [Table, Horizontal Stack Table](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/table-advanced) | Use when exact rows, values, statuses, links, or downloads matter more than shape. |
| **Cross-tab analysis** | [Pivot Tables:](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/pivot-table) Pivot Table 2, Pivot Table 3 | Use rows, columns, and measures to summarize data across two or more dimensions |
| **Stages and movement** | [Funnel V2, Waterfall V2, Sankey](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/funnel-sankey-waterfall) | Use for conversion stages, cumulative change, source-to-target flows, and process drop-offs. |
| **Distribution and outliers** | Histogram, Boxplot, Scatter, Bubble V1 | Use for spread, skew, clusters, unusual points, and relationship between numeric variables. |
| **Relationships** | [Network](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/network), Sankey | Use source, target, and value columns to show links, affinity, dependencies, or flows |
| **Geography** | [World Map, Indian States, USA Map, USA Map with](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/maps) [Scatter, USA Map with Bar](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/maps) | Use when region names match the chosen map geography. |
| **Task timelines** | [Gantt](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/gantt) | Use start date, end date, task label, and optional status or owner fields. |
### **Standard Databrain build pattern**
1. Create or edit a metric from the dashboard.
2. Add dimensions and measures, or use Custom SQL/Python when the data shape needs preparation.
3. Click the Charts icon and choose the chart type that matches the business question.
4. Open Settings and use appearance and actions to assign axes or roles.
5. Use Appearance to set colors, labels, legends, number format, prefix/suffix, thresholds, and chart-specific styling.
6. Use Actions to enable Group By, drill down, switch axes, click actions, forecasting, sorting, or secure underlying-data behavior where relevant.
7. Save to Dashboard and test the chart with filters, drill paths, and embed/app-filter behavior if it will be customer-facing
### **Requirement-to-chart playbook**
| Requirement | Recommended chart | Data setup | Databrain features to enable |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Executive KPI tile | Single Value | One aggregate measure such as SUM(revenue), COUNT(order\_id), AVG(score). | Metric expression, comparison value, conditional formatting. |
| Progress toward a Target | Gauge V2, Linear Gauge V2, Progress Bar V2 | One measure plus optional min, max, or target columns. | Threshold colors, prefix/suffix formatting, target markers. |
| Compare performance by category | Bar | Dimension = category Measure = revenue, count, margin, or score | Sort, chart labels, switch Y axis, dashboard filter. |
| Many category names or long labels | Horizontal Stack | Use the category as the vertical label and the measure on the horizontal axis. | Right-size labels, sort descending, show top categories. |
| Each bar split by status/channel/segment | Bar Stack or Horizontal Bar Stack | Dimension: month/region/category Measure: count or sum. Group By: status/channel/segment | Group By, dynamic options, legend, dashboard filter. |
| Month-over-Month trend | Line, [Time Series](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/time-series), Area | Date dimension plus one or more measures. | Time grain, dynamic group by, switch Y axis |
| Compare actuals and forecast or two units | Combo or Horizontal Combo | One dimension plus at least two measures, usually bar plus line. | Multi-scale combo for measures with different units. |
| Understand movement from starting value to ending value | Waterfall V2 | Category dimension plus measure representing increase, decrease, or total. | Use for revenue bridge, spend variance, margin movement. |
| Source-to-Target movement | Sankey | Source dimension, target dimension, value measure. | Use for channel journeys, process handoffs, budget movement. |
| Conversion from lead to customer | Funnel V2 | Stage dimension plus measure for count/value at each stage. | Use clear stage order, show conversion/drop-off. |
| Relationships or Affinity | Network | Source, target, and value/strength columns. | Use for entity relationships, co-occurrence, dependencies, supplier-product networks. |
| Hierarchy and contribution together | Hierarchical Map | Dimension hierarchy plus measure. | Use for category/subcategory/product contribution. |
| Share of Total | Doughnut, Pie, Rose | Small number of categories plus one measure. | Avoid too many slices, use bar when exact comparison matters. |
| Row-level Validation or audit view | Table | Dimensions and measures as visible columns. | Download, hide columns, conditional formatting, metric filters. |
| Excel-like Summary | Pivot Table 2 or Pivot Table 3 | Rows, columns, and aggregate measures. | Use for finance, operations, account, and cohort summaries |
| Spot Outliers | Boxplot, Scatter, Bubble V1, Histogram | Numeric fields for distribution, relationship, or size. | Use filters to isolate segment, table to inspect underlying rows. |
| Geographic Performance | World Map, Indian States, USA Map, USA Map with Scatter, USA Map with Bar | Region/country/state dimension plus measure. | Region names must match the selected map geography. |
| Project/Task Timelines | Gantt | Task label, start date, end date, optional owner/status, and measure if needed. | Use filters for owner, project, status, or priority. |
### **Analysis patterns**
Use this section for any analysis requirement instead of a chart name. The goal is to translate the analysis intent into a Databrain build pattern while keeping the positioning clear: Databrain can visualize, filter, drill, summarize, and operationalize the analysis.
| Analysis need | Databrain story | Product-safe implementation guidance | Suggested features |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Outlier detection | Use Time Series, Line, [Trend Analyzer](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/trend-analyzer), Boxplot, Histogram, Scatter, Bubble V1, and Table. The story is: show the trend or distribution, make the unusual point easy to see, then let the user filter, drill, or open the records behind it. | Native pattern: Visual outlier review, AI Summary, filters, and underlying-data inspection | Time Series, [Boxplot](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/boxplot), [Histogram](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/histogram), Scatter, Bubble, Chart Actions, Metric AI Summary, Drill Down |
| Clustering and Segmentation | Use Group By feature for Bar Stack, Horizontal Stack, Scatter, Bubble V1, and dashboard filters. The story is: split the chart by customer segment, cohort, product family, region, risk band, or generated cluster label. | Native pattern: dimensions, Group By, dynamic options, filters | [Group By](https://docs.usedatabrain.com/guides/metric/group-by) |
| What-if / Scenario Analysis | Use Single Value, Combo, Line, Gauge/Progress, and Table. The story is: compare baseline vs selected scenario and show the impact on headline KPI, trend, and detailed drivers. | Native pattern: filters, Dynamic Property, and scenario columns/measures | [Dynamic Property](https://docs.usedatabrain.com/guides/metric/dynamic-property#dynamic-property) |
| Affinity / Graph Analysis | Use Network and Sankey. The story is: show which entities are connected, how strong the relationship is, and where flow, dependency, or co-occurrence is concentrated. | Native pattern: source, target, and value visualization. | [Network](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/network#network-chart), [Sankey](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/funnel-sankey-waterfall#sankey-setup) |
| Geospatial Analysis | Use World Map, Indian States, USA Map, USA Map with Scatter, USA Map with Bar The story is: show where performance, risk, demand, supply, or exceptions are concentrated geographically. | Native pattern: geography dimension plus measure. Keep country/state/region names aligned with the selected map geography and use dashboard filters for territory, segment, or time range | [Map Charts](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/maps#map-charts), [Dashboard](https://docs.usedatabrain.com/guides/filters/dashboard-filter#dashboard-filter) [Filter](https://docs.usedatabrain.com/guides/filters/dashboard-filter#dashboard-filter), [Metric Filter](https://docs.usedatabrain.com/guides/filters/metric-filter) |
| Augmented Analysis | Use AI Summary, Metric Summary, forecasting, drill down, and filters alongside the chart. The story is: help the viewer understand what changed, why it matters, and where to investigate next. | Native pattern: explain, summarize, forecast, and guide exploration from the metric view | [AI Summary](https://docs.usedatabrain.com/guides/metric/ai-summary), [Metric](https://docs.usedatabrain.com/guides/metric/metric-summary#metric-summary) [Summary](https://docs.usedatabrain.com/guides/metric/metric-summary#metric-summary), [Chart Actions](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions#chart-actions), [Forecasting](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions#9-forecasting), [Drill Down](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/drill-down#drill-down) |
### **Interaction features that make charts useful**
| Feature | Use it when |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Group By | When one column contains the breakdown values, such as status or channel, Group By turns those values into chart series. Use it with stacked bars and lines. |
| Drill Down | Use when the dataset has hierarchy: Region > Country > City, Year > Quarter > Month, Category > Product. Databrain applies the clicked value as a filter and re-groups by the next dimension |
| Cross-dashboard Drill Down | Use when a click in one metric should update the rest of the dashboard context. |
| Switch X Axis / Switch Y Axis | Use when end users should compare the same metric by different dimensions or measures without duplicating charts. |
| End user measures and dimensions | Use for self-service exploration where the viewer can change dimensions and measures on a metric card |
| Chart Click Action / Card Click Action | Use when a data point or card should take the user to a detail page, related metric, dashboard, or configured URL |
| Dashboard filters | Use when one control should update multiple charts on the dashboard. |
| Metric filters | Use when a filter is specific to one chart and should not affect the full dashboard. |
| App filters | Use in embedded dashboards when the host app or guest token should pre-scope data for tenant, user, date, region, or role |
| Forecasting | Use on trend-oriented charts when the client wants future periods, expected direction, or forecast comparison. |
| AI Summary | Use when the viewer needs a quick natural-language explanation of a metric in full-screen mode. |
| Downloads and Underlying Data | Use when customers need to export chart data, inspect records, or validate the calculation. |
### **Chart catalog**
#### **KPI Cards**
| Chart | What it is used for | Setup and feature tip |
| ------------------------------------ | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Single Value | Shows one headline KPI such as total revenue, churn rate, or open tickets. | One measure or a dimension that resolves to one value. Add metric expression, comparison, and conditional formatting. |
| Gauge V2 | Shows score, utilization, SLA, capacity, or risk against a range. | One measure, optional dimensions, min/max, thresholds. Prefer V2 for new dashboards. |
| Linear Gauge V2 | Shows progress on a horizontal scale with threshold bands. | One measure plus optional min/max or range configuration. |
| Progress Bar V2 | Shows completion percentage, usage vs limit, quota progress, or onboarding progress. | One measure and optional max/min. Use when a simple horizontal progress story is clearer than a radial gauge. |
| Gauge, Linear Gauge, Progress Bar V1 | Legacy variants that may appear in older workspaces or existing dashboards. | Use V2 variants for new chart work when available. |
#### **Tables**
| Chart | What it is used for | Setup and feature tip |
| ---------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Table | Shows exact rows and values for audit, operations, account lists, and validation. | Dimensions and measures as columns. Add downloads, hidden columns, formatting, and filters. |
| Trend Analyzer | Shows trend-focused metric analysis over time. | Use for time-oriented datasets where the customer needs direction, change, or pattern review. |
| Pivot Table | Legacy pivot-style summary. | Use a pivot variant when rows, columns, and aggregate measures are needed. |
| Pivot Table 2 | Cross-tab summary for business users who expect Excel-like slices. | Requires aggregate measures and one or more dimensions. |
| Pivot Table 3 | More configurable pivot for row/column style summaries. | Use for finance, cohort, account, product, or operational matrix views. |
| Horizontal Stack Table | Table plus compact in-row bar comparison. | Use when the exact value and visual magnitude should appear together. |
#### **Line and Time Series**
| Chart | What it is used for | Setup and feature tip |
| ----------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| Line | Shows trend over ordered categories or dates. | Dimension plus one or more measures. Good for revenue, users, tickets, defects, conversion trend. |
| Time Series | Shows measures over a date/time dimension with time grain control. | Requires a date dimension and measures. Supports daily, weekly, monthly, quarterly, yearly grouping. |
#### **Bar**
| Chart | What it is used for | Setup and feature tip |
| -------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Bar | Compares categories vertically. | Dimension plus measure. Good first choice for ranked category comparison. |
| Bar Stack | Compares total and composition in one vertical bar. | Dimension plus measure, with Group By or multiple measures for segments. |
| Hybrid Bar | Mixes stacked and non-stacked bars in the same view. | Use when part of the comparison needs stacking and another part should remain standalone. |
| Horizontal Bar | Compares many or long category labels. | Same as bar, but easier to read for long labels. |
| Horizontal Bar Stack | Compares composition across many long-label categories. | Use for status by team, training by management level, cases by reason, or customer segment by product. |
| Gantt | Shows task, project, or process timelines. | Needs task labels plus start/end date fields; useful for milestone tracking. |
#### [**Combo**](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/combo-chart)
| Chart | What it is used for | Setup and feature tip |
| ------------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Combo (Multi-Scales) | Combines bars and lines when measures use different units. | Use for revenue and margin percent, volume and price, actual and rate. |
| Horizontal Combo (Multi-Scales) | Horizontal variant for long categories with two measure scales. | Use when category labels need horizontal space. |
| Combo (Single-Scale) | Combines visual forms when measures share one scale. | Use when bars and line belong to the same unit or comparable range. |
| Horizontal Combo (Single-Scale) | Compares actual vs target on one horizontal scale. | Use for target tracking by category. |
#### **Area**
| Chart | What it is used for | Setup and feature tip |
| ------------ | ----------------------------------- | ------------------------------------------------------------------------------ |
| Area | Emphasizes magnitude over time. | Use when the filled shape helps communicate volume, backlog, demand, or usage. |
| Stacked Area | Shows composition change over time. | Use for segment mix, channel mix, product contribution, or usage by plan. |
#### **Pie**
| Chart | What it is used for | Setup and feature tip |
| -------- | ------------------------------------------------------------------ | -------------------------------------------------------------------- |
| Doughnut | Shows share of total with a clean center space. | Use for a small number of categories. |
| Pie | Shows simple part-to-whole distribution. | Use sparingly, choose bar if exact comparison is important. |
| Rose | Shows part-to-whole with stronger visual emphasis on segment size. | Use when the category count is small and relative magnitude matters. |
#### **Distribution**
| Chart | What it is used for | Setup and feature tip |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Histogram | Shows how many records fall into numeric ranges. | Numeric dimension plus measure/count. Use for age bands, spend buckets, order value distribution. |
| BoxPlot | Shows median, quartiles, spread, and outliers. | Needs enough numeric columns/values. Use for outlier and distribution checks. |
| Scatter | Shows relationship between two numeric variables. | X and Y axes as dimensions/measures. Use for correlation and outlier discovery. |
| Bubble | Scatter with a constant bubble-size multiplier. | Use when all points can share the same visual size scale. |
| [Bubble V2](https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/bubble-chart-v2) | Scatter where bubble size is driven by a measure. | Use when X, Y, and size together explain segment value, risk, volume, or priority. |
#### **Funnel and Flow**
| Chart | What it is used for | Setup and feature tip |
| ------------ | ------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Funnel | Legacy funnel for stage drop-off. | Use Funnel V2 for new work when available. |
| Funnel V2 | Shows conversion stages and drop-off. | Stage dimension plus measure. Good for sales, onboarding, claims, approval workflows. |
| Waterfall | Legacy waterfall for cumulative change. | Use Waterfall V2 for new work when available. |
| Waterfall V2 | Explains increases/decreases from start to final value. | Use for variance bridge, P\&L movement, budget vs actual. |
| Sankey | Shows flow from source to target. | Needs source, target, and value. Use for journey, allocation, handoff, or movement analysis. |
| Network | Shows graph-style nodes and links. | Needs source, target, value. Use for relationships, affinity, dependencies, co-occurrence. |
#### **Hierarchical**
| Chart | What it is used for | Setup and feature tip |
| -------- | ---------------------------------------------------- | -------------------------------------------------------------------------- |
| Tree Map | Shows hierarchy and contribution in a compact space. | Dimension plus measure. Use for category/subcategory/product contribution. |
#### **Maps**
| Chart | What it is used for | Setup and feature tip |
| ------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
| Indian States | Shows values by Indian states or territories. | Region dimensions must match Indian map names; measure colors regions. |
| US Map | Shows values by US states. | Use state names matching the map geography. |
| US Map with Scatter | Adds point/scatter overlay to the US map. | Use for event density, store locations, incidents, or demand points. |
| US Map with Bar | Adds bar comparison beside or over the US map context. | Use when geography and ranked values should be read together. |
| World Map | Shows values by country. | Country names must match expected world map names. |
# Chart Actions
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions
Enhance your data visualization and analysis with these powerful chart customization features.
Unlock the full potential of your data visualizations with Databrain's powerful chart actions. From interactive click behaviors and intelligent drill-downs to advanced forecasting and security controls, these features transform static charts into dynamic analytical tools. This guide walks you through essential chart actions that will help you create more engaging, interactive, and secure data experiences.
1. **Access Chart Actions**:
* Navigate to your metric card.
* Click on the **“Settings”** icon in the top-right corner of the chart area.
* Head to the **“Actions”** tab to begin customizing.
2. **Card Click Actions**:
* Click on the card in your dashboard to redirect to a specific page. Toggle to activate or deactivate.
* **Redirect Type**: Define the type of redirection.
* **Identifier Type**: Choose the identifier for redirection.
* **Destination Base URL**: Specify the URL to direct users.
For more details, kindly refer the below link
This card links to the full documentation on configuring card click actions in your dashboard.
### 3. **Chart Click Actions**
* Enable the toggle to set up actions when you click on the chart.
* **Redirect Type**: Choose how you want to redirect.
* **Value Column**: Select the data column for redirection.
* **Destination Base URL**: Enter the URL for redirection.
For more details, kindly refer to the link below:
Learn how to configure redirection logic when clicking on chart elements including internal route types, value column mapping, and dynamic URL targets.
### 3. **Chart Click Actions with Metric**
* Specify the Metric name to which Chart should be redirected.
### 4. **Group X-Axis**
Enable grouping to group your data along the x-axis to streamline visualization.
#### Use Case:
Let us take a combo chart with dual scales showing quantity sold (purple bars) and profit (blue line) by store name and client name.
When you toggle on **Group X-Axis**:
* The detailed view automatically consolidates into four main store name groups
* Both quantity sold and profit values are aggregated within each group
* The result is a clearer visualization showing consolidated performance by store
### 5. **Sort on Metric Card**
Sort the data directly on the metric card for better insights.
* Turn on the **Sort on Metric Card** Toggle and save the metric to Dashboard.
* Right Click on the chart to sort the data in either ascending or descending order.
### 6. **Switch X axis, Switch Y axis**
You can add Metric Filters for each card just like "Dashboard Filters". For an in-depth guide on adding metric filters, refer to the below link.
Learn how to toggle between axis dimensions to change your chart's view dynamically.
### 7. **End user measures & dimensions**
To configure dimensions and measures for charts and adjust them as needed, enhancing interactive data exploration capabilities.
**Use Case:**
Let us take a line chart with multiple metrics – quantity sold, unit price, and profit across stores.
When you toggle ON **"End user measures & dimensions"** and select:
* **Dimension**: store name
* **Measure**: quantity sold
The chart immediately simplifies to show only quantity sold across stores, making it easier to analyze this specific metric.
### 8. **Drill Down**
* For charts with multiple dimensions, toggle the **Drill down** option.
* **Cross Dashboard Drill-down**: Adjust the entire dashboard based on your selected dimensions.
For more details, kindly refer the below links:
Learn how to enable and use drill-down functionality on metric cards.
Configure and apply cross-filters across dashboards using drill-down context.
### 9. **Forecasting**
Enable or disable forecasting to predict future trends.
**Use Case:**\
Let us take a line chart showing quantity over time (2022–2024). When you toggle ON **"Forecast"** and configure:
* **Time Grain**: Choose the relevant time intervals
* **ARIMA Model Options**: Choose from linear, constant, or constant + linear
* **Prophet Model Options**: Select linear or flat trends
* **Adjust Hyperparameters**: Fine-tune your forecasting models
### 10. **Hide Coloumns Using Custom Underlying Data Dropdown or Security Actions Dropdown**
* **Hide Columns by SQL Query**: Write the corresponding SQL query to hide required columns from Underlying Data.
* **Hide Columns**: Conceal specific columns from view.
* **Hide Columns from CSV data**: Prevent certain columns from being included in CSV exports.
These options may vary depending on the **"Chart Type"** chosen. Some options may not be available for certain chart types.
**By tailoring these chart actions, you can ensure a customized and secure data visualization experience in Databrain.**
### 11. **Alerts & Signals**
For Single Value Cards, you can configure and set alerts to trigger notifications when data exceeds or falls below a specified threshold.
You’ve successfully explored all major Chart Actions!\
Your dashboards can now deliver richer interactivity, smarter navigation, better forecasting, and secure data handling for every user.
# Card Click Action
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/card-click-action
This guide offers a process for configuring card click actions in a dashboard. By following these steps, you can set up and utilize the card click action to navigate users to the specified routes.
### 1. **Access & Configure Card Click Action**
* Navigate to the **"Appearance and Actions"** section and toggle **"Card Click Action"**.
* **Re-Direct Type**: Specify the route for navigation: external or internal.
* **Identifier Type**: Choose the identifier for redirection.
* **Destination base url**: Use variable values for URL parameters.
### 2. **Save metric to the Dashboard**
### 3. **Generate Preview link and access the dashboard**
-Click on the **Share Button** near the dashboard settings icon\
-Configure the access control settings and, click on **Generate Link** and click on **"View Demo"** button.
### 4. **Card Click Action in Dashboard**
Clicking on the title of the card will lead you to the specified URL.
You’ve successfully enabled Card Click Action.\
Your dashboard cards can now redirect users seamlessly to the destinations you configure.
# Chart Click Action
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/chart-click-action
This guide provides an approach to configuring interactive chart click. The elements or data points of the chart are now clickable, and the action will lead to the route configured by you.
### 1. **Access & Confifgure Chart Click Action**
* Navigate to the **"Appearance and Actions"** section and toggle **"Chart Click Action"**.
* **Re-Direct Type**: Specify the route for navigation: external or internal
* **Value Column**: Specify the column
* **Destination base URL**: Use variable values for URL parameters.
### 2. **Save metric to the Dashboard**
### 3. **Chart Click Action in Dashboard**
Clicking on the bar of any contract status will take you to the specified URL.
**By following these steps, you can set up and utilize the chart click action to navigate users to the specified routes upon interaction with the chart.**
You’ve successfully configured Chart Click Action!\
Your charts are now interactive, enabling seamless navigation and richer user experiences directly from visual elements.
# Chart Click Action with metric
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/chart-click-action-with-metric
This guide offers a straightforward approach to enhancing your data visualization experience by enabling and configuring chart click actions with metrics.
### 1. **Enable & Configure Chart Click Actions with Metric**
* Click on the **Settings** icon and navigate to the **Actions** section.
* Then, toggle on the **Chart Click Actions with Metric** option.
* Select the metric you want to drill down into from the current metric and save the metric to your dashboard.
### 2. **Save Metric to Dashbaord**
### 3. **View the Drill-Down Action**
Once configured, clicking on a chart will drill down into the selected metric, displaying a more detailed view.
You’ve successfully enabled Chart Click Action with Metric!\
Your charts can now drill directly into deeper insights, creating a seamless and interactive analytical flow.
# Cross Dashboard Drill Down
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/cross-dashboard-drill-down
Enable cross-dashboard drill-down to filter all metrics on a dashboard based on a drilled dimension, providing interconnected analysis across your entire dashboard.
## What is Cross Dashboard Drill Down?
Regular drill-down only affects the single metric you click on. **Cross Dashboard Drill Down** takes it further — when you click a data point, the selected dimension value is applied as a **filter across all other metrics** on the same dashboard.
For example, if you click "West" on a revenue-by-region bar chart, every other metric on the dashboard (customer count, order trends, product breakdown) automatically filters to show only data for the "West" region.
This is useful for:
* **Multi-metric correlation analysis** — see how a dimension selection impacts all KPIs simultaneously
* **Interactive executive dashboards** — let stakeholders click once and see the full picture
* **Customer-facing dashboards** — provide self-service exploration without building separate filtered views
***
## How It Works
When Cross Dashboard Drill Down is enabled on a metric:
1. You click a data point (e.g., a bar segment for "West")
2. The system extracts the drilled dimension and its value (e.g., `region = 'West'`)
3. This value is applied as a **row-level security (RLS) filter condition** to all other metrics on the dashboard
4. All metrics re-query their data with the additional filter applied
5. The entire dashboard updates to reflect the selected dimension value
Cross-dashboard drill-down filters work alongside existing dashboard filters. Both are applied simultaneously — the drill filter does not replace your dashboard filters, it adds to them.
***
## Setting Up Cross Dashboard Drill Down
### 1. Activate Cross Dashboard Drill Down
On the metric page, click the **"Settings"** icon, navigate to the **"Actions"** tab, and enable the **"Drill down"** toggle. Then activate **"Cross Dashboard Drill Down"** beneath it.
### 2. View Changes in the Dashboard
Click on a segment of the chart where drill down is enabled. All other metrics on the dashboard will update to reflect the selected value.
### 3. Clear the Cross-Dashboard Filter
Click on the **same dimension** in the drilled-down chart to revert all changes and remove the cross-dashboard filter.
***
## Which Metrics Are Affected?
When you trigger a cross-dashboard drill, the filter is applied to **all metrics on the same dashboard**. The drilled value is passed as an additional filter condition to every metric's query.
* Metrics whose underlying data **includes the drilled column** will filter their results accordingly.
* Metrics whose queries **do not reference that column** may show no change or may return an error depending on the SQL generated. For best results, ensure metrics on the same dashboard share common dimensions when using cross-dashboard drill.
* The filter uses the column name from the drilled metric, so consistent naming across metrics improves reliability.
***
## Cross Dashboard vs. Regular Drill Down
| Behavior | Regular Drill Down | Cross Dashboard Drill Down |
| --------------- | ------------------------- | ------------------------------------------- |
| Scope | Single metric only | Entire dashboard |
| Other metrics | Unaffected | Filtered by drilled value |
| Use case | Deep-dive into one metric | Correlated analysis across metrics |
| Clearing | Breadcrumb navigation | Click the drilled dimension again |
| Can be combined | Yes — enable both | Yes — cross-dashboard adds to regular drill |
You can enable both regular drill-down and cross-dashboard drill-down on the same metric. The cross-dashboard filter applies to other metrics while the originating metric drills into its own hierarchy.
***
## Troubleshooting
**Cause:** Cross Dashboard Drill Down is not enabled, or other metrics don't share the drilled column.
**Fix:**
* Verify **Cross Dashboard Drill Down** is enabled in the originating metric's **Settings > Actions** tab.
* Check that other metrics on the dashboard have the same dimension column (by name or alias) as the drilled value.
**Cause:** Both dashboard filters and the cross-dashboard drill filter are applied simultaneously.
**Fix:**
* This is expected behavior — both filters are additive. If the dashboard filter already restricts to a different value, the combined filter may return no data.
* Clear either the dashboard filter or the cross-dashboard drill to see results.
**Fix:** Click on the **same dimension value** in the originating chart (the one where you first drilled) to clear the cross-dashboard filter and restore all metrics.
You've successfully enabled Cross Dashboard Drill Down.
Your dashboard now responds dynamically to drilled dimensions, giving users deeper, interconnected analysis across views.
# Drill Down
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-actions/drill-down
Explore detailed insights within your charts by drilling down into specific dimensions for a more granular analysis.
## What is Drill Down?
Drill Down lets users interact with data visualizations dynamically. By clicking a specific data point (e.g., a bar in a bar chart), users can expand and analyze the underlying or related dimensions. It moves from aggregated data to detailed views — for example, from total revenue by region to revenue by country or city.
When you click a data point, the system adds a **WHERE filter** for the clicked value and **re-groups** by the next dimension in the hierarchy. Each level triggers a new database query, so drill-down is always working with live, accurate data.
***
## When to Use Drill Down
Drill Down is ideal for datasets with hierarchical or multi-level structures, such as:
* **Geographical data** — Region > Country > City
* **Time-series data** — Year > Quarter > Month
* **Organizational structures** — Department > Team > Employee
* **Product categories** — Category > Subcategory > Product
***
## Requirements
To enable and use the Drill Down feature, ensure:
1. **Data Structure**: The dataset must include hierarchical relationships or dimensions that can be broken down into subcategories.
2. **Visualization Type**: Must be a [supported chart type](#supported-chart-types) (see list below).
3. **Dimensions and Measures**: The metric must have **at least two dimensions** and **at least one aggregate measure** (e.g., SUM, COUNT, AVG).
***
## Setting Up Drill Down
### 1. Enable Drill Down
On the metric page, click the **"Settings"** icon, go to the **"Actions"** tab, and turn on the **"Drill down"** toggle.
### 2. Configure the Data Layer
Drag and drop the dimensions you want to use for drill-down, **in order**. The order defines the drill hierarchy: the first dimension is the top level, the second is the first drill, and so on.
### 3. Configure Drill Levels
Set up all drill-down levels and define the chart settings associated with each level.
With **Drill-Down 2.0**, each level can have its own:
* **Chart type** — switch from a bar chart at level 1 to a line chart at level 2 to a table at level 3
* **Dimensions and measures** — customize which columns appear at each level
* **Filters** — apply level-specific filters to narrow the data further
This lets you build rich, multi-perspective analytical paths rather than a single rigid hierarchy.
### 4. Save to Dashboard
After configuring the drill-down, save the chart to your dashboard.
### 5. Use Drill Down in Your Chart
* **Drill down**: Click on any data point (e.g., a bar or pie slice) to drill into the next level.
* **Drill back**: Click the drilled dimension label or use the breadcrumb navigation to go back one or more levels.
* For example, drilling on Store State: "Oregon" shows its cities, and drilling on Store City: "East Kristin" shows product categories.
***
## Common Drill-Down Patterns
### Geographic Hierarchy
| Level | Dimension | Suggested Chart Type |
| ----- | --------- | --------------------------------------------------------- |
| 1 | Region | Bar chart (overview of regions) |
| 2 | Country | Bar chart or table (countries within the selected region) |
| 3 | City | Pie or doughnut (city-level breakdown) |
### Time-Based Hierarchy
| Level | Dimension | Suggested Chart Type |
| ----- | --------- | ------------------------------------ |
| 1 | Year | Line chart (trend over years) |
| 2 | Quarter | Bar chart (quarterly breakdown) |
| 3 | Month | Area chart or table (monthly detail) |
### Product Hierarchy
| Level | Dimension | Suggested Chart Type |
| ----- | ----------- | --------------------------------------------- |
| 1 | Category | Bar chart (top categories) |
| 2 | Subcategory | Stacked bar (subcategories within a category) |
| 3 | Product | Table (individual products) |
***
## Custom SQL Metrics and Drill Down
Drill-down works the same way for custom SQL metrics. The key requirement is that **the columns you use in the drill hierarchy must exist in your custom SQL result set** — by alias or column name.
If a drill level does not appear or the drill fails:
* Verify that the columns referenced in your drill levels are included in your SQL `SELECT` clause.
* Check that column aliases match the dimension names configured in the drill hierarchy.
* Ensure the query returns enough data for the hierarchy to be meaningful.
**Example:**
```sql theme={"dark"}
SELECT
region,
country,
city,
SUM(revenue) AS total_revenue
FROM sales
GROUP BY region, country, city
```
With this query, you can set up a 3-level drill: Region > Country > City with `total_revenue` as the measure.
***
## Supported Chart Types
* Table chart
* Line chart
* Step chart
* Bar & Bar Stack Chart (horizontal & vertical)
* Combo Single-scale and Multi-scales (horizontal & vertical)
* Area Charts (Area, Stacked Area)
* Pie/Doughnut/Rose charts
* Histogram
* Scatter plot
* Bubble chart
* Waterfall chart (including Waterfall V2)
* Network chart
* Tree map
* Bullet chart
Drill-down is **not** available for: Boxplot, Funnel, Gauge, Geo maps, Horizontal Stack Table, Pivot, Sankey, Single Value, and Time series. If you don't see the option, switch to one of the supported chart types and ensure you have at least two dimensions.
***
## Troubleshooting
**Cause:** The chart type is not supported, or the metric does not have enough dimensions.
**Fix:**
* Switch to a [supported chart type](#supported-chart-types).
* Ensure the metric has **at least two dimensions** and **at least one measure** (aggregate).
**Cause:** Drill down is not enabled or the data layer is not configured.
**Fix:**
* Confirm **Drill down** is toggled on in **Settings > Actions**.
* Check the **Data Layer** has at least two dimensions in the correct order.
* Save the metric to the dashboard after configuring drill-down.
**Cause:** Dimensions are in the wrong order in the data layer.
**Fix:** Reorder dimensions in the **Data Layer**: the first dimension is the top level (broadest), the next is the first drill (more detail), and so on.
**Cause:** The drill hierarchy references columns that don't exist in the SQL result.
**Fix:**
* Verify that all hierarchy columns appear in your SQL `SELECT` clause (by name or alias).
* Check that the aliases match exactly what is configured in the drill levels.
* Run the query standalone to confirm it returns the expected columns.
**Cause:** Table drill-down removes the GROUP BY and shows individual rows matching the drilled value.
**Fix:**
* This is expected behavior — table drill shows raw detail rows.
* For large datasets, consider adding filters at the drill level to limit results, or use a non-table chart type for drill levels that may return many rows.
**Cause:** Cross Dashboard Drill Down is not enabled, or other metrics don't share the drilled dimension.
**Fix:**
* Ensure **Cross Dashboard Drill Down** is enabled in the **Actions** tab.
* The drilled filter is applied to all metrics on the dashboard. For best results, ensure other metrics include the same dimension column as the drilled value.
* See [Cross Dashboard Drill Down](/guides/visualizations-actions-and-appearance/chart-actions/cross-dashboard-drill-down) for full details.
***
## How Drill-Down Queries Work
Understanding what happens behind the scenes can help you design better drill-down experiences:
1. **Level 0 (initial view)**: Your metric runs its normal query — e.g., `SELECT region, SUM(revenue) FROM sales GROUP BY region`.
2. **Level 1 (first drill)**: You click "West". The system generates a new query that adds `WHERE region = 'West'` and changes GROUP BY to the next dimension — e.g., `SELECT country, SUM(revenue) FROM sales WHERE region = 'West' GROUP BY country`.
3. **Level 2 (second drill)**: You click "USA". Another query adds the additional filter — e.g., `WHERE region = 'West' AND country = 'USA'` and groups by the next dimension (e.g., `city`).
Each level builds on the previous filters, creating a progressively narrower and more detailed view of the data.
You've successfully enabled Drill Down.
Your charts can now expand into deeper layers of data, helping users explore insights with precision and clarity.
# Chart Appearance
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-appearance
Personalize your metric charts with an array of appearance settings for clarity and visual appeal.
In Databrain, charts are highly customizable and extensible - you can control the appearance, format the labels, manage click behavior and drilldowns, and much more. This guide walks you through the key customization options to help you create professional and effective data visualizations.
## Access Chart Appearance
* Navigate to your metric card, click the **"Appearance & Actions"** icon, and select the **"Appearance"** tab.
### 1. Horizontal Axis Customizations
* **Toggles**: Axis Line, Splitlines, Axis Labels, Truncate Label.
* **Set Values**: Label Rotation, Custom Rotation, Truncate Label Value, Distance between name and labels.
* **Adjust**: Font properties and color.
**X-axis tick spacing is not configurable.** The horizontal-axis options control label appearance (rotation, fonts, visibility) — there is no setting for the numeric interval between ticks (e.g. "every 10 units"). If you need evenly spaced buckets, pre-bucket the data in SQL and use the bucket column as your x-axis, for example: `SELECT FLOOR(value/10)*10 AS bucket, COUNT(*) FROM t GROUP BY 1`.
### 2. Vertical Axis Customizations
* **Toggles**: Axis Line, Splitlines, Axis Labels.
* **Set Values**: Distance between name and labels.
* **Adjust**: Axis Position and font properties.
### 3. Chart Legend
**Customize**: Display, appearance, position, truncation, and shape.
**Use Case**:
Let us take a combo multi-scales chart showing Revenue (purple bars) and YoY Growth (blue line).\
When you customize the Chart Legend, you can configure:
* **Position**: Top-left, center, right; Middle-left, center, right; Bottom-left, center, right
* **Orientation**: Horizontal (side by side) or Vertical (stacked)
* **Legend Shape**: Square, Diamond, Triangle, Circle, Line
* **Set**: the Font, Font size, and Label Color and also truncate the size of label
The legend now appears exactly how and where you want it, making the chart clearer and more professional.
### 4. Chart Margin
Define margins for all four sides of the chart.
### 5. Chart Label
**Position:** Determine where value labels appear on the chart.
**Use Case:**\
Consider a comparative bar chart displaying Concluded and Starts counts across various locations. With the Chart Label setting, you can choose exactly where the value labels appear—inside the bar, above it, centered, or aligned left or right.
### 6. Chart Tooltip
**Adjust:** Font and color for Header, Label, and Value.
**Use Case:**\
When you hover over any bar, the Chart Tooltip provides detailed information. You can further customize tooltip fonts and colors.
### 7. **Chart Colors**
**Modify:** Chart colors, gradients, and background gradients.
### 8. Chart Title & Description
**Add:** Titles and descriptions, and adjust their positions.
### 9. Formatting
**Set:** Number formatting, and prefix or suffix.
### 10. Features
Options vary based on chart type.
Specific chart types offer unique customizations.
> **Note:** Options may vary based on the **"Chart Type"** chosen.
For chart-specific appearance options, refer to the link below:
Explore appearance settings unique to each chart type such as bar, line, area, and combo charts.
You’ve successfully configured chart appearance.\
Your visualizations now follow a consistent, professional style with clearer labels, cleaner legends, and improved readability.
# Chart-Specific Appearance Options
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-appearance/chart-specific-appearance-options
This guide presents appearance options for similar charts and key insights into customizing common chart types, improving data presentation and clarity.
For how to set up each chart type (data requirements, axis assignment), see [Chart Setup Overview](/guides/visualizations-actions-and-appearance/chart-setup/overview).
## 1. **Bar Chart Styling**
*Applies to: Bar Charts, Stacked Bar Charts, Combo Charts (Single-Scale), Horizontal Bar Charts, Horizontal Combo Charts, and Horizontal Stacked Bar Charts*
### • Purpose and Use Case
Bar charts are ideal for comparing discrete categories, with vertical bars enabling clear magnitude comparisons across business units.
### • Key Style Parameters
* **Width**: Controls spacing between bars to optimize data visibility and category comparison
* **Top Radius**: Adds modern, soft edges for professional presentation
* **Bottom Radius**: Provides visual stability while harmonizing with top radius
## 2. **Table Chart UI Styling**
### • Essential Design Elements
* **Headers**: Clean black text on white background
* **Category Display**: Categories presented as visual badges
* **Number Formatting**: Right-aligned sales figures
* **Interactive Features**: Medium spacing with responsive hover effects
### • Business Benefits
* Facilitates quick executive review
* Enables efficient sales comparisons
* Maintains professional appearance
* Provides immediate access to insights
## 3. **Circular Chart Customization**
*Applies to Pie Charts and Rose Charts*
### **Chart 1: Pie Chart Options**
#### **Interaction Modes:**
* **Single**: Expands one sector at a time on click
* **Multiple**: Expands multiple sectors sequentially
* **Series**: Expands all sectors together
* **Offset**: Adjusts expansion distance in pixels
### Chart 2: **Rose Chart Options**
#### *Chart Types:*
* **Radius Mode**\
▪ Highlights absolute value differences\
▪ Ideal for category magnitude comparison
* **Area Mode**\
▪ Displays proportional relationships\
▪ Useful for market share analysis
#### *Interaction Settings:*
* Supports **Single**, **Multiple**, and **Series** modes
* Adjustable offset distance
You’ve successfully reviewed chart-specific appearance options.\
Your visualizations now follow consistent styling across bar charts, tables, and circular charts for clearer, more professional insights.
**Related:** [Axis Charts setup](/guides/visualizations-actions-and-appearance/chart-setup/axis-charts) | [Circular Charts setup](/guides/visualizations-actions-and-appearance/chart-setup/circular-charts) | [Table setup](/guides/visualizations-actions-and-appearance/chart-setup/table-advanced)
# Axis Charts (Line, Bar, Stack, Row, Area, Stepped)
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/axis-charts
Set up Line, Bar, Stack, Row, Area, and Stepped charts with dimensions and measures.
Axis charts share the same setup: a **horizontal axis** (X-axis), a **vertical axis** (Y-axis), and optional **Switch X Axis** / **Switch Y Axis** to change which columns are used.
## Chart Types
| Chart | Use case |
| ---------------- | ----------------------------------------------- |
| **Line** | Trends over time or categories |
| **Stepped** | Step-style line (e.g., cumulative values) |
| **Bar** | Vertical bars; compare categories |
| **Stack** | Stacked vertical bars; compare parts of a whole |
| **Row** | Horizontal bars; many categories or long labels |
| **Area** | Filled area under a line |
| **Stacked Area** | Stacked areas; composition over time |
## Data Requirements
* At least one **dimension** (e.g., category, date, region)
* At least one **measure** (e.g., SUM, COUNT, AVG)
* Drag columns into **Dimensions** and **Measures** when creating the metric
## How to Set Up
1. Create or edit a metric. Add dimensions and measures from your table.
2. Click the **Charts** icon and choose **Line**, **Bar**, **Stack**, **Row**, **Area**, or **Stepped**.
3. Click the **Settings** icon and open the **Chart types** tab, then **Chart properties**.
4. Under **Required Axis**:
* **Horizontal Axis**: Select the dimension (or measure) for the X-axis.
* **Vertical Axis**: Select one or more measures for the Y-axis.
5. For **Row** and **Bullet** charts, the labels are **Vertical Axis** (Y) and **Horizontal Axis** (X) because the bars are horizontal.
## Switch X Axis / Switch Y Axis
On the metric card or in full-screen view, you can use:
* **Switch X Axis** — Change the horizontal axis (requires multiple dimensions in your metric).
* **Switch Y Axis** — Change the measure(s) on the vertical axis (requires multiple measures).
These toggles appear when the **End user measures & dimensions** or **Switch X Axis** / **Switch Y Axis** actions are enabled in **Appearance & Actions**.
## Appearance Options
Use the **Appearance** tab in **Settings** to adjust:
* Bar width, top radius, bottom radius (Bar, Stack)
* Label position, legend, colors, margins
* Number format, prefix, suffix
See [Chart-Specific Appearance Options](/guides/visualizations-actions-and-appearance/chart-appearance/chart-specific-appearance-options) for details.
# Boxplot Chart
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/boxplot
Set up a Boxplot chart for distribution and quartile visualization.
A Boxplot shows the **distribution** of a numeric variable: quartiles, median, and outliers.
## Data Requirements
* **5+ numeric columns** (or a grouped structure with enough numeric values)
* Boxplot is enabled when your metric has at least 5 numeric columns and 3+ total columns
## How to Set Up
1. Create a metric with at least 5 numeric measures or columns.
2. Click the **Charts** icon and choose **Boxplot** (if available).
3. Under **Required Axis**:
* **Horizontal Axis**: Category/dimension for grouping.
* **Vertical Axis**: The numeric measure(s) for the distribution.
## When Boxplot Is Disabled
Boxplot may not appear if:
* You have fewer than 5 numeric columns and 3+ total columns.
* The data shape does not support quartile calculation.
## Alternative
For fewer numeric columns, use a **Bar** or **Histogram** chart with a binned dimension.
# Bubble Chart V2
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/bubble-chart-v2
Bubble Chart V2 lets you control bubble size using a measure. Learn when it's available, data requirements, and why it might be disabled.
**Bubble Chart V2** lets you control **bubble size** using a **measure** (e.g., sum of revenue, count of orders), so each point's size reflects a numeric value. This is in addition to the X and Y axes.
***
## Data Requirements
To use Bubble Chart V2, you need:
| Axis | What to configure |
| ---------- | --------------------------------------------------------------------------------- |
| **X-axis** | A dimension or measure (e.g., category, date, or numeric value) |
| **Y-axis** | A dimension or measure |
| **Size** | A **measure** that determines bubble size (e.g., `SUM(revenue)`, `COUNT(orders)`) |
You need at least **one dimension** and **two measures** — one for an axis and one for bubble size.
***
## How to Use Bubble V2
1. Create or edit a metric with at least one dimension and two or more measures.
2. Select **Bubble Chart V2** (or "Bubble v2") from the chart type list.
3. In chart settings, assign a **measure to bubble size** (look for a "Bubble size" or "Size measure" setting).
4. Save the metric.
***
## Why Bubble V2 Might Be Disabled
If you don't see Bubble V2 in the chart type list or it's grayed out:
The chart type requires a measure assigned for bubble size. If no measure is configured for size, the option may be unavailable.
**Fix:** Add a second measure to your metric and assign it to the bubble size setting.
You may need at least one dimension (or axis) and two measures.
**Fix:** Add the required columns to your metric configuration.
Bubble V2 may be hidden in certain embed modes, workspaces, or plans.
**Fix:** Check whether your environment or plan supports this chart type, or contact support.
In some cases, certain metrics or data shapes filter out Bubble V2 from the chart type selector.
**Fix:** Try a metric that has clear X, Y dimensions and a numeric measure for size.
***
## Summary
| Topic | What to know |
| ------------- | -------------------------------------------------------------------------------------------- |
| Data needed | X, Y, and a **measure for bubble size**. |
| Why disabled? | Usually: no size measure set, or not enough dimensions/measures. Sometimes: context or plan. |
| What to do | Add a measure and assign it to bubble size. If still disabled, check data shape and plan. |
# Horizontal Combo: Single-Scale (Bullet Chart)
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/bullet
Set up a Bullet chart for target vs actual comparison.
A Bullet chart compares a **measure** to a **target** in a horizontal bar. Useful for KPIs and performance vs goal.
## Data Requirements
* One **dimension** (categories, e.g., sales rep, product)
* One or more **measures** (actual values)
* Optional: A **target** column or fixed target value (configured in **Bullet options** in Appearance)
## How to Set Up
1. Create a metric with a dimension and measure(s).
2. Click the **Charts** icon and choose **Horizontal Combo: Single-Scale**.
3. Under **Required Axis**:
* **Vertical Axis**: The category dimension.
* **Horizontal Axis**: The measure(s).
4. In **Appearance** → **Features**: Configure the measures as bullet measures and line measures.
## Layout
Bullet charts use horizontal bars. The bar length is the measure; a marker or segment can show the target. Configuration options depend on the implementation.
# Circular Charts (Pie, Doughnut, Rose)
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/circular-charts
Set up Pie, Doughnut, and Rose charts with dimension and measure.
Pie, Doughnut, and Rose charts show **parts of a whole**. Each uses a **dimension** (categories) and a **measure** (values).
## Chart Types
| Chart | Use case |
| ------------ | ---------------------------------------------------------- |
| **Pie** | Proportions; few categories (e.g., market share by region) |
| **Doughnut** | Same as pie with center hollow |
| **Rose** | Similar to pie; radius or area mode for different emphasis |
## Data Requirements
* One **dimension** (categories, e.g., region, product, segment)
* One **measure** (values, e.g., SUM of sales, COUNT of orders)
## How to Set Up
1. Create or edit a metric. Add one dimension and one measure.
2. Click the **Charts** icon and choose **Pie**, **Doughnut**, or **Rose**.
3. Click the **Settings** icon, then open **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Dimension**: Column for categories (sectors).
* **Measure**: Column for values (sector sizes).
## Rose Chart Options
For **Rose** charts, use the **Appearance** tab in **Settings**:
* **Rose type**:
* **Radius** — Sector radius reflects value (absolute comparisons).
* **Area** — Sector area reflects value (proportional).
## Label and Interaction
In **Appearance** → **Chart Label**:
* **Position**: Outside, Inside, or Hidden.
* **Show dimension**: Include category name in labels.
* **Selected mode**: Single, Multiple, or Series (which sectors expand on click).
* **Selected offset**: Distance (px) when a sector is selected.
## Related
* [Chart-Specific Appearance Options](/guides/visualizations-actions-and-appearance/chart-appearance/chart-specific-appearance-options) — Pie and Rose styling.
# Combo Chart (Bar + Line)
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/combo-chart
Set up Combo, Horizontal Combo, and Vertical Combo charts with bar and line series.
Combo charts mix **bars** and **lines** so you can show measures with different scales (e.g., revenue and growth rate).
## Chart Types
| Chart | Orientation |
| -------------------- | --------------------------------- |
| **Combo** | Vertical bars + line; dual Y-axes |
| **Horizontal Combo** | Horizontal bars + line |
| **Vertical Combo** | Vertical bars; stacked or grouped |
## Data Requirements
* One **dimension** (X-axis categories)
* Two or more **measures** (for bars and/or lines)
## How to Set Up
1. Create or edit a metric with one dimension and two or more measures.
2. Click the **Charts** icon and choose **Combo**, **Horizontal Combo**, or **Vertical Combo**.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Horizontal Axis**: Dimension for categories.
* **Vertical Axis**: Select the measures to show.
* **Combo Bar**: Choose which measure(s) are shown as **bars**; the rest appear as **lines**.
## Axis and Series
In **Appearance & Actions** → **Combo chart settings** (or chart configuration):
* Assign each measure to **Left** or **Right** Y-axis.
* Set each measure as **Bar** or **Line**.
* Set **Prefix** and **Suffix** per axis (e.g., "\$", "%").
## Group X-Axis
When you have multiple dimensions, **Group X-Axis** aggregates categories. Enable it in **Actions** to consolidate the X-axis.
# Funnel, Sankey, and Waterfall Charts
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/funnel-sankey-waterfall
Set up Funnel, Funnel V2, Sankey, Waterfall, and Waterfall V2.
Funnel, Sankey, and Waterfall charts show stages, flows, and cumulative changes.
## Chart Types
| Chart | Use case |
| ---------------- | -------------------------------------------------------- |
| **Funnel** | Progression through stages (e.g., signup → trial → paid) |
| **Funnel V2** | Updated funnel with D3 rendering |
| **Sankey** | Flow between nodes (e.g., source → destination) |
| **Waterfall** | Cumulative effect of +/− changes (e.g., P\&L) |
| **Waterfall V2** | Updated waterfall with enhanced styling |
## Funnel Setup
**Data:** One **step dimension** (stage order) + one **measure** (value per stage).
1. Add a dimension for stages and one measure.
2. Choose **Funnel** or **Funnel V2**.
3. Under **Required Axis**:
* **Step**: The stage/category dimension.
* **Measure**: The value per stage.
## Sankey Setup
**Data:** **Source** dimension + **Target** dimension + **Value** measure.
1. Add at least two dimensions (source, target) and one measure.
2. Choose **Sankey**.
3. Under **Required Axis**:
* **Source**: "From" node column.
* **Target**: "To" node column.
* **Value**: Flow size (measure).
## Waterfall Setup
**Data:** One **category dimension** + one **measure**. Optional start value and total row.
1. Add a dimension (e.g., P\&L line items) and one measure.
2. Choose **Waterfall** or **Waterfall V2**.
3. Under **Required Axis**:
* **Horizontal Axis**: Category dimension.
* **Vertical Axis**: Measure (positive = up, negative = down).
4. In **Waterfall settings** (Appearance): configure increase/decrease colors, total styling, optional start value.
# Gantt Chart
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/gantt
Set up a Gantt chart for task timelines.
A Gantt chart shows **tasks** over time with start and end dates. Useful for project timelines and scheduling.
## Data Requirements
* **Task** dimension (task name or label)
* **Start date** column
* **End date** column
* Optional: **Duration** or additional dimensions
* Gantt is enabled when you have **4+ dimension columns** (per `getEnabledChart`)
## How to Set Up
1. Create a metric with a task dimension and start/end date columns.
2. Click the **Charts** icon and choose **Gantt** (if available).
3. In chart configuration, assign:
* Task/label dimension
* Start date column
* End date column
4. Use **Appearance** for colors, labels, and tooltip content.
## When Gantt Is Disabled
Gantt may not appear if you have fewer than 4 dimension (non-numeric) columns. Add more dimensions to your metric to enable it.
# Gauge, Progress Bar, and Linear Gauge
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/gauge-progress-linear-gauge
Set up Gauge V2, Progress Bar, Progress Bar V2, Linear Gauge, and Linear Gauge V2 for single-value KPIs.
Gauge, Progress Bar, and Linear Gauge show **one main value** or progress toward a target.
**Gauge V1 is deprecated.** If you see a message to use Gauge V2 instead, choose **Gauge V2** from the chart type list. Gauge V2 offers improved styling and options.
## Chart Types
| Chart | Use case |
| ------------------- | -------------------------------------------- |
| **Gauge V2** | Radial gauge; score or utilization % |
| **Progress Bar** | Horizontal bar; % complete or usage vs limit |
| **Progress Bar V2** | Updated progress bar |
| **Linear Gauge** | Horizontal scale with segments/thresholds |
| **Linear Gauge V2** | Updated linear gauge |
## Data Requirements
* One **measure** (the value to display)
* Optional: **Progress max** and **Progress min** columns for range (Progress Bar, Linear Gauge)
* Optional: **Dimensions** for gauge breakdown (Gauge V2)
## How to Set Up
1. Create a metric with at least one measure. For progress, add optional min/max columns.
2. Click the **Charts** icon and choose the chart type.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Gauge V2**: **Measure** (metric) and optional **Dimensions** for breakdown.
* **Progress Bar / Linear Gauge**: **Measure** (progress column). Optionally set **Progress max** and **Progress min** columns in chart configuration.
## Min and Max
In **Appearance** or chart configuration:
* Set **Min** and **Max** for the scale (e.g., 0–100 for %, or 0–capacity for usage).
* If not set, the app may use the measure range or 0–100.
## Thresholds (Gauge and Linear Gauge)
Thresholds color parts of the scale (e.g., green 0–60, yellow 60–80, red 80–100). Configure in **Appearance** → chart-specific settings.
## Formatting
Set **Prefix** (e.g., "\$") and **Suffix** (e.g., "%", "K") in **Appearance** → **Formatting**.
# How to Create a Histogram
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/histogram
Create histograms using the Histogram chart type or a bar chart with numeric dimensions and binning.
A histogram shows the **distribution** of a numeric variable — for example, how many orders fall into each price range, or how customers are distributed across age brackets.
***
## When to Use a Histogram
* You have a **numeric column** (e.g., price, age, quantity, score) and want to see how many rows fall into each range (bin).
* You want a **count** (or similar aggregate) per bin, not individual values.
***
## Option 1: Histogram Chart Type
If **Histogram** is available in the chart type list:
1. Create or edit a metric.
2. Select **Histogram** as the chart type.
3. Add a **numeric dimension** (the column you want to bin, e.g., `order_amount`).
4. Add a **measure** (e.g., Count).
5. The product may **automatically create bins** from the numeric dimension.
If bins are not as expected (e.g., too many or too few), see Option 2 for manual control.
***
## Option 2: Bar Chart with Numeric Dimension
For more control over binning, use a **Bar chart**:
1. Create a **binned column** in your dataset using SQL:
```sql theme={"dark"}
SELECT
FLOOR(order_amount / 50) * 50 AS price_bucket,
COUNT(*) AS order_count
FROM orders
GROUP BY price_bucket
ORDER BY price_bucket
```
This creates buckets of 50 (e.g., 0-49, 50-99, 100-149).
2. Use the binned column (e.g., `price_bucket`) as the **X-axis dimension**.
3. Use the count as the **Y-axis measure**.
4. Select **Bar chart** as the visualization type.
***
## Why "Count + Bar" Might Not Look Like a Histogram
A histogram needs **one bar per bin** with a **count per bin**. Common issues:
* **No dimension added**: If you only add a count measure without a dimension, you get a single bar. Add a dimension that represents the bins.
* **Non-numeric dimension**: If your dimension is categorical (not numeric), the chart shows categories instead of ranges. Use a numeric column or create bins in SQL.
* **Group By has no options**: Ensure your metric has at least one **dimension** and one **measure**. Some aggregation choices (e.g., window functions like `PERCENTILE_CONT`) do not collapse rows into groups and may leave Group By empty.
***
## Summary
| Goal | What to do |
| ------------------------ | ------------------------------------------------------------------------------ |
| Use Histogram chart type | Select Histogram, add numeric dimension + measure (e.g., Count). |
| Use Bar chart | Create bins in SQL (e.g., `FLOOR(col/10)*10`), use as X-axis, Count as Y-axis. |
| Bins not automatic? | Create bins in SQL or a calculated column, then use as dimension. |
| Group By empty? | Ensure you have at least one dimension and one aggregate measure. |
# Hybrid Bar Chart
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/hybrid-bar
Set up a Hybrid Bar chart with mixed stacked and non-stacked bars.
A Hybrid Bar chart mixes **stacked** and **non-stacked** bars for different measures. Some measures stack; others appear as separate bars.
## Data Requirements
* One **dimension** (X-axis categories)
* Two or more **measures**
* Configure which measures **stack** together
## How to Set Up
1. Create a metric with one dimension and two or more measures.
2. Click the **Charts** icon and choose **Hybrid bar**.
3. Under **Required Axis**:
* **Horizontal Axis**: Dimension for categories.
* **Vertical Axis**: The measures.
4. In **Appearance** or chart configuration, set **Hybrid stack measures** — choose which measure(s) are stacked together. Other measures appear as separate bars.
# Map Charts
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/maps
Set up World Map, Indian States, Geo Map, Geo Map with Bar, and Geo Map with Scatter.
Map charts show values by geographic region. The map type depends on the geography in your data.
## Chart Types
| Chart | Geography |
| -------------------------- | -------------------------------- |
| **World Map** | Countries |
| **Indian States** | Indian states/territories |
| **Geo Map** | US states |
| **Geo Map (with bar)** | US states with bar chart overlay |
| **Geo Map (with scatter)** | US states with scatter overlay |
## Data Requirements
* One **dimension** with region names (country names, US state names, or Indian state names — must match map geography)
* One or more **measures** (values to color or size the regions)
## How to Set Up
1. Create a metric with a region dimension (e.g., country, state) and a measure.
2. Click the **Charts** icon and choose the map type that matches your geography.
3. Under **Required Axis**:
* **Horizontal Axis**: The region/country/state column. Values must match the map (e.g., "United States" for World Map, "California" for Geo Map).
* **Vertical Axis**: The measure(s) for color or size.
4. For **Geo Map (with bar)** or **Geo Map (with scatter)**, the map shows regions with additional bar or scatter overlays.
## Region Name Matching
Region names in your data must match the map’s expected values (e.g., "United States" not "USA" for World Map). Rows that don’t match any region may appear in a separate table or be omitted.
# Network Chart
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/network
Set up a Network chart for node and link visualization.
A Network chart shows **nodes** and **links** between them (e.g., relationships, flow). Similar in structure to Sankey but for graph-style connections.
## Data Requirements
* **Source** dimension (from node)
* **Target** dimension (to node)
* **Value** measure (link strength/size)
* Network is enabled when you have 3+ total columns and 5+ numeric values (per `getEnabledChart` logic)
## How to Set Up
1. Create a metric with at least two dimensions (source, target) and one measure.
2. Click the **Charts** icon and choose **Network** (if available).
3. Configure **Source**, **Target**, and **Value** in chart properties (similar to Sankey setup).
## When Network Is Disabled
Network may not appear if your data has fewer than 3 total columns or fewer than 5 numeric values. Use **Sankey** for flow-style data with a similar structure.
# Chart Setup Overview
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/overview
How to set up each chart type in Databrain. Data requirements, axis assignment, and chart-specific settings.
This guide explains how to configure each chart type in Databrain. For each chart, you choose dimensions and measures, assign them to axes or specific roles, and adjust settings in **Settings** (or **Appearance & Actions**).
## Access Chart Setup
1. Create or edit a metric from your dashboard.
2. Click the **Charts** icon to select a chart type.
3. Use the **Settings** icon (or **Appearance & Actions**) to configure axes and chart-specific options.
4. Configure **Chart types** and **Chart properties** in the settings panel.
## Chart Setup Guides
| Chart Type | Guide | Data Requirements |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| Bubble V2 | [Bubble Chart V2](/guides/visualizations-actions-and-appearance/chart-setup/bubble-chart-v2) | X-axis, Y-axis, measure for bubble size |
| Histogram | [Histogram](/guides/visualizations-actions-and-appearance/chart-setup/histogram) | Numeric dimension + measure |
| Axis charts (Line, Bar, Stack, Row, Area, etc.) | [Axis Charts](/guides/visualizations-actions-and-appearance/chart-setup/axis-charts) | Dimension(s) + measure(s) |
| Circular (Pie, Doughnut, Rose) | [Circular Charts](/guides/visualizations-actions-and-appearance/chart-setup/circular-charts) | Step + measure |
| Scatter, Bubble | [Scatter and Bubble](/guides/visualizations-actions-and-appearance/chart-setup/scatter-bubble) | X-axis, Y-axis (Bubble: + size) |
| Combo, Horizontal Combo, Vertical Combo | [Combo Chart](/guides/visualizations-actions-and-appearance/chart-setup/combo-chart) | Dimension + 2+ measures |
| Time Series | [Time Series](/guides/visualizations-actions-and-appearance/chart-setup/time-series) | Date dimension + measure(s) |
| Pivot Table (1, 2, 3) | [Pivot Table](/guides/visualizations-actions-and-appearance/chart-setup/pivot-table) | Dimensions + measures |
| Funnel, Sankey, Waterfall | [Funnel, Sankey, and Waterfall](/guides/visualizations-actions-and-appearance/chart-setup/funnel-sankey-waterfall) | Step + measure; Sankey: source + target + value |
| Gauge, Progress Bar, Linear Gauge | [Gauge, Progress, and Linear Gauge](/guides/visualizations-actions-and-appearance/chart-setup/gauge-progress-linear-gauge) | One measure; min/max; optional thresholds |
| Single Value | [Single Value](/guides/visualizations-actions-and-appearance/chart-setup/single-value) | One measure |
| Table, Horizontal Stack Table | [Table and Horizontal Stack Table](/guides/visualizations-actions-and-appearance/chart-setup/table-advanced) | Dimensions + measures |
| Maps (World, Indian, Geo) | [Maps](/guides/visualizations-actions-and-appearance/chart-setup/maps) | Region dimension + measure |
| Trend Analyzer | [Trend Analyzer](/guides/visualizations-actions-and-appearance/chart-setup/trend-analyzer) | Time-series data |
| Boxplot | [Boxplot](/guides/visualizations-actions-and-appearance/chart-setup/boxplot) | 5+ numeric columns |
| Tree Map | [Tree Map](/guides/visualizations-actions-and-appearance/chart-setup/tree-map) | Dimension + measure |
| Bullet | [Bullet Chart](/guides/visualizations-actions-and-appearance/chart-setup/bullet) | Measure + optional target |
| Hybrid Bar | [Hybrid Bar](/guides/visualizations-actions-and-appearance/chart-setup/hybrid-bar) | Dimension + measures; hybrid stack |
| Network | [Network Chart](/guides/visualizations-actions-and-appearance/chart-setup/network) | Source, target, value |
| Gantt | [Gantt Chart](/guides/visualizations-actions-and-appearance/chart-setup/gantt) | Start/end dates, task labels |
## Related
* [Chart Appearance](/guides/visualizations-actions-and-appearance/chart-appearance) — Customize axes, legend, colors, and formatting
* [Chart Actions](/guides/visualizations-actions-and-appearance/chart-actions) — Click actions, drill down, switch axes
# Pivot Table
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/pivot-table
Set up Pivot Table, Pivot Table 2, and Pivot Table 3.
Pivot tables show data in rows and columns with measures as values. Pivot Table 2 and 3 add column headers, dynamic pivot columns, and row aggregates.
## Chart Types
| Chart | Use case |
| ----------------- | ------------------------------------- |
| **Pivot Table** | Basic pivot: rows and columns |
| **Pivot Table 2** | Column headers, dynamic pivot columns |
| **Pivot Table 3** | Columns, rows, row aggregates |
## Data Requirements
* One or more **dimensions** (for rows and/or column headers)
* One or more **measures** (for cell values)
## How to Set Up
1. Create or edit a metric with dimensions and measures.
2. Click the **Charts** icon and choose **Pivot Table**, **Pivot Table 2**, or **Pivot Table 3**.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Pivot Table**: Choose **Metrics** and **Group by** (dimensions for structure).
* **Pivot Table 2 / 3**: Configure in **Pivot Settings** (gear or configuration panel):
* **Columns** / **Headers**: Dimensions for column headers.
* **Rows** / **Dimensions**: Dimensions for row structure.
* **Measures**: Measures for cell values.
## Pivot Table 2 Options
* **Dynamic pivot columns**: Column headers come from dimension values in your data (e.g., months as columns).
* **Headers**: Which dimensions appear as column headers.
## Pivot Table 3 Options
* **Columns** and **Rows**: Define the pivot structure.
* **Show Row Aggregates**: Add a summary row (e.g., Total) at the bottom.
* **Aggregate Type**: Sum, Average, or Count for the aggregated row.
# Scatter and Bubble Charts
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/scatter-bubble
Set up Scatter and Bubble (V1) charts. For Bubble V2 with measure-based size, see Bubble Chart V2.
Scatter and Bubble charts show points on X and Y axes. **Scatter** uses two numeric dimensions or measures. **Bubble (V1)** adds a constant size multiplier. For size driven by a measure, use [Bubble Chart V2](/guides/visualizations-actions-and-appearance/chart-setup/bubble-chart-v2).
## Data Requirements
| Chart | Requirements |
| --------------- | ------------------------------------------------------------------- |
| **Scatter** | Horizontal axis (X), Vertical axis (Y) — dimensions or measures |
| **Bubble (V1)** | Same as Scatter + **Constant for bubble size** (numeric multiplier) |
## How to Set Up Scatter
1. Create or edit a metric with at least one dimension and one measure (or two dimensions).
2. Click the **Charts** icon and choose **Scatter**.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Horizontal Axis**: Column for X.
* **Vertical Axis**: Column(s) for Y (multiple create multiple series).
## How to Set Up Bubble (V1)
1. Set up as for Scatter.
2. Choose **Bubble** from the chart type list.
3. Under **Required Axis**, set **Horizontal Axis** and **Vertical Axis**.
4. Set **Constant for bubble size** — a number that scales all bubble sizes (e.g., 20).
## Scatter vs Bubble V1 vs Bubble V2
| Chart | X | Y | Size |
| --------- | -------------------- | -------------------- | ------------------------------ |
| Scatter | Dimension or measure | Dimension or measure | N/A |
| Bubble V1 | Dimension or measure | Dimension or measure | Constant (same for all points) |
| Bubble V2 | Dimension or measure | Dimension or measure | **Measure** (e.g., SUM, COUNT) |
Use **Bubble V2** when each point’s size should reflect a measure (e.g., revenue, count). Use Bubble V1 when you only need a uniform scale factor.
# Single Value (KPI Card)
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/single-value
Set up a Single Value card for KPIs, with optional metric expression and comparison.
A Single Value card shows **one number** (e.g., total revenue, count of customers). You can add a metric expression, comparison value, and conditional formatting.
## Data Requirements
* One **measure** (or dimension that returns a single value when aggregated)
## How to Set Up
1. Create a metric with one measure. For a true KPI, use an aggregate (e.g., SUM, COUNT) without a dimension, or with a filter that returns one row.
2. Click the **Charts** icon and choose **Single Value**.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Measure**: The column to display.
## Metric Expression
Use a **metric expression** to compute the displayed value (e.g., percentage, ratio). Configure in metric settings or the Single Value configuration.
## Comparison Value
Enable **Comparison** in **Appearance** to show a previous-period or target comparison (e.g., "vs last month"). Configure the comparison column and format in chart settings.
## Conditional Formatting
In **Appearance**, you can define rules that change color based on value ranges (e.g., green when above target, red when below).
# Table and Horizontal Stack Table
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/table-advanced
Set up Table and Horizontal Stack Table charts.
Tables show data in rows and columns. **Horizontal Stack Table** adds horizontal bars for selected measure columns.
## Data Requirements
* **Table**: One or more dimensions and measures.
* **Horizontal Stack Table**: Dimensions + measures; choose which columns get stack bars.
## How to Set Up Table
1. Create a metric with dimensions and measures.
2. Choose **Table** from the chart type list.
3. Under **Required Axis** → **Measure**: Select the columns to display (dimensions and measures).
4. In **Appearance** → **Table settings**: Configure alignment, formatting, pagination, search, sorting, conditional formatting.
## How to Set Up Horizontal Stack Table
1. Create a metric with dimensions and measures.
2. Choose **Horizontal Stack Table**.
3. Under **Required Axis**:
* **Vertical Axis**: Dimensions for rows.
* **Measure**: Measures for columns and bars.
4. In chart configuration, set **Stack columns** — which measure columns show horizontal bars.
5. In **Appearance**: Bar width, radius, label position, colors.
## Table Settings
In **Appearance** → **Table settings**:
* Header alignment, content alignment, font weight
* Number formatting, prefix, suffix
* Conditional formatting (colors by value)
* Pagination, search, sorting
* Hide columns, text wrap
## Text Wrap and Line Breaks
To wrap long cell content or preserve newlines that exist in your data, open the **Text Wrap** section of the table settings:
* **Enable Header Text Wrap** — wrap long column headers.
* **Enable Content Text Wrap** — wrap cell content instead of truncating it.
* **Text Wrap Columns** — choose which columns wrap (leave empty for all).
* **Allow Line Breaks** — render newline characters in your data as actual line breaks. Without this, multi-line values display as one line.
For multi-line cell content, turn on both **Enable Content Text Wrap** and **Allow Line Breaks**.
## Conditional Formatting with Number Formatters
By default, conditional-formatting rules compare against the **raw** column value. If you apply a number formatter (for example a `%` formatter), your rule thresholds may stop matching — a rule of `> 50` matches the raw value `0.5` differently than the formatted `50%`.
When a number formatter targets a column, a **Compare Value with** control appears in the conditional-formatting settings with two options:
* **Raw Data** (default) — rules compare against the unformatted value (`0.5`).
* **Formatted Data** — rules compare against the value after formatting (`50%`).
Pick the mode that matches how you wrote your thresholds. If your conditional formatting "broke" after adding a formatter, switching this control is usually the fix.
# Time Series Chart
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/time-series
Set up a Time Series chart with date dimension and measures.
A Time Series chart shows measures over a **date or time dimension** (e.g., daily revenue, weekly orders). You can mix line, bar, and area series.
## Data Requirements
* One **date dimension** (e.g., order date, created at) for the X-axis
* One or more **measures** (e.g., SUM of sales, COUNT of orders)
## How to Set Up
1. Create or edit a metric. Add a **date-type** column as a dimension and one or more measures.
2. Click the **Charts** icon and choose **Time series**.
3. Click **Settings** → **Chart types** → **Chart properties**.
4. Under **Required Axis**:
* **Horizontal Axis**: The date dimension.
* **Vertical Axis**: The measure(s) to plot.
5. In **Appearance** (or chart configuration), use **Time series** settings to:
* **Group by**: Daily, Weekly, Monthly, Quarterly, or Yearly.
* **Series type**: For each measure, choose Line, Bar, Area, Stack, or Combo.
## Time Grain / Group By
The **Group by** option buckets dates (e.g., by month or week). Use it when raw dates are too granular. Options include:
* Daily
* Weekly
* Monthly
* Quarterly
* Yearly
## Dynamic Group By
When **Dynamic** group by is enabled, you can change the time grain from the metric card or full-screen view.
# Tree Map
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/tree-map
Set up a Tree Map chart for hierarchical breakdown.
A Tree Map shows **hierarchical data** as nested rectangles. Size reflects the measure; grouping reflects dimensions.
## Data Requirements
* One or more **dimensions** (for hierarchy/grouping)
* One or more **measures** (for rectangle size)
## How to Set Up
1. Create a metric with dimensions and measures.
2. Click the **Charts** icon and choose **Tree map**.
3. Under **Required Axis**:
* **Metrics**: The measure(s) for rectangle size.
* **Group by** / dimensions: Define the hierarchy.
## Configuration
Tree Map uses pivot-style configuration. Set which dimensions form the hierarchy and which measures determine size in the chart properties panel.
# Trend Analyzer
Source: https://docs.usedatabrain.com/guides/visualizations-actions-and-appearance/chart-setup/trend-analyzer
Set up the Trend Analyzer chart for time-series and trend analysis.
Trend Analyzer shows data in a table-like view with trend analysis. It is available when your metric returns data suitable for trend or time-series analysis.
## When Trend Analyzer Is Available
Trend Analyzer appears in the chart type list when your metric has:
* A single **measure** (with or without dimensions), or
* Only non-numeric columns (categorical data)
Availability can vary by workspace and plan.
## Data Requirements
* At least one column (dimension or measure)
* Often used with time-series or sequential data
## How to Set Up
1. Create a metric with the appropriate data shape.
2. Click the **Charts** icon and choose **Trend Analyzer** (if available).
3. Configure columns in **Chart properties** as for a table.
4. Use **Appearance** and **Table settings** to adjust layout and formatting.
## Notes
Trend Analyzer is not available in all embed modes (e.g., some plugin/end-user configurations). If it does not appear, use **Table** or **Time Series** for similar use cases.
# Multi Datamart Workspace
Source: https://docs.usedatabrain.com/guides/workspace/multi-datamart-workspace
Steps to Set Up and Use Multi-Datamart Switching in Your Dashboard.
Navigate to the Data Studio page and add all the datamarts.
Follow the steps outlined in the link below to configure each datamart properly.
Step-by-step guide for creating and configuring your datamarts.
On the Home page, click to create a new workspace.
Select Multi Datamart under the "Select Data Connection" option.
Create a new dashboard.
Locate the dropdown dedicated to Datamart Switching in your dashboard interface.
Add your desired metrics.
Enjoy seamless switching between datamarts within the same dashboard.
You’ve successfully set up your Multi-Datamart Workspace in Databrain!\
Your dashboards can now dynamically switch between multiple datamarts, allowing seamless comparison and unified insights across databases.
# Multi Datasource Workspace
Source: https://docs.usedatabrain.com/guides/workspace/multi-datasource-workspace
Steps to Set Up and Use Multi-Datasource Switching in Your Dashboard.
Navigate to the Data Studio page and add all the datasources.
Follow the steps outlined in the link below to configure each datasource properly.
Step-by-step guide for adding your data connections.
Skip Tenancy if each client/customer is identified by a unique database (Datasource).
On the Home page, click to create a new workspace.
Select Multi Datasource under the "Select Data Connection" option.
Create a new dashboard.
Locate the dropdown dedicated to Datasource Switching in your dashboard interface.
Add your desired metrics.
Enjoy seamless switching between datasources within the same dashboard.
You’ve successfully set up your Multi-Datasource Workspace in Databrain!\
Your dashboards can now dynamically switch between multiple data sources, allowing seamless comparison and unified insights across databases.