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

# SQL reference

> Query Braintrust logs, experiments, and datasets with SQL. Run queries from the Query page, CLI, or API, and find your way around the SQL reference.

SQL queries in Braintrust provide a precise, standard syntax for querying Braintrust logs, experiments, and datasets. Use SQL to:

* Filter and search for relevant logs and experiments. Use [`WHERE` clauses](https://docs.braintrust.dev/reference/sql/query-structure#where) to filter individual records and [`HAVING` clauses](https://docs.braintrust.dev/reference/sql/query-structure#having-for-filtering-aggregations) to filter aggregated results after grouping.
* Create consistent, reusable queries for monitoring.
* Build automated reporting and analysis pipelines.
* Write complex queries to analyze model performance.

To understand what a filter matches before you write one, see [How filtering works](https://docs.braintrust.dev/reference/sql/filtering.md). For tips on query performance and common pitfalls, see [SQL best practices](https://docs.braintrust.dev/reference/sql/best-practices.md).

> [!NOTE]
>
> **[Self-hosted deployments](https://docs.braintrust.dev/admin/self-hosting.md)**: SQL syntax support requires data plane version v1.1.29 or later.

## Syntax styles

Braintrust supports two syntax styles: standard **SQL syntax**, and the legacy **BTQL syntax** with pipe-delimited clauses. SQL syntax is recommended for all new queries.

The parser automatically detects whether your query is SQL or BTQL:

* **SQL queries** start with `SELECT`, `WITH`, etc. followed by whitespace
* **BTQL queries** use clause syntax like `select:`, `filter:`, etc.

| SQL Clause | BTQL Clause |
| - | - |
| `SELECT ...` | `select: ...` |
| `FROM table('id', shape => 'traces')` | `from: table('id') traces` |
| `WHERE ...` | `filter: ...` |
| `GROUP BY ...` | `dimensions: ...` |
| `GROUP BY ROLLUP(...)` | `rollup: ...` |
| `GROUP BY GROUPING SETS (...)` | `grouping_sets: (...)` |
| `HAVING ...` | `final_filter: ...` |
| `TABLESAMPLE n PERCENT [SEED (seed)]` | `sample: n%` |
| `TABLESAMPLE n ROWS [SEED (seed)]` | `sample: n` |
| `ORDER BY ...` | `sort: ...` |
| `LIMIT n` | `limit: n` |
| `OFFSET '<CURSOR_TOKEN>'` | `cursor: '<CURSOR_TOKEN>'` |
| `SETTINGS key = value, ...` | `settings: key = value, ...` |

> [!NOTE]
>
> SQL syntax specifies the shape with a named parameter (e.g., `FROM experiment('id', shape => 'traces')`), while BTQL uses a trailing token (e.g., `from: experiment('id') traces`). Table aliases on top-level table functions (e.g., `FROM project_logs('id') AS t`) are reserved for future use. Aliases on subquery sources (e.g., `FROM (...) AS sub`) are required.

> [!NOTE]
>
> **Full-text search:** Use the `MATCH` infix operator for full-text search:
>
> * `WHERE input MATCH 'search term'` → `filter: input MATCH 'search term'`
> * Multiple columns require OR: `WHERE input MATCH 'x' OR output MATCH 'x'` → `filter: input MATCH 'x' OR output MATCH 'x'`

> [!WARNING]
>
> **Unsupported SQL features:** The SQL parser does not support the following. For queries that require them, use BTQL's native syntax.
>
> * `JOIN`, `UNION`/`INTERSECT`/`EXCEPT`, and window functions.
> * [Subqueries](https://docs.braintrust.dev/reference/sql/query-structure.md#subqueries) in `WHERE`, `HAVING`, `SELECT`, or `PIVOT IN` (they are supported only in `FROM`).
> * `PIVOT` with explicit value lists, subqueries, or `ORDER BY` (only `IN (ANY)` is supported).
> * `INCLUDES` and `CONTAINS` operators. For exact array membership in SQL mode, use `IN`/`NOT IN` (for example, `tags IN ('value')`), or switch to BTQL's `filter: tags INCLUDES 'value'` syntax. `MATCH` is a fuzzy approximation.

## Run SQL queries

Run SQL from the Query page, the [`bt sql`](https://docs.braintrust.dev/reference/cli/sql) CLI, or the API. All three run queries synchronously by default and return results in a single request, which times out after 30 seconds on Braintrust-hosted deployments.

On the Enterprise plan, the CLI and API can also run [async queries](https://docs.braintrust.dev/api-reference/query.md#async-queries) in the background, for large exports or well-scoped queries that still time out. Async queries can select and filter rows but can't aggregate, deduplicate, or sort them.

### Query page

To test SQL with autocomplete, validation, and a table of results, use the [** Query**](https://www.braintrust.dev/app/~/sql) page in your project. The Query page organizes your queries in a collapsible sidebar, where you can search by name, reorder by dragging, or navigate to any query from the command bar.

To run a query, click  **Run**. Select SQL in the editor to change the button to **Run selection** and execute only the selected SQL. With no selection, or a whitespace-only selection, the Query page runs the whole document.

To manage your queries:

* Click  **New query** to start another query.
* Hover over a query in the sidebar, click , and choose **Rename**, **Duplicate**, **Open in split view**, or **Delete**. **Delete** doesn't appear for your last remaining query.

**Open in split view** shows a query in a second panel beside the current one, so you can run and compare two queries side by side. Split view requires at least two queries. While split view is open, selecting a query in the sidebar opens it in the panel you last worked in. To close the split view, click  **Close split view** in the split panel header.

Duplicating a query adds a copy named `<name> (copy)` to the top of the sidebar and makes it active. The copy includes the query's chart tabs.

To chart the results of a `project_logs` query, use the chart tabs in the results panel. See [Chart a query on the Query page](https://docs.braintrust.dev/observe/dashboards/sql-charts.md#chart-a-query-in-the-sql-sandbox).

> [!WARNING]
>
> Queries live in your browser for the current organization, so they don't follow you to another browser or device, and clearing your browser data removes them. Deleting a query can't be undone.

To hand a query to a teammate, click  **Copy share link** in the Query page header. Opening the link adds the query to the recipient's Query page and selects it without running it. The address bar always reflects your active query, so you can copy it directly or refresh without losing your place.

> [!NOTE]
>
> If a `project_logs()` query is missing a range filter on `created`, `_xact_id`, `_pagination_key`, or a specific `root_span_id`/`id`, the Query page proactively warns you so you don't have to wait for a timeout to discover the issue.

### Loop

[** Loop**](https://docs.braintrust.dev/loop.md) can query your logs, experiments, and datasets with SQL and return the results in the thread, so you can ask a question in natural language without writing the query yourself.

Loop can also generate and optimize queries on the [** Query**](https://www.braintrust.dev/app/~/sql) page:

Example queries:

* "Find the most common errors in logs over the last week"
* "What are the highest scoring rows in my experiment"
* "Show me error distribution over time"
* "List all traces where latency exceeded 60 seconds"

Loop automatically populates the Query page with the generated query, runs it, and provides a text summary of the results along with suggestions for additional queries. The query stays on the Query page so you can refine it by hand.

Once you have a query on the Query page, ask Loop to refine it:

* "Update the query to show error distribution over time"
* "Add a filter to only show errors from specific models"
* "Group by user instead"

After you run selected SQL, Loop can refine or fix that selection without replacing the surrounding queries.

Each Loop thread stays with the query it started from, even if you switch to another query. If that query isn't open when Loop works on it, the Query page opens it in split view beside the query you're on.

When your query has errors, Loop can help fix them. Select **Fix with Loop** next to the error message on the Query page. Loop analyzes the issue type and context to provide targeted fixes for:

* Syntax errors
* Schema validation issues
* Field name corrections

### bt CLI

Run SQL from your terminal with [`bt sql`](https://docs.braintrust.dev/reference/cli/sql). It opens an interactive editor, accepts an inline query, or reads from stdin for scripting.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
# Interactive editor
bt sql

# Inline query
bt sql "SELECT * FROM project_logs('project-name') WHERE created > now() - interval 1 day LIMIT 5"

# FROM logs shorthand
bt sql -p project-name "SELECT * FROM logs WHERE created > now() - interval 1 day LIMIT 5"

# Pipe from a file
cat query.sql | bt sql

# Non-interactive mode
bt sql --non-interactive "SELECT count(*) FROM project_logs('project-name') WHERE created > now() - interval 1 day"
```

With a project selected through `bt switch`, `--project`, or `BRAINTRUST_DEFAULT_PROJECT`, `FROM logs` is shorthand for that project's `project_logs(...)` source. See [`bt sql`](https://docs.braintrust.dev/reference/cli/sql) for details.

On the Enterprise plan, pass `--async` to run longer queries in the background. See [Async queries](https://docs.braintrust.dev/reference/cli/sql.md#async-queries).

### API

Run SQL programmatically by sending a `POST` request to the `/btql` endpoint:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -X POST https://api.braintrust.dev/btql \
  -H "Authorization: Bearer $BRAINTRUST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT * FROM project_logs('\''your-project-id'\'') WHERE tags IN ('\''triage'\'') AND created > now() - interval 7 day LIMIT 100"}'
```

See [Query by SQL](https://docs.braintrust.dev/api-reference/query.md) for the full reference: request and response schema, parameters, output formats, pagination, and examples.

## Next steps

* Understand [how filtering works](https://docs.braintrust.dev/reference/sql/filtering.md): query shapes, span-level matching, and `ANY_SPAN()`.
* Learn the [query structure](https://docs.braintrust.dev/reference/sql/query-structure.md): clauses, data sources, data shapes, and field access.
* Look up syntax in [Functions and operators](https://docs.braintrust.dev/reference/sql/functions.md).
* Browse copy-and-run patterns in [Example queries](https://docs.braintrust.dev/reference/sql/examples.md).
* Write correct, fast queries with [SQL best practices](https://docs.braintrust.dev/reference/sql/best-practices.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.