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

# Token

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

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 <Link href="/developer-docs/how-to-embed">web component</Link>.

<Info>`Create API key from Databrain's dashboard` that should be passed in the headers in these requests.</Info>

<Note>Guest tokens are designed for frontend embedding. Never expose your API key in frontend code — always generate tokens from your backend.</Note>

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

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

<Note>Guest tokens are free. There is no charge, metering, or purchase involved in generating them — mint as many as you need from your backend.</Note>

```json theme={"dark"}
// 200: OK
{
  "token": "..."
}
```

```json theme={"dark"}
// 400: Bad Request
{
  "error": {
    "message": "invalid dashboard id",
    "code": "<ERROR_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"
        }
      }
    }]
  }
}
```

<CardGroup cols={2}>
  <Card title="Request.json" href="/images/guides/Request.json" icon="file-arrow-down" horizontal />
</CardGroup>

### 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": ["<embed-or-dashboard-id-1>", "<embed-or-dashboard-id-2>"]
  }
}
```

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

<Panel>
  <RequestExample>
    ```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<String, Object> 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<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    ```

    ```php PHP icon="fa-brands fa-php" theme={"dark"}
    <?php
    $curl = curl_init();

    $data = [
        'clientId' => '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);
    ```
  </RequestExample>
</Panel>

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

<Warning>**Rate Limiting**: API requests are limited to prevent abuse. Implement exponential backoff for rate limited requests (429 status).</Warning>

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