> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usedatabrain.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an Empty Dashboard Embed

> 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.

<Warning>
  **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.
</Warning>

<Note>
  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.
</Note>

## Endpoint Formats

<Tabs>
  <Tab title="New Endpoint (Recommended)">
    ```
    POST https://api.usedatabrain.com/api/v2/data-app/dashboard-embeds
    ```

    **Use this endpoint** for all new integrations. This is the recommended endpoint format.
  </Tab>

  <Tab title="Legacy Endpoint (Deprecated Soon)">
    ```
    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.
  </Tab>
</Tabs>

## 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

<ParamField header="Authorization" type="string" required>
  Bearer token for API authentication. Use your API key from the data app.

  ```
  Authorization: Bearer dbn_live_abc123...
  ```
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Supported values:

  * `application/json` for pure JSON payloads
  * `multipart/form-data` when uploading a dashboard export JSON file via `importDashboardDataFile`

  ```
  Content-Type: application/json
  ```
</ParamField>

<Note>
  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.
</Note>

<Note>
  `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.
</Note>

## Request Body

<ParamField body="dashboardId" type="string" required>
  Unique identifier for the new dashboard. Must be unique within the data app.
</ParamField>

<ParamField body="workspaceName" type="string" required>
  The name of the workspace where the dashboard will be created.
</ParamField>

<ParamField body="clientId" type="string" required>
  Client ID for the dashboard owner. Used for multi-tenant isolation and row-level security.
</ParamField>

<ParamField body="templateDashboardId" type="string">
  Dashboard ID to clone filters, grid margins, and layout settings from (optional).
</ParamField>

<ParamField body="metadata" type="object">
  Custom metadata for the dashboard (optional).
</ParamField>

<ParamField body="isAllowPrivateMetricsByDefault" type="boolean">
  Allow users to create private metrics visible only to them (optional).
</ParamField>

<ParamField body="name" type="string">
  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.
</ParamField>

<ParamField body="embedDescription" type="string">
  Description for the embed configuration (optional).
</ParamField>

<ParamField body="isImportMetrics" type="boolean">
  When `true` and `templateDashboardId` is provided, metrics from the template dashboard are imported into the new dashboard (optional).
</ParamField>

<ParamField body="importDashboardData" type="object">
  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.
</ParamField>

<ParamField body="importDashboardDataFile" type="file (.json)">
  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.
</ParamField>

<ParamField body="isRenameDashboard" type="boolean">
  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.
</ParamField>

<ParamField body="metricImportMode" type="'GALLERY' | 'METRIC'">
  When `isImportMetrics` is `true` and `templateDashboardId` is provided, controls how metrics are imported: `GALLERY` or `METRIC` (optional).
</ParamField>

<ParamField body="schemaPairs" type="array">
  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.
</ParamField>

<ParamField body="accessSettings" type="object" required>
  Access control settings for the dashboard.
</ParamField>

<ParamField body="accessSettings.datamartName" type="string" required>
  The datamart name used in the embedded environment.
</ParamField>

<ParamField body="accessSettings.isAllowAiPilot" type="boolean">
  Allow AI Pilot features (optional).
</ParamField>

<ParamField body="accessSettings.isAllowEmailReports" type="boolean" required>
  Allow sending email reports.
</ParamField>

<ParamField body="accessSettings.isAllowManageMetrics" type="boolean" required>
  Allow managing metrics.
</ParamField>

<ParamField body="accessSettings.isAllowMetricCreation" type="boolean" required>
  Allow metric creation.
</ParamField>

<ParamField body="accessSettings.isAllowMetricDeletion" type="boolean" required>
  Allow metric deletion.
</ParamField>

<ParamField body="accessSettings.isAllowMetricLayoutChange" type="boolean" required>
  Allow layout changes to metrics.
</ParamField>

<ParamField body="accessSettings.isAllowMetricUpdate" type="boolean" required>
  Allow updating metrics.
</ParamField>

<ParamField body="accessSettings.isAllowUnderlyingData" type="boolean" required>
  Allow viewing of underlying data.
</ParamField>

<ParamField body="accessSettings.isAllowCreateDashboardView" type="boolean" required>
  Allow creating dashboard views.
</ParamField>

<ParamField body="accessSettings.joinModel" type="'single' | 'multi'">
  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)
</ParamField>

<ParamField body="accessSettings.isIncrementalJoin" type="boolean">
  Legacy join strategy flag. Prefer using `accessSettings.joinModel` instead.
</ParamField>

<ParamField body="accessSettings.metricCreationMode" type="'DRAG_DROP' | 'CHAT'" required>
  Mode of metric creation (drag and drop or chat).
</ParamField>

<ParamField body="accessSettings.tableTenancySettings" type="array">
  List of allowed tables and client columns for table tenancy (optional). When provided, each item must include `name` and `clientColumn`.
</ParamField>

<ParamField body="accessSettings.tableTenancySettings[].name" type="string">
  Table name. Required when the parent `tableTenancySettings` array is provided.
</ParamField>

<ParamField body="accessSettings.tableTenancySettings[].clientColumn" type="string">
  Client-level column for table tenancy. Required when the parent `tableTenancySettings` array is provided.
</ParamField>

<Panel>
  <RequestExample>
    ```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,
          "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,"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,
          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,
            "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')}")
    ```
  </RequestExample>

  <ResponseExample>
    ```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
      }
    }
    ```
  </ResponseExample>
</Panel>

## Response

<ResponseField name="id" type="string">
  The ID of the created dashboard embed configuration.
</ResponseField>

<ResponseField name="error" type="null | object">
  Error object if the request failed, otherwise `null`.
</ResponseField>

<ResponseField name="name" type="string">
  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`.
</ResponseField>

## 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

<Steps>
  <Step title="Get your API token">
    For detailed instructions, see the [API Token guide](/developer-docs/helpers/api-token).
  </Step>

  <Step title="Create a new dashboard for your client">
    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"
        }
      }'
    ```
  </Step>

  <Step title="(Optional) Use a template">
    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": { ... }
    }
    ```
  </Step>

  <Step title="Generate a guest token">
    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.
  </Step>

  <Step title="Embed in your application">
    Use the dashboard ID and guest token in your web component:

    ```javascript theme={"dark"}
    <dbn-dashboard 
      token="guest-token-here" 
      dashboard-id="client-acme-analytics" 
    />
    ```
  </Step>
</Steps>

## Use Cases

<CardGroup cols={2}>
  <Card title="Multi-Tenant SaaS" icon="users">
    Create isolated dashboards for each customer in your SaaS application.
  </Card>

  <Card title="Template-Based Creation" icon="copy">
    Use `templateDashboardId` to clone filters and settings from a master template.
  </Card>

  <Card title="Custom Dashboard Names" icon="signature">
    Set `isRenameDashboard: true` with `name` to give each client dashboard a human-readable display name instead of `{dashboardId}_{clientId}`.
  </Card>

  <Card title="Dynamic Provisioning" icon="wand-magic-sparkles">
    Automatically create dashboards during customer onboarding or upgrades.
  </Card>

  <Card title="Client Isolation" icon="shield">
    Ensure data isolation with `clientId` and row-level security settings.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Generate Guest Token" icon="key" href="/developer-docs/helpers/api-reference/token">
    Create secure tokens to access your new dashboard
  </Card>

  <Card title="Embed a Pre-built Dashboard/Metric" icon="code" href="/developer-docs/helpers/api-reference/create-embed">
    Embed existing dashboards that were built in the databrain platform
  </Card>

  <Card title="How to Embed" icon="laptop-code" href="/developer-docs/how-to-embed">
    Integrate dashboards into your application
  </Card>

  <Card title="Multi-Tenant Access Control" icon="shield" href="/developer-docs/multi-tenant-access-control">
    Set up row-level security for your dashboards
  </Card>
</CardGroup>
