---
title: "Save a query"
method: POST
path: "/queries"
tags: ["Queries"]
---

# Save a query

`POST /queries`

## Request

- Base URL: `https://saturnsql.com/api`
- URL: `https://saturnsql.com/api/queries`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Saves a query for reuse, optionally filed into a folder with `folderPath` (null = root). Available to API keys with the `write` scope. Sharing a query company-wide is plan-gated and done in the web app.

The fields below are the whole create surface: `description` and `chart` are ignored if sent. The saved query is immediately readable at `/app/report/{id}`, where the result shape decides the chart.

## Request body

- object
  - `name` string, required
  - `sql` string, required
  - `connectionId` string: Optional; the connection this query targets
  - `folderPath` string, nullable: A single flat folder label, not a nested path ("A/B" is one label); null = root
  - `variables` QueryVariable[]: Declarations for the `{{name}}` placeholders in `sql`. Omit or send [] when there are none.
    - `name` string, required: Matches `[A-Za-z_][A-Za-z0-9_]*`
    - `type` 'date' | 'text' | 'number' | 'boolean' | 'dropdown', required
    - `required` boolean: An empty value for a required variable is a 422, not an empty substitution.
    - `default` object, nullable: Used when the value is absent. A `relative` default is only valid on a `date` variable and resolves against the caller time zone (or the schedule time zone).
      - `kind` 'fixed' | 'relative'
      - `value` string: Literal for `fixed`; one of today, yesterday, 7_days_ago, 30_days_ago, 90_days_ago, start_of_this_month, start_of_last_month, end_of_last_month, start_of_this_year for `relative`.
    - `options` string[]: Dropdown only, non-empty. A value outside this list is a 422.

## Response `201`

Saved

- SavedQuery
  - `id` string
  - `name` string
  - `sql` string
  - `connectionId` string, nullable
  - `folderPath` string, nullable: A single flat folder label (not a nested path); "A/B" is one folder named "A/B", not "A" containing "B". null = root.
  - `isShared` boolean
  - `description` string, nullable: Subtitle on the report page. Returned by GET /queries; nothing can set it yet, so always null.
  - `chart` ChartSpec: How a report should be drawn. Stored verbatim and interpreted at render time, since the columns a spec refers to only exist after a run: a spec naming a column the SELECT list no longer returns falls back to the shape-derived guess rather than failing. With no spec stored, the result shape decides — see the "saved query is also a report page" section of the API guide for the rules an agent should write SQL against.
    - `type` 'line' | 'area' | 'bar' | 'scatter' | 'share' | 'number' | 'none', required: `none` suppresses the chart for good, which is why it is distinct from a null `chart`. `share` is never guessed and must be set explicitly: its shape is identical to `bar` and nothing in the data says which is meant.
    - `x` string: Column for the x axis or the category. Absent for `number`.
    - `series` string[]: Measure columns, in order. Capped at 3: the validated palette separates three series by lightness and a fourth has no colour.
    - `group` string: Low-cardinality column splitting a scatter into groups.
  - `userId` string
  - `variables` QueryVariable[]: Declared `{{name}}` variables, in first-appearance order in the SQL. Empty when the query has none.
    - `name` string, required: Matches `[A-Za-z_][A-Za-z0-9_]*`
    - `type` 'date' | 'text' | 'number' | 'boolean' | 'dropdown', required
    - `required` boolean: An empty value for a required variable is a 422, not an empty substitution.
    - `default` object, nullable: Used when the value is absent. A `relative` default is only valid on a `date` variable and resolves against the caller time zone (or the schedule time zone).
      - `kind` 'fixed' | 'relative'
      - `value` string: Literal for `fixed`; one of today, yesterday, 7_days_ago, 30_days_ago, 90_days_ago, start_of_this_month, start_of_last_month, end_of_last_month, start_of_this_year for `relative`.
    - `options` string[]: Dropdown only, non-empty. A value outside this list is a 422.
  - `createdAt` string, date-time
  - `updatedAt` string, date-time

## Other responses

- `400`: Validation failed
- `401`: Bad or missing credentials
- `403`: Saved-query limit reached (plan)

---

[API](https://skmtc.dev/saturnsql/apis/saturnsql-api.md) · [All operations](https://skmtc.dev/saturnsql/apis/saturnsql-api/llms.txt) · [OpenAPI document](https://skmtc.dev/saturnsql/apis/saturnsql-api/revisions/90a3e54ad115?raw)
