---
title: "Create Harbor Saved Query Draft"
method: POST
path: "/api/harbors/{harbor_id}/saved-queries"
tags: ["Harbors"]
---

# Create Harbor Saved Query Draft

`POST /api/harbors/{harbor_id}/saved-queries`

## Request

- Base URL: `https://app.polytomic.com`
- URL: `https://app.polytomic.com/api/harbors/{harbor_id}/saved-queries`
- Auth: one of:
  - HTTP bearer
  - HTTP basic

Creates a stable Harbor saved query with its initial mutable draft.

Saved queries are supported only for Polytomic-managed Harbors whose backing
Connection type is `polytomic_harbor`. Customer-managed Harbor backings return
an unsupported-backing error.

The saved query receives a stable ID, but it remains absent from published
saved-query reads until an administrator publishes its initial draft.

Use `{{parameter_name}}` references in `sql_template`. Each reference must have
one scalar declaration. Validation values and defaults must match the declared
`string`, `number`, `boolean`, `date`, `timestamp`, or `uuid` type.

Unknown JSON fields, including fields inside parameter declarations, return
`400 Bad Request` before the draft is saved. Use `default_value`, not `default`,
for parameter defaults.

When you omit a parameter during execution, Polytomic uses its published
`default_value`, never its draft validation value. An omitted optional parameter
without a default binds SQL `NULL`. A required parameter allows omission when a
default exists, but rejects explicit `null` even with a default.

For a report window, use a required parameter with a default so omission selects
a useful window and explicit `null` is rejected:

```json
{"name": "days", "type": "number", "required": true, "default_value": 7}
```

## Path parameters

- `harbor_id` string, uuid, required: Unique identifier of the Harbor

## Headers

- `X-Polytomic-Version` string

## Request body

- CreateHarborSavedQueryDraftRequest
  - `change_note` string, nullable: Optional note copied to the immutable published version
  - `description` string: Business definition and usage notes. Maximum 2,000 characters.
  - `name` string, required: Human-readable saved-query name. Maximum 200 characters.
  - `owner` string: Human-readable owner label. Maximum 200 characters.
  - `parameters` HarborSavedQueryParameter[], nullable: Typed scalar parameter declarations
    - `default_value` unknown
    - `name` string, required: Template parameter name referenced as {{start_date}}
    - `required` boolean: When true, rejects explicit null during validation and execution and allows omission only when default_value is present
    - `type` 'string' | 'number' | 'boolean' | 'date' | 'timestamp' | 'uuid', required: Scalar parameter type
  - `sql_template` string, required: DuckDB SQL template using {{name}} references for bound parameters
  - `validation_values` object, nullable: Author-supplied JSON scalar values used only to validate this draft

## Response `200`

OK

- HarborSavedQueryDraftEnvelope
  - `data` HarborSavedQueryDraftResponse
    - `change_note` string, nullable: Optional draft change note
    - `created_at` string, date-time: When the draft was created
    - `created_by` string, uuid, nullable: Actor that created the draft. Null for the system actor.
    - `created_by_type` string: Type of actor that created the draft
    - `description` string: Draft business definition
    - `id` string, uuid: Unique identifier of this mutable draft candidate
    - `name` string: Draft name
    - `owner` string: Draft owner label
    - `parameters` HarborSavedQueryParameter[], nullable: Draft typed parameter declarations
      - `default_value` unknown
      - `name` string, required: Template parameter name referenced as {{start_date}}
      - `required` boolean: When true, rejects explicit null during validation and execution and allows omission only when default_value is present
      - `type` 'string' | 'number' | 'boolean' | 'date' | 'timestamp' | 'uuid', required: Scalar parameter type
    - `saved_query_id` string, uuid: Stable saved-query identifier
    - `sql_template` string: Draft SQL template
    - `updated_at` string, date-time: When the draft was last replaced
    - `updated_by` string, uuid, nullable: Actor that last replaced the draft. Null for the system actor.
    - `updated_by_type` string: Type of actor that last replaced the draft
    - `validation_values` object, nullable: Author-supplied validation inputs

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found
- `422`: Unprocessable Entity
- `500`: Internal Server Error

## Changes

- **2026-10-22** `d80b0fdea14e`: 1 breaking, 15 warning, 1 info
  - the `data` response's property type changed from `object` to no type for status `200`
  - removed the optional property `data/change_note` from the response with the `200` status
  - removed the optional property `data/created_at` from the response with the `200` status
  - removed the optional property `data/created_by` from the response with the `200` status
  - …13 more
- **2026-09-14** `21557a3c149d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/polytomic/apis/polytomic-api/changes/api/harbors/:harbor_id/saved-queries/post.md)

---

[API](https://skmtc.dev/polytomic/apis/polytomic-api.md) - [All operations](https://skmtc.dev/polytomic/apis/polytomic-api/llms.txt) - [OpenAPI document](https://skmtc.dev/polytomic/apis/polytomic-api/revisions/3c88180d2470?raw)
