From e73a3cf199c5b1e76b3bbfe894070e78ec6bc908 Mon Sep 17 00:00:00 2001 From: "kolbeyang@gmail.com" Date: Tue, 5 May 2026 12:16:21 +0000 Subject: [PATCH] LAM-1551: document SQL API as a dedicated page Adds `/platform/sql-api` covering the `POST /v1/sql/query` endpoint with auth, request/response shape, parameterized-query example, and curl / Python / TypeScript SDK snippets (`client.sql.query`). Links the new page from the SQL Editor API bullet, the viewing-traces next-steps card, and the "Query across traces" list on every integration page that previously listed "SQL API" as an unlinked bullet. Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 2 +- docs.json | 1 + platform/sql-api.mdx | 167 +++++++++++++++++++++ platform/sql-editor.mdx | 2 +- platform/viewing-traces.mdx | 2 +- tracing/integrations/claude-agent-sdk.mdx | 2 +- tracing/integrations/deepagents.mdx | 2 +- tracing/integrations/mastra.mdx | 2 +- tracing/integrations/openai-agents-sdk.mdx | 2 +- tracing/integrations/opencode.mdx | 2 +- tracing/integrations/pydantic-ai.mdx | 2 +- tracing/integrations/vercel-ai-sdk.mdx | 2 +- 12 files changed, 178 insertions(+), 10 deletions(-) create mode 100644 platform/sql-api.mdx diff --git a/CLAUDE.md b/CLAUDE.md index 5186438..5e5df97 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,7 +56,7 @@ This is a Mintlify site. Pages are `.mdx`, navigation lives in `docs.json`, reus - `grep "[em-dash]" ` before committing. Em dashes should not appear in docs prose; they sneak in easily from copy-paste. `` strings are a frequent source — prefer a colon over an em dash inside captions. - `grep -E "seamless|powerful|unleash|cutting-edge|best-in-class|revolutionary|supercharge"` returns banned marketing words. -- Every integration page needs the three forward links in data-flow order: viewing traces, then Signals, then SQL access. The "Query across traces" bullet list on integration pages enumerates **four** channels in a fixed order: `[SQL editor](/platform/sql-editor)` → `SQL API` → `[CLI](/platform/cli)` (`lmnr-cli sql query`) → `[MCP server](/platform/mcp)`. Keep all four on any new integration page; omitting the CLI or MCP row drifts pages out of sync. +- Every integration page needs the three forward links in data-flow order: viewing traces, then Signals, then SQL access. The "Query across traces" bullet list on integration pages enumerates **four** channels in a fixed order: `[SQL editor](/platform/sql-editor)` → `[SQL API](/platform/sql-api)` → `[CLI](/platform/cli)` (`lmnr-cli sql query`) → `[MCP server](/platform/mcp)`. Keep all four on any new integration page; omitting the CLI or MCP row drifts pages out of sync. - The **Track outcomes with Signals** section on every tracing integration page must frame Signals as the *cross-trace* layer, not a "extract stuff from one trace" feature. The template: contrast traces (*what happened on this run*) with Signals (*how often / when / which runs* — the question that only makes sense across many traces), explain that a Signal pairs a plain-language prompt with a JSON output schema, mention Triggers (live) and Jobs (backfill), and finish with the `[query](/platform/sql-editor), [cluster](/signals/clusters), and [alert](/signals/alerts)` inline-bold triplet. Always include a `` about the Failure Detector Signal shipped with every new project. The "extracts matching events across your history and every new trace" wording from prior versions understates what Signals do — don't revert to it. ## Example code conventions diff --git a/docs.json b/docs.json index 741b324..4c40b4d 100644 --- a/docs.json +++ b/docs.json @@ -121,6 +121,7 @@ "platform/debugger", "platform/mcp", "platform/sql-editor", + "platform/sql-api", "platform/cli", "platform/search", "custom-dashboards/overview", diff --git a/platform/sql-api.mdx b/platform/sql-api.mdx new file mode 100644 index 0000000..4645e0a --- /dev/null +++ b/platform/sql-api.mdx @@ -0,0 +1,167 @@ +--- +title: SQL API +--- + +Query your Laminar data programmatically over HTTP. The SQL API is the same SQL surface as the [SQL Editor](/platform/sql-editor), the [CLI](/platform/cli), and the [MCP server](/platform/mcp), exposed as a single REST endpoint so scripts, pipelines, and services can pull spans, traces, signals, and evaluations directly from your project. + +## Endpoint + +``` +POST https://api.lmnr.ai/v1/sql/query +``` + +For self-hosted deployments, replace the base URL with your instance (for example, `http://localhost:8000/v1/sql/query`). + +## Authenticate + +Every request is authorized with a project API key in the `Authorization` header: + +``` +Authorization: Bearer +``` + +Grab one from **Settings → Project API Keys** in the Laminar dashboard. The key scopes the query to its project automatically; you do not need a project id or tenant filter in the request or the `WHERE` clause. + +## Request and response + +Request body: + +```json +{ + "query": "SELECT name, duration FROM spans WHERE start_time > now() - INTERVAL 1 HOUR LIMIT 20", + "parameters": { } +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `query` | `string` | ClickHouse SQL. `SELECT` only. | +| `parameters` | `object` | Optional. Map of typed parameters referenced from the query (e.g. `{evaluation_id: "..."}` matches `{evaluation_id:UUID}` in the query). | + +Response body: + +```json +{ + "data": [ + { "name": "openai.chat", "duration": 1.23 }, + { "name": "tool.search", "duration": 0.41 } + ] +} +``` + +`data` is an array of rows, each row a JSON object keyed by column name. Errors return a non-`2xx` status with `{"error": "..."}`. + +## Examples + + + + ```bash + curl -X POST https://api.lmnr.ai/v1/sql/query \ + -H "Authorization: Bearer $LMNR_PROJECT_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT name, total_cost FROM spans WHERE span_type = {span_type:String} AND start_time > now() - INTERVAL 1 DAY LIMIT 10", + "parameters": { "span_type": "LLM" } + }' + ``` + + + The `LaminarClient` in the `lmnr` Python SDK exposes the SQL API as `client.sql.query(...)`: + + ```python + from lmnr import LaminarClient + + client = LaminarClient(project_api_key="") + + rows = client.sql.query( + "SELECT name, total_cost FROM spans " + "WHERE span_type = 'LLM' AND start_time > now() - INTERVAL 1 DAY " + "LIMIT 10" + ) + + for row in rows: + print(row["name"], row["total_cost"]) + ``` + + Parameterized queries pass typed placeholders in the SQL and a matching dict: + + ```python + rows = client.sql.query( + "SELECT id, scores FROM evaluation_datapoints " + "WHERE evaluation_id = {evaluation_id:UUID}", + parameters={"evaluation_id": "98765432-1098-4654-9210-987654321098"}, + ) + ``` + + The async variant `AsyncLaminarClient` exposes the same `client.sql.query(...)` method and returns a coroutine. + + + The `LaminarClient` in `@lmnr-ai/lmnr` exposes the SQL API as `client.sql.query(...)`: + + ```typescript + import { LaminarClient } from "@lmnr-ai/lmnr"; + + const client = new LaminarClient({ + projectApiKey: process.env.LMNR_PROJECT_API_KEY, + }); + + const rows = await client.sql.query( + "SELECT name, total_cost FROM spans " + + "WHERE span_type = 'LLM' AND start_time > now() - INTERVAL 1 DAY " + + "LIMIT 10", + ); + + for (const row of rows) { + console.log(row.name, row.total_cost); + } + ``` + + Parameterized queries pass typed placeholders in the SQL and a matching object: + + ```typescript + const rows = await client.sql.query( + "SELECT id, scores FROM evaluation_datapoints " + + "WHERE evaluation_id = {evaluation_id:UUID}", + { evaluation_id: "98765432-1098-4654-9210-987654321098" }, + ); + ``` + + + +## What you can query + +The API queries the same logical tables as the SQL Editor: `spans`, `traces`, `signal_events`, `signal_runs`, `logs`, `dataset_datapoints`, `dataset_datapoint_versions`, and `evaluation_datapoints`. See [SQL Editor](/platform/sql-editor) for the full schema reference, example queries, and ClickHouse-specific tips (time filters, JSON extraction, tuple fields). + + +Only `SELECT` queries are allowed. Queries are scoped to the project associated with the API key; cross-project access is not possible. + + +## Self-hosted + +Swap the base URL for your instance and (optionally) a custom port: + +```bash +curl -X POST http://localhost:8000/v1/sql/query \ + -H "Authorization: Bearer $LMNR_PROJECT_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"query": "SELECT count() FROM traces WHERE start_time > now() - INTERVAL 1 DAY"}' +``` + +The Python and TypeScript SDK clients accept `baseUrl` / `base_url` (and `port`) so you can point them at a self-hosted app-server. + +## What's next + + + + Full schema reference, writing-queries guide, and example queries. + + + Run the same SQL from your terminal with `lmnr-cli sql query`. + + + Let Claude Code, Cursor, or Codex query Laminar directly. + + + `LaminarClient` reference for Python and TypeScript. + + diff --git a/platform/sql-editor.mdx b/platform/sql-editor.mdx index ee15894..12ce24a 100644 --- a/platform/sql-editor.mdx +++ b/platform/sql-editor.mdx @@ -33,7 +33,7 @@ Results appear in a table or raw JSON view. Export results to a dataset or label You can also query from outside the UI: -- **API**: `POST /v1/sql/query` — authenticate with your project API key and pass `{ "query": "..." }`. +- **API**: `POST /v1/sql/query` — see [SQL API](/platform/sql-api) for the endpoint, auth, and Python / TypeScript examples. - **CLI**: `lmnr-cli sql query "" --json` — see [CLI](/platform/cli). - **MCP**: connect an MCP client (Claude Code, Cursor, Codex) and call `query_laminar_sql` — see [MCP Server](/platform/mcp). diff --git a/platform/viewing-traces.mdx b/platform/viewing-traces.mdx index ad112a9..e250bea 100644 --- a/platform/viewing-traces.mdx +++ b/platform/viewing-traces.mdx @@ -134,6 +134,6 @@ Use SQL Editor when you need precise filtering, aggregation, or auditing on the Turn outcomes and failures you see in the transcript into structured events you can query and alert on. - Use the SQL editor, SQL API, [CLI](/platform/cli), or [MCP server](/platform/mcp) to slice every span, event, and signal across your traces. + Use the [SQL editor](/platform/sql-editor), [SQL API](/platform/sql-api), [CLI](/platform/cli), or [MCP server](/platform/mcp) to slice every span, event, and signal across your traces. diff --git a/tracing/integrations/claude-agent-sdk.mdx b/tracing/integrations/claude-agent-sdk.mdx index 518b31d..b52f6f9 100644 --- a/tracing/integrations/claude-agent-sdk.mdx +++ b/tracing/integrations/claude-agent-sdk.mdx @@ -240,7 +240,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code, Cursor, Codex, or any MCP-aware client. diff --git a/tracing/integrations/deepagents.mdx b/tracing/integrations/deepagents.mdx index e1808db..4abf8e1 100644 --- a/tracing/integrations/deepagents.mdx +++ b/tracing/integrations/deepagents.mdx @@ -258,7 +258,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code, Cursor, or Codex. diff --git a/tracing/integrations/mastra.mdx b/tracing/integrations/mastra.mdx index 729ee15..a15d4d7 100644 --- a/tracing/integrations/mastra.mdx +++ b/tracing/integrations/mastra.mdx @@ -238,7 +238,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar from Claude Code, Cursor, or Codex. diff --git a/tracing/integrations/openai-agents-sdk.mdx b/tracing/integrations/openai-agents-sdk.mdx index b49427a..6f46c7f 100644 --- a/tracing/integrations/openai-agents-sdk.mdx +++ b/tracing/integrations/openai-agents-sdk.mdx @@ -510,7 +510,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code, Cursor, Codex, or any MCP-aware client. diff --git a/tracing/integrations/opencode.mdx b/tracing/integrations/opencode.mdx index 63070ad..fc82927 100644 --- a/tracing/integrations/opencode.mdx +++ b/tracing/integrations/opencode.mdx @@ -166,7 +166,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar directly from OpenCode, Claude Code, Cursor, or Codex. diff --git a/tracing/integrations/pydantic-ai.mdx b/tracing/integrations/pydantic-ai.mdx index 2bfed94..a923309 100644 --- a/tracing/integrations/pydantic-ai.mdx +++ b/tracing/integrations/pydantic-ai.mdx @@ -156,7 +156,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code, Cursor, or Codex. diff --git a/tracing/integrations/vercel-ai-sdk.mdx b/tracing/integrations/vercel-ai-sdk.mdx index c0bbefc..05f6731 100644 --- a/tracing/integrations/vercel-ai-sdk.mdx +++ b/tracing/integrations/vercel-ai-sdk.mdx @@ -277,7 +277,7 @@ Every new project ships with a **Failure Detector** Signal that categorizes issu ## Query across traces - **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. +- **[SQL API](/platform/sql-api)** for programmatic access from scripts and pipelines. - **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. - **[MCP server](/platform/mcp)** to query Laminar from Claude Code, Cursor, or Codex.