# Create an exploration

Creates a new exploration, including its chart, queries, and variables.

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

[[body_param]]
name = "name"
description = "The name of the exploration. This is also set as the chart's name."
required = true
type = "string"

[[body_param]]
name = "chart"
description = "An object defining the chart's type and settings. `chart_type` is required."
required = true
type = "object"

[[body_param]]
name = "queries"
description = "An array of one or more query objects. At least one query is required."
required = true
type = "array"

[[body_param]]
name = "date_range_from"
description = "The start of the exploration's date range."
required = false
type = "string"
default = "now-3h"

[[body_param]]
name = "date_range_to"
description = "The end of the exploration's date range."
required = false
type = "string"
default = "now"

[[body_param]]
name = "exploration_group_id"
description = "The ID of an exploration group to organize this exploration. Use `0` to remove it from a group."
required = false
type = "integer"

[[body_param]]
name = "variables"
description = "An array of custom query variable objects. Default variables (`time`, `start_time`, `end_time`, `source`) are created automatically if not provided."
required = false
type = "array"

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

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

[responses]
[[response]]
status = 201
description = "The exploration was created successfully."
body = '''
{
  "data": {
    "id": "123",
    "type": "exploration",
    "attributes": {
      "name": "Error Rate Analysis",
      "date_range_from": "now-3h",
      "date_range_to": "now",
      "exploration_group_id": 456,
      "created_at": "2026-02-20T10:00:00Z",
      "updated_at": "2026-02-20T10:00:00Z",
      "chart": {
        "chart_type": "line_chart",
        "description": "Shows error rates across all services",
        "settings": {
          "unit": "number",
          "decimal_places": 0,
          "legend": "bottom",
          "stacking": "dont_stack"
        }
      },
      "queries": [
        {
          "id": 1,
          "name": "Main Query",
          "query_type": "sql_expression",
          "sql_query": "SELECT {{time}} AS time, count(*) AS value FROM {{source}} WHERE time BETWEEN {{start_time}} AND {{end_time}} GROUP BY time",
          "source_variable": "source"
        }
      ],
      "variables": [
        {
          "name": "time",
          "variable_type": "datetime",
          "default_values": []
        },
        {
          "name": "start_time",
          "variable_type": "datetime",
          "default_values": []
        },
        {
          "name": "end_time",
          "variable_type": "datetime",
          "default_values": []
        },
        {
          "name": "source",
          "variable_type": "source",
          "default_values": ["123"]
        }
      ]
    }
  }
}
'''

[[response]]
status = 422
description = "Validation failed due to invalid parameters."
body = '''
{
  "errors": "Sorry, some values are incorrect",
  "invalid_values": {
    "chart.name": ["can't be blank"]
  }
}
'''
[/responses]

## Example request

```shell
[label cURL]
curl --request POST \
  --url https://telemetry.betterstack.com/api/v2/explorations \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Error Rate Analysis",
    "date_range_from": "now-3h",
    "date_range_to": "now",
    "exploration_group_id": null,
    "chart": {
      "chart_type": "line_chart",
      "description": "Shows error rates across all services",
      "settings": {
        "unit": "number",
        "decimal_places": 0,
        "legend": "bottom",
        "stacking": "dont_stack"
      }
    },
    "queries": [
      {
        "name": "Main Query",
        "query_type": "sql_expression",
        "sql_query": "SELECT {{time}} AS time, count(*) AS value\nFROM {{source}}\nWHERE time BETWEEN {{start_time}} AND {{end_time}}\n  [[ AND JSONExtractString(raw, '\''level'\'') = {{level}} ]]\nGROUP BY time",
        "source_variable": "source"
      }
    ],
    "variables": [
      {
        "name": "source",
        "variable_type": "source",
        "default_values": ["123"]
      },
      {
        "name": "level",
        "variable_type": "multi_select_with_sql",
        "values": [],
        "default_values": [],
        "sql_definition": "JSONExtractString(raw, '\''level'\'')"
      }
    ]
  }'
```

## Chart and query compatibility

Not all query types are compatible with all chart types. Use this matrix to ensure you are using a valid combination.

| Chart Type | `sql_expression` | `tail_query` | `static_text` | `funnel_query` (read-only) |
|---|:---:|:---:|:---:|:---:|
| `line_chart` | Yes | Yes | - | - |
| `bar_chart` | Yes | Yes | - | - |
| `number_chart` | Yes | Yes | - | - |
| `table_chart` | Yes | - | - | - |
| `pie_chart` | Yes | - | - | - |
| `gauge_chart` | Yes | Yes | - | - |
| `tail_chart` | - | Yes | - | - |
| `static_text_chart` | - | - | Yes | - |
| `text_chart` | Yes | Yes | - | - |
| `scatter_chart` | Yes | - | - | - |
| `heatmap_chart` | Yes | - | - | - |
| `map_chart` | Yes | - | - | - |
| `anomalies_chart` | - | Yes | - | - |
| `funnel_chart` | - | - | - | Yes |

## Charts

Single object defining the exploration chart.

- `chart_type` - The type of chart. Choose one of:
  - `line_chart` - Only `line_chart` supports multiple queries. All other chart types accept only a single query.
  - `bar_chart`
  - `pie_chart`
  - `scatter_chart`
  - `gauge_chart`
  - `number_chart`
  - `heatmap_chart`
  - `table_chart`
  - `map_chart`
  - `text_chart`
  - `tail_chart`
  - `anomalies_chart`
  - `static_text_chart`
- `description` - detailed explanation shown as a tooltip.
- `settings` - JSON used for chart-specific settings such as customizing units.

## Queries

Each object in the `queries` array defines a data source for the chart.

- `query_type` - The type of query. Choose one of:
  - `sql_expression` for querying using SQL.
  - `tail_query` for Log filtering query, similar to Live tail.
  - `static_text` for static markdown text.
- `sql_query` - The SQL query string. Required for `sql_expression` type.
- `source_variable` - The name of the `source` type variable to use for this query. Defaults to `source`, but can also point to different sources using `source:table_name`.
- `where_condition` - The query string for filtering. Required for `tail_query` type.
- `static_text` - The markdown content. Required for `static_text` type.

[info]
Read-only query types (`query_builder`, `pql_expression`, and `funnel_query`) cannot be created or modified via the API as they require client-side compilation to SQL.
[/info]

## Variables

Each object in the `variables` array defines a new variable. See [Query variables](https://betterstack.com/docs/logs/dashboards/variables/) for details.

Default variables (`time`, `start_time`, `end_time`, `source`) are created automatically.

- `name` - Name of the variable, without the `{{}}`.
- `variable_type` - Type of the variable, one of the following:
- `values` - Values currently saved in the preset.
  - `source` is a data source reference, `values` are source IDs.
  - `string`
  - `number`
  - `date`
  - `datetime`
  - `boolean`
  - `sql_expression` for raw SQL expressions, added to the query without escaping.
  - `select_value`
  - `select_with_sql` requires `sql_definition` parameter.
  - `multi_select_with_sql` requires `sql_definition` parameter.
- `default_values` - Default values defined in the variable itself.
