# Import a dashboard

Creates a new dashboard from an exported JSON.

[endpoint]
base_url = "https://telemetry.betterstack.com"
path = "/api/v2/dashboards/import"
method = "POST"

[[body_param]]
name = "name"
description = "A name for the new dashboard."
required = true
type = "string"

[[body_param]]
name = "data"
description = "The dashboard configuration data in JSON format, typically obtained from the [Export dashboard](https://betterstack.com/docs/logs/api/dashboards/export/) endpoint."
required = true
type = "object"

[[body_param]]
name = "team_name"
description = "Required if using [global API token](https://betterstack.com/docs/logs/api/getting-started/#get-a-global-api-token) to specify the team which should own the resource"
required = false
type = "string"

[[header]]
name = "Authorization"
description = "Bearer `$TOKEN`"
required = true
type = "string"

[[header]]
name = "Content-Type"
description = "application/json"
required = true
type = "string"
[/endpoint]

[responses]
[[response]]
status = 201
description = "The dashboard was successfully created and the import process has been queued."
body = '''
{
  "data": {
    "id": "5678",
    "type": "dashboard",
    "attributes": {
      "team_id": 123456,
      "team_name": "example-team",
      "name": "My Imported Dashboard",
      "dashboard_group_id": null,
      "refresh_interval": 60,
      "date_range_from": "now-24h",
      "date_range_to": "now",
      "created_at": "2026-01-20T15:05:00.000Z",
      "updated_at": "2026-01-20T15:05:00.000Z"
    }
  }
}
'''

[[response]]
status = 401
description = "Invalid or missing authentication token."

[[response]]
status = 422
description = "Validation failed because of missing required attributes."
body = '''
{
  "errors": "Sorry, you are missing some required attributes",
  "required_attributes": [
    "name",
    "data"
  ]
}
'''
[/responses]

[note]
The response to a successful import contains a minimal representation of the dashboard. It does not reflect the final configuration of all imported items like charts and sections, as the full import is processed asynchronously.
[/note]

## Example request

[code-tabs]
```shell
[label Reading from saved JSON]
curl --request POST \
     --url "https://telemetry.betterstack.com/api/v2/dashboards/import" \
     --header "Authorization: Bearer $TOKEN" \
     --header "Content-Type: application/json" \
     --data '{
       "name": "My Imported Dashboard",
       "data": '"$(cat my_dashboard_template.json || echo "{}")"'
     }'
```
```shell
[label Example with literal JSON]
curl --request POST \
     --url "https://telemetry.betterstack.com/api/v2/dashboards/import" \
     --header "Authorization: Bearer $TOKEN" \
     --header "Content-Type: application/json" \
     --data '{
       "name": "My Imported Dashboard",
       "data": {
         "refresh_interval": 60,
         "date_range_from": "now-24h",
         "date_range_to": "now",
         "preset": {
           "preset_type": "implicit",
           "preset_variables": [
             {
               "name": "source",
               "variable_type": "source",
               "values": []
             }
           ]
         },
         "charts": [
           {
             "chart_type": "line_chart",
             "name": "Logs by level",
             "description": null,
             "x": 0,
             "y": 0,
             "w": 6,
             "h": 8,
             "transform_with": "async (existingDataByQuery, newDataByQuery, completed) => {\n  return Object.keys(newDataByQuery).reduce((result, queryIndex) => {\n    result[queryIndex] = result[queryIndex].concat(newDataByQuery[queryIndex]);\n    return result;\n  }, existingDataByQuery);\n}\n",
             "settings": {
               "unit": "shortened",
               "fresh": true,
               "label": "shown_below",
               "legend": "shown_below",
               "stacking": "dont_stack",
               "time_column": "time",
               "x_axis_type": "time",
               "y_axis_scale": "linear",
               "series_colors": {
                 "level = info": "#55bfc1",
                 "level = error": "#c03a5a"
               },
               "series_column": "series",
               "value_columns": ["value"],
               "decimal_places": 2,
               "point_size_column": "size",
               "treat_missing_values": "connected"
             },
             "chart_queries": [
               {
                 "name": null,
                 "query_type": "query_builder",
                 "sql_query": "SELECT\n  {{time}} AS time,\n  countMerge(events_count) AS value,\n  '"'"'level = '"'"' || COALESCE(level, '"'"'null'"'"') AS series\nFROM {{source}}\nWHERE\n  dt BETWEEN {{start_time}} AND {{end_time}}\nGROUP BY\n  time,\n  level",
                 "where_condition": null,
                 "static_text": null,
                 "y_axis": [
                   {
                     "name": "events",
                     "type": "integer",
                     "value": "events",
                     "measure": "count"
                   }
                 ],
                 "filters": [],
                 "group_by": [
                   {
                     "name": "level",
                     "type": "string",
                     "value": "level"
                   }
                 ],
                 "source_variable": null
               }
             ],
             "chart_alerts": [
               {
                 "name": "Spike in errors",
                 "alert_type": "relative",
                 "operator": "increases_by",
                 "value": 50.0,
                 "query_period": 3600,
                 "confirmation_period": 0,
                 "recovery_period": 7200,
                 "escalation_target": "current_team",
                 "name_autogenerated": false,
                 "aggregation_interval": 300,
                 "source_mode": "source_variable",
                 "source_platforms": [],
                 "metadata": {},
                 "check_period": 600,
                 "incident_per_series": false,
                 "shown_interval": 86400
               }
             ]
           }
         ],
         "sections": []
       }
     }'
```
[/code-tabs]

## Data structure reference

### Top-level fields

| Field | Type | Description |
|-------|------|-------------|
| `refresh_interval` | integer | Refresh interval in seconds |
| `date_range_from` | string | Start time expression, e.g., "now-3h", "2023-01-01" |
| `date_range_to` | string | End time expression, e.g., "now", "2023-01-02" |
| `source_eligibility_sql` | string/null | SQL filter determining which sources can use this dashboard |
| `preset` | object | Dashboard variables configuration object |
| `charts` | array | Array of chart configuration objects |
| `sections` | array | Array of dashboard section objects |

### Preset fields

| Field | Type | Description |
|-------|------|-------------|
| `id` | integer | Unique preset identifier |
| `name` | string/null | Human-readable preset name |
| `preset_type` | string | Type of preset, e.g. "implicit" |
| `preset_variables` | array | Array of variable configuration objects |

### Preset variable fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Variable name used in queries |
| `variable_type` | string | Input type: "select\_value", "datetime", "source", "text" |
| `values` | array | Current selected values |
| `default_values` | array | Default/fallback values |
| `sql_definition` | string/null | SQL query to dynamically generate options |

### Chart fields

| Field | Type | Description |
|-------|------|-------------|
| `chart_type` | string | Chart type: "line\_chart", "table\_chart", "bar\_chart", "number\_chart", "scatter\_chart", "heatmap\_chart", "tail\_chart" |
| `name` | string | Chart display title |
| `description` | string/null | Optional chart description |
| `x` | integer | Grid column 0-based position |
| `y` | integer | Grid row 0-based position |
| `w` | integer | Chart width in grid units |
| `h` | integer | Chart height in grid units |
| `transform_with` | string | JavaScript function to transform data before rendering |
| `finalize_with` | string | JavaScript function called after all data arrives |
| `settings` | object | Chart-specific display and behavior settings |
| `chart_queries` | array | Array of data query configurations |
| `chart_alerts` | array | Array of alert rule configurations |

### Chart query fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string/null | Query name/identifier |
| `query_type` | string | Query type: "sql\_expression", "query\_builder", "tail\_query" |
| `sql_query` | string | The actual SQL query string |
| `where_condition` | string | Additional WHERE clause logic: "AND", "OR" |
| `static_text` | string/null | Static text replacement in queries |
| `y_axis` | array/object | Y-axis configuration for query builder |
| `filters` | array | Additional filter conditions |
| `group_by` | array | GROUP BY column specifications |
| `source_variable` | string | Variable name for dynamic source selection |

### Chart alert fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Alert rule name |
| `alert_type` | string | Alert type: "threshold", "anomaly", etc. |
| `metric` | string | Metric to monitor, e.g. "avg(response_time)"|
| `operator` | string | Comparison operator: ">", "<", "==", etc. |
| `value` | number | Threshold value for triggering |
| `query_period` | integer | Time window for checking in seconds |
| `confirmation_period` | integer | Additional confirmation time |
| `recovery_period` | integer | Time before auto-recovery |
| `escalation_target` | string | Who to notify for alerts |
| `name_autogenerated` | boolean | Whether name was auto-generated |
| `aggregation_interval` | integer | Data aggregation period |
| `source_mode` | string | Source selection mode |
| `source_platforms` | array | Allowed source platforms |
| `metadata` | object | Additional alert metadata |
| `check_period` | integer | How often to check the alert |
| `incident_per_series` | boolean | Whether to create separate incidents per series |
| `shown_interval` | string | Display interval for alert |

### Section fields

| Field | Type | Description |
|-------|------|-------------|
| `name` | string | Section display name |
| `y` | integer | Vertical position in dashboard grid |
| `collapsed` | boolean | Whether section is collapsed by default |

## Chart settings reference

The `settings` object varies by chart type but commonly includes:

### All charts

| Field | Type | Description |
|-------|------|-------------|
| `unit` | string | Display unit: "auto", "ms", "B_iec", "%", etc. |
| `legend` | string | Legend position: "shown_below", "hidden" |
| `ttl_cache` | string | Cache TTL: "auto", duration |
| `decimal_places` | integer | Number of decimal places to show |

### Line and bar charts

| Field | Type | Description |
|-------|------|-------------|
| `time_column` | string | Column containing time data |
| `x_axis_type` | string | X-axis type: "time", "category" |
| `y_axis_scale` | string | Y-axis scale: "linear", "log" |
| `series_column` | string | Column for grouping series |
| `value_columns` | array | Columns containing values |
| `stacking` | string | Bar stacking: "dont_stack", "stacked" |
| `treat_missing_values` | string | How to handle gaps: "connected", "show_gaps" |

### Table charts

| Field | Type | Description |
|-------|------|-------------|
| `table_width` | integer | Table width in pixels |
| `column_widths` | object | Custom column widths |
| `percentage_highlight_columns` | array | Columns to highlight as percentages |

### Number charts

| Field | Type | Description |
|-------|------|-------------|
| `max` | number | Maximum value for gauge |
| `min` | number | Minimum value for gauge |
| `label` | string | Label position: "shown_below", "hidden" |
| `selected_series` | string | Which series to display |
| `point_size_column` | string | Column for point sizing |

### Map and scatter charts

| Field | Type | Description |
|-------|------|-------------|
| `lat_column` | string | Latitude column name |
| `lng_column` | string | Longitude column name |
| `point_size_column` | string | Column for point sizing |
| `selected_series` | string | Active series filter |