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

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

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

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

## Endpoint Formats

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

    **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/data-app/datamarts
    ```

    This endpoint still works but will be deprecated. Please migrate to the new endpoint format.
  </Tab>
</Tabs>

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

<Panel>
  <RequestExample>
    ```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'
    ```
  </RequestExample>
</Panel>

## Headers

<ParamField header="Authorization" type="string" required>
  Bearer token for API authentication. Use your service token.

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

<ParamField header="Content-Type" type="string" required>
  Must be set to `application/json` for all requests.

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

## Request Body

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

  <Expandable title="Naming guidelines">
    * 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
  </Expandable>
</ParamField>

<ParamField body="datasourceName" type="string" required>
  The datasource to which this datamart belongs. Must match an existing datasource in your organization.

  <Expandable title="Finding datasource names">
    * Check your datasources list in the DataBrain dashboard
    * Use the exact name as it appears in your datasource configuration
    * Names are case-sensitive
  </Expandable>
</ParamField>

<ParamField body="tableList" type="array" required>
  Array of tables with columns to include in the datamart. Must be non-empty.
</ParamField>

<ParamField body="tableList.name" type="string" required>
  Table name from your datasource.
</ParamField>

<ParamField body="tableList.schemaName" type="string">
  Optional schema name (required only for schema-based datasources like PostgreSQL, SQL Server).
</ParamField>

<ParamField body="tableList.clientColumn" type="string">
  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.

  <Expandable title="Client column usage">
    * Used for table-level tenancy when `tenancyLevel` is `TABLE`
    * The column should contain client/tenant identifiers
  </Expandable>
</ParamField>

<ParamField body="tableList.isHide" type="boolean">
  Optional flag to hide the table from the datamart interface.
</ParamField>

<ParamField body="tableList.label" type="string">
  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.

  <Expandable title="Label usage">
    * 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
  </Expandable>
</ParamField>

<ParamField body="tableList.wildcard" type="string">
  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.

  <Expandable title="OpenSearch wildcard usage">
    * 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
  </Expandable>
</ParamField>

<ParamField body="tableList.columns" type="array" required>
  List of column objects for this table. Must be non-empty.
</ParamField>

<ParamField body="tableList.columns.name" type="string" required>
  Column name from the table.
</ParamField>

<ParamField body="tableList.columns.alias" type="string">
  Optional alias for the column to display a different name.
</ParamField>

<ParamField body="tableList.columns.label" type="string">
  Optional label for the column for better readability.
</ParamField>

<ParamField body="tableList.columns.isHide" type="boolean">
  Optional flag to hide the column from the datamart interface.
</ParamField>

<ParamField body="tableList.columns.isCustomColumn" type="boolean">
  Optional flag to mark this as a custom/calculated column. When `true`, the `sql` field is required to define the column's SQL expression.

  <Expandable title="Custom column usage">
    * 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
  </Expandable>
</ParamField>

<ParamField body="tableList.columns.sql" type="string">
  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.

  <Expandable title="SQL expression examples">
    * 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`
  </Expandable>
</ParamField>

<ParamField body="tableList.columns.isAggregate" type="boolean">
  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.

  <Expandable title="Aggregate column usage">
    * 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
  </Expandable>
</ParamField>

<ParamField body="tableList.columns.isApplyTimezone" type="boolean">
  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.

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

  <Expandable title="Timezone conversion details">
    * 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
  </Expandable>
</ParamField>

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

  <Expandable title="Tenancy configuration details">
    * **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
  </Expandable>
</ParamField>

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

<ParamField body="tenancySettings.clientColumnType" type="string">
  Data type of the client identifier column. Must be either `NUMBER` or `STRING`.

  **Required when** `tenancyLevel` is `TABLE`.
</ParamField>

<ParamField body="tenancySettings.primaryDatabase" type="string | null">
  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`.
</ParamField>

<ParamField body="tenancySettings.schemaName" type="string">
  Schema name where the client mapping table is located.

  **Required when** `tenancyLevel` is `TABLE`.
</ParamField>

<ParamField body="tenancySettings.tableName" type="string">
  Name of the table that contains client mapping information.

  **Required when** `tenancyLevel` is `TABLE`.
</ParamField>

<ParamField body="tenancySettings.tableClientNameColumn" type="string">
  Column name in the mapping table that stores the client identifier.

  **Required when** `tenancyLevel` is `TABLE`.
</ParamField>

<ParamField body="tenancySettings.tablePrimaryKeyColumn" type="string">
  Primary key column of the client mapping table.

  **Required when** `tenancyLevel` is `TABLE`.
</ParamField>

<ParamField body="relationships" type="array">
  Optional array of table relationships to define how tables in the datamart are connected. Relationships enable joins between tables for more complex queries.

  <Expandable title="Relationship configuration">
    * 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
  </Expandable>
</ParamField>

<ParamField body="relationships.parentTableName" type="string" required>
  Name of the parent table in the relationship.
</ParamField>

<ParamField body="relationships.parentColumnName" type="string" required>
  Column name in the parent table that participates in the relationship.
</ParamField>

<ParamField body="relationships.childTableName" type="string" required>
  Name of the child table in the relationship.
</ParamField>

<ParamField body="relationships.childColumnName" type="string" required>
  Column name in the child table that participates in the relationship.
</ParamField>

<ParamField body="relationships.relationshipName" type="string" required>
  A descriptive name for the relationship (e.g., "orders\_to\_customers").
</ParamField>

<ParamField body="relationships.cardinality" type="string">
  The cardinality of the relationship. Must be one of: `ManyToMany`, `ManyToOne`, `OneToMany`, `OneToOne`.

  **Optional:** Can be omitted or set to `null` if not specified.
</ParamField>

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

## Response

<ResponseField name="id" type="string">
  The name of the created datamart (same as the input name).
</ResponseField>

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

## Examples

<Panel>
  <RequestExample>
    ```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": "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
              },
              {
                "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"
        }
      }'
    ```

    ```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<String> 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"}
    <?php
    $url = 'https://api.usedatabrain.com/api/v2/data-app/datamarts';
    $data = [
        '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'
            ]
        ]
    ];

    $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'];
    ?>
    ```
  </RequestExample>

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

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

<Steps>
  <Step title="Verify your datasource">
    Ensure your datasource exists and is properly configured. You'll need the exact datasource name as it appears in your DataBrain workspace.
  </Step>

  <Step title="Prepare your table structure">
    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"
        }
      ]
    }
    ```
  </Step>

  <Step title="Create your datamart">
    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"
          }
        ]
      }'
    ```
  </Step>

  <Step title="Use your datamart">
    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
      }
    });
    ```
  </Step>
</Steps>

## Next Steps

<CardGroup cols={2}>
  <Card title="List Datamarts" icon="list" href="/developer-docs/helpers/api-reference/list-datamarts">
    View all datamarts in your organization
  </Card>

  <Card title="Delete Datamart" icon="trash" href="/developer-docs/helpers/api-reference/delete-datamart">
    Remove datamarts you no longer need
  </Card>

  <Card title="Embed a Pre-built Dashboard/Metric" icon="code" href="/developer-docs/helpers/api-reference/create-embed">
    Use your datamart in embed configurations
  </Card>

  <Card title="Getting Started" icon="book" href="/">
    Learn how to get started with DataBrain embedding
  </Card>
</CardGroup>
