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

# Update a saved view



## OpenAPI

````yaml https://api.select.dev/v2/openapi.json patch /saved-views/{saved_view_id}
openapi: 3.1.0
info:
  title: SELECT API (v2)
  version: 0.1.0
servers:
  - url: https://api.select.dev/v2
    description: SELECT API v2
security: []
tags:
  - name: metrics
    description: >-
      Query cost and usage data across Snowflake, BigQuery, Databricks and
      Tableau. Each route is `POST /v2/metrics/<model>/query` for one semantic
      model. Every route takes the same body shape and returns the same response
      shape. Each route page gives guidance on when to use the route, and worked
      examples.


      ## Body shape


      | Field | Meaning |

      | --- | --- |

      | `measures` | Aggregates to compute, for example `sum_spend`. |

      | `dimensions` | Fields to group by. Each one is returned on every row. |

      | `filter_expression` | An `and`/`or` tree of filters on dimensions,
      applied before aggregation. |

      | `measure_filters` | Filters on measures, applied after aggregation. |

      | `sort` | The order of the rows: `[{"field": "sum_spend", "direction":
      "desc"}]`. |

      | `limit` | The maximum number of rows. Results are not paginated: `limit`
      cuts the result short, and there is no next page. Omit `limit` to get all
      rows. |

      | `aggregate` | Set `false` to list the rows with no grouping. See
      "Listing rows". |


      v2 accepts only `filter_expression`. The body refuses the legacy `filters`
      list.


      ## Filter on dates


      Filter on the `day` field. Use two filters (both bounds are inclusive):


      ```json

      {"operator": "and", "filters": [
        {"field": "day", "operator": ">=", "value": "2026-08-01"},
        {"field": "day", "operator": "<=", "value": "2026-08-31"}], "limit": 1000}
      ```


      Or use one relative filter: `{"field": "day", "operator": "in range",
      "value": "30D"}`. The values are `{N}D` and `{N}M` (the last N days or
      months, today included), `WTD`, `MTD`, `QTD`, `YTD`, and `LMTD` (the whole
      previous calendar month).


      - Do not filter on `hour`, `week`, `month` or `quarter` to bound a range.
      Filter on `day`, and use the coarser fields as dimensions.

      - A timestamp such as `start_time <= "2026-08-31"` compares to midnight
      and drops most of that day. Use `day`, or `start_time < "2026-09-01"`.

      - A snapshot route (for example `snowflake-storage-summary`) describes the
      current state, and a `day` filter does not bound its size and cost fields.
      On routes that join the snapshot to activity, `day` bounds only the
      activity fields. Each route page says which fields these are.


      ## Which measure is cost


      - `sum_spend` (or `spend`, or `cost` on some routes) is the dollar cost in
      the filtered period. Use it for "how much did we spend".

      - `*_annualized` measures extend the spend of the filtered period to a
      year: a `7D` range gives that week's spend times 365 / 7. They are
      projections, not spend.

      - On snapshot routes, `annual_cost`, `*_monthly_cost` and `*_annual_cost`
      are the current rate extended to a month or a year. A date range does not
      bound them.

      - Do not present any of these run-rates as spend in a period.

      - Databricks routes also give DBUs (for example `sum_task_usage`). DBUs
      are not dollars.


      The `spend` route is the consolidated cost of every platform. Use it for
      totals, trends and breakdowns by service. Use a platform route to explain
      what inside the platform caused the cost.


      ## Text values are case-sensitive


      Filter values must match the stored case. A value in the wrong case
      matches no rows, with no error. For example:


      - On `spend`, `connection_type` is `Snowflake`, `Bigquery` or
      `Databricks`, and `"snowflake"` matches nothing.

      - On `search`, `data-freshness` and `workload-metadata-suggestions`,
      `connection_type` is lowercase: `snowflake`, `bigquery`, `databricks`.

      - On `snowflake-workloads`, most `resource_type` values are lowercase keys
      (`query_pattern`, `dbt`), but the AI types are title case (`Cortex
      Analyst`).


      ## Usage groups


      A usage group set divides cost into named groups, such as departments or
      teams. To group by the groups of one set, name the set in `path`:


      ```json

      {"dimensions": [{"field": "usage_group", "path": ["Department"]}],
      "limit": 1000}

      ```


      `path[0]` is the name of the set, not its ID. A plain `"usage_group"`
      dimension groups by every set at once. The same `{"field": ..., "path":
      [...]}` form reads keys of other semi-structured fields, for example
      workload metadata.


      ## Period over period


      Some routes publish `<measure>_previous_period`, `change_<measure>` and
      `percent_change_<measure>`. These measures need one bounded date range on
      `day`, at the top level of `filter_expression`:


      - Use two bounds on `day`, or one `in range` filter. Do not mix the two
      forms.

      - Do not nest the date filter in a sub-expression, and do not bound the
      range with `month` or `quarter`.

      - The previous period is the same number of days, just before the range.
      For `QTD` on 2026-09-28 (2026-07-01 to 2026-09-28, 90 days), the previous
      period is 2026-04-02 to 2026-06-30, not the previous calendar quarter.


      ## Listing rows


      Set `"aggregate": false` and name only `dimensions` to get the rows as
      they are, for example the individual queries that ran longer than ten
      minutes. If the body also names `measures` or `measure_filters`, the route
      aggregates, with no error. Always set a `limit` on a listing.


      ## Default scoping filters


      Some tables hold more than one kind of row, and the SELECT app filters to
      one kind by default. Each route page names these filters. For example:


      - `snowflake-query-patterns`: `{"field": "resource_type", "operator":
      "in", "values": ["query_pattern"]}`. `bigquery-query-patterns` filters
      `workload_type` to `bigquery_query_pattern`, and
      `databricks-query-patterns` filters `resource_type` to
      `databricks_query_pattern`.

      - `snowflake-dbt`: `{"field": "dbt_node_resource_type", "operator": "=",
      "value": "model"}`. Without it, tests, seeds and snapshots rank with
      models. The same filter applies to `bigquery-dbt-queries` and
      `databricks-dbt-queries`.


      ## Teams


      Send `X-Team-Id` to evaluate a query as a team you belong to. The rows are
      then limited to what the team's roles can reach.


      ## Which route answers which question


      | Question | Route |

      | --- | --- |

      | Total spend, spend trend, spend by platform, service or usage group |
      `spend` |

      | Most expensive Snowflake warehouses | `snowflake-workloads` (or
      `snowflake-warehouses` for metering spend) |

      | Warehouse utilization, idle spend, cluster usage |
      `snowflake-warehouses`, `snowflake-warehouse-clusters` |

      | Query latency, spillage and bytes scanned on a warehouse |
      `snowflake-warehouse-query-performance` |

      | Most expensive recurring queries | `snowflake-query-patterns` |

      | Individual queries | `snowflake-queries` |

      | Cost of dbt models, and of dbt runs | `snowflake-dbt`,
      `snowflake-dbt-invocations` |

      | Cost of tasks, stored procedures, dynamic tables | `snowflake-tasks`,
      `snowflake-stored-procedures`, `snowflake-dynamic-tables` |

      | Cost of BI tools (Looker, Mode, Hex, Sigma, Periscope, Tableau) |
      `snowflake-looker`, `snowflake-mode`, `snowflake-hex`, `snowflake-sigma`,
      `snowflake-periscope`, `tableau-queries` |

      | Cost of Fivetran, and of workloads defined by query tags |
      `snowflake-fivetran`, `snowflake-custom-workloads` |

      | Serverless, automatic clustering and Snowpipe cost |
      `snowflake-serverless`, `snowflake-automatic-clustering`,
      `snowflake-snowpipe` |

      | Storage cost in a period | `snowflake-storage`, `bigquery-storage-spend`
      |

      | Largest or unused tables now | `snowflake-storage-summary`,
      `bigquery-storage-summary` |

      | Which workloads read or write a table | `lineage-workloads`,
      `lineage-tables`, `lineage-edges` |

      | BigQuery cost by project, job or query pattern | `bigquery-projects`,
      `bigquery-jobs`, `bigquery-query-patterns` |

      | BigQuery reservations and commitments | `bigquery-reservation-timeline`,
      `bigquery-commitments`, `bigquery-commitment-scopes` |

      | Databricks cost by job, query, SQL warehouse or cluster |
      `databricks-jobs`, `databricks-queries`, `databricks-sql-warehouses`,
      `databricks-clusters` |

      | Savings from SELECT actions | `action-realized-savings` |

      | How current the data is | `data-freshness` |
paths:
  /saved-views/{saved_view_id}:
    patch:
      tags:
        - saved-views
      summary: Update a saved view
      operationId: update_saved_view_route_saved_views__saved_view_id__patch
      parameters:
        - name: saved_view_id
          in: path
          required: true
          schema:
            type: string
            title: Saved View Id
        - name: If-Match
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              The saved view's current ETag, required to guard against a
              concurrent update.
            title: If-Match
          description: >-
            The saved view's current ETag, required to guard against a
            concurrent update.
        - name: x-tenant-id
          in: header
          required: true
          schema:
            type: string
            description: The organization ID the request is scoped to.
            title: X-Tenant-Id
          description: The organization ID the request is scoped to.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SavedViewUpdateV2'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SavedViewV2'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '408':
          $ref: '#/components/responses/RequestTimeout'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - HTTPBearer: []
components:
  schemas:
    SavedViewUpdateV2:
      properties:
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: Display name.
        params:
          anyOf:
            - type: string
            - type: 'null'
          title: Params
          description: Serialized parameters.
        icon:
          anyOf:
            - type: string
            - type: 'null'
          title: Icon
          description: >-
            Identifier of an icon from SELECT's icon set, e.g. `Storage` or
            `CircleStar`. Not validated against the set; an unrecognized value
            falls back to a default icon in the UI.
        color:
          anyOf:
            - type: string
            - type: 'null'
          title: Color
          description: >-
            Color name, e.g. `Red`, `Green`, or `Blue` (not a hex code). Not
            validated against a fixed palette; an unrecognized value falls back
            to a default color in the UI.
        team_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Team Id
          description: Team to assign this view to.
        is_personal:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Personal
          description: Whether this is a personal view.
      additionalProperties: false
      type: object
      title: SavedViewUpdate
      description: |-
        A merge patch: an omitted field leaves it unchanged, and `null` clears
        it. The URL a saved view represents cannot be changed after creation.
    SavedViewV2:
      properties:
        id:
          type: string
          title: Id
          description: The unique identifier of the saved view.
          readOnly: true
          x-terraform-computed: true
        etag:
          type: string
          title: Etag
          description: >-
            Opaque strong ETag for this saved view. Matches the `ETag` response
            header, and changes whenever any field on the saved view changes.
          readOnly: true
          x-terraform-computed: true
        url:
          type: string
          title: Url
          description: The URL path this saved view represents.
        name:
          type: string
          title: Name
          description: Display name for the saved view.
        params:
          type: string
          title: Params
          description: Serialized filter/query parameters.
        icon:
          anyOf:
            - type: string
            - type: 'null'
          title: Icon
          description: >-
            Identifier of an icon from SELECT's icon set, e.g. `Storage` or
            `CircleStar`. Not validated against the set; an unrecognized value
            falls back to a default icon in the UI.
        color:
          anyOf:
            - type: string
            - type: 'null'
          title: Color
          description: >-
            Color name, e.g. `Red`, `Green`, or `Blue` (not a hex code). Not
            validated against a fixed palette; an unrecognized value falls back
            to a default color in the UI.
        team_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Team Id
          description: Team that owns this view, if team-scoped.
        email_address:
          anyOf:
            - type: string
            - type: 'null'
          title: Email Address
          description: Owner email, if this is a personal view.
          readOnly: true
          x-doit-confidentiality: customer-data
          x-doit-pii: true
          x-terraform-computed: true
        is_personal:
          type: boolean
          title: Is Personal
          description: Whether this is a personal view, owned only by `email_address`.
          readOnly: true
          x-terraform-computed: true
        created_by:
          anyOf:
            - type: string
            - type: 'null'
          title: Created By
          description: Email of the user who created this view.
          readOnly: true
          x-doit-confidentiality: customer-data
          x-doit-pii: true
          x-terraform-computed: true
        updated_by:
          anyOf:
            - type: string
            - type: 'null'
          title: Updated By
          description: Email of the user who last updated this view.
          readOnly: true
          x-doit-confidentiality: customer-data
          x-doit-pii: true
          x-terraform-computed: true
        create_time:
          type: string
          title: Create Time
          description: When the saved view was created.
          readOnly: true
          x-terraform-computed: true
        update_time:
          type: string
          title: Update Time
          description: When the saved view was last changed.
          readOnly: true
          x-terraform-computed: true
        team:
          anyOf:
            - $ref: '#/components/schemas/TeamProperties'
            - type: 'null'
          description: Team details, when the view is team-scoped.
        view_type:
          type: string
          title: View Type
          description: 'The ownership type: Public, Personal, or Team.'
          readOnly: true
          x-terraform-computed: true
        page:
          type: string
          title: Page
          description: The page segment of the view URL.
          readOnly: true
          x-terraform-computed: true
      type: object
      required:
        - id
        - etag
        - url
        - name
        - params
        - is_personal
        - create_time
        - update_time
        - view_type
        - page
      title: SavedView
    TeamProperties:
      properties:
        name:
          type: string
          title: Name
        is_all_users:
          type: boolean
          title: Is All Users
        default_member_role:
          $ref: '#/components/schemas/TeamRoleEnum'
        sso_groups:
          items:
            $ref: '#/components/schemas/SSOGroup'
          type: array
          title: Sso Groups
        id:
          type: string
          format: uuid
          title: Id
        organization_id:
          type: string
          title: Organization Id
        permission_entity:
          $ref: '#/components/schemas/PermissionEntityWithDisplayName'
      type: object
      required:
        - name
        - is_all_users
        - default_member_role
        - sso_groups
        - id
        - organization_id
        - permission_entity
      title: TeamProperties
      description: Schema for an existing team without joined properties.
    ProblemDetail:
      additionalProperties: true
      description: >-
        RFC 9457-style error payload, served as ``application/problem+json``.


        ``code`` is the stable, machine-readable identifier — consumers branch
        on it,

        never on ``title``. ``type`` stays ``about:blank``: we keep no per-error

        documentation pages. There is no ``instance``/request-id member (we
        don't run

        access logs). See the flat error-code catalogue in §4 of the standards
        doc.
      properties:
        type:
          default: about:blank
          title: Type
          type: string
        title:
          type: string
          title: Title
        status:
          title: Status
          type: integer
        detail:
          title: Detail
          type: string
        code:
          title: Code
          type: string
        retryable:
          title: Retryable
          type: boolean
        details:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          default: null
          title: Details
      required:
        - title
        - status
        - detail
        - code
        - retryable
      title: ProblemDetail
      type: object
    TeamRoleEnum:
      type: string
      enum:
        - admin
        - editor
        - viewer
      title: TeamRoleEnum
      description: |-
        Defines the permission level of a user within a team:
        - ADMIN: Administers the team — its settings and the roles held on it
        - EDITOR: Manages team resources, creates and modifies shared items
        - VIEWER: Reads team resources with limited interaction capabilities
    SSOGroup:
      properties:
        sso_group_name:
          type: string
          title: Sso Group Name
        role:
          $ref: '#/components/schemas/TeamRoleEnum'
      type: object
      required:
        - sso_group_name
        - role
      title: SSOGroup
      description: Represents an SSO Group mapping for automatic team membership
    PermissionEntityWithDisplayName:
      properties:
        type:
          $ref: '#/components/schemas/PermissionEntityType'
        id:
          type: string
          title: Id
        display_name:
          type: string
          title: Display Name
        usage_group_details:
          anyOf:
            - $ref: '#/components/schemas/UsageGroupDetails'
            - type: 'null'
        parent_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Parent Id
      type: object
      required:
        - type
        - id
        - display_name
      title: PermissionEntityWithDisplayName
      description: >-
        Permission entity with a human readable display name.


        Args:
            type: The type of the entity. `usage_group`, `snowflake_account`,
                `snowflake_organization`, `databricks_account`, `databricks_connection`,
                `team`, or `select_organization`.
            id: The id of the entity. The `usage_group_id`, `snowflake_account_uuid`,
                `snowflake_organization_name`, `databricks_account_id`,
                `databricks_conn_id`, `team_id`, or `organization_id`.
            display_name: A human readable name for the entity. Typically colon delimited.
                On this class the property is required.
            usage_group_details: Optional details about the usage group. Only included in
                serialization when type is USAGE_GROUP.

        Note that the hashing and equality check are done based on the `type`
        and `id` fields

        as per the `PermissionEntity` class. This means that even if the
        `display_name` is

        different, two `PermissionEntityWithDisplayName` instances will still
        compare equal.
    PermissionEntityType:
      type: string
      enum:
        - select_organization
        - snowflake_organization
        - snowflake_account
        - databricks_account
        - databricks_connection
        - bigquery_connection
        - aws_account
        - tableau_site
        - team
        - usage_group
      title: PermissionEntityType
      description: >-
        The type of the permission entity.


        Comparison operations are supported to understand the level in the
        hierarchy of

        the type.


        NOTE: The object hierarchy is not linear. SELECT Organizations are still
        at the

        top, but teams and usage groups are effectively the same level, but will
        return

        false if compared.


        Hierarchy (see ``grants.CONTAINS`` for the authoritative tree):

        SELECT_ORGANIZATION

        ├── SNOWFLAKE_ORGANIZATION

        │   └── SNOWFLAKE_ACCOUNT

        │       └── USAGE_GROUP

        ├── DATABRICKS_ACCOUNT

        │   └── DATABRICKS_CONNECTION

        ├── BIGQUERY_CONNECTION

        ├── AWS_ACCOUNT

        ├── TABLEAU_SITE

        ├── TEAM

        │   └── USAGE_GROUP

        └── USAGE_GROUP
    UsageGroupDetails:
      properties:
        set_name:
          type: string
          title: Set Name
        group_name:
          type: string
          title: Group Name
      type: object
      required:
        - set_name
        - group_name
      title: UsageGroupDetails
      description: |-
        Details about a usage group entity.

        This is only populated when the entity type is USAGE_GROUP.
  responses:
    BadRequest:
      description: Bad request
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Unauthorized:
      description: Unauthorized
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      headers:
        WWW-Authenticate:
          description: Authentication challenge for the requested resource.
          required: true
          schema:
            type: string
    Forbidden:
      description: Forbidden
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    NotFound:
      description: Not found
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    MethodNotAllowed:
      description: Method not allowed
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      headers:
        Allow:
          description: HTTP methods supported by the requested resource.
          required: true
          schema:
            type: string
    RequestTimeout:
      description: Request Timeout
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Conflict:
      description: Conflict
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    PreconditionFailed:
      description: Precondition failed
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    ValidationFailed:
      description: Validation failed
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    PreconditionRequired:
      description: Precondition required
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    RateLimited:
      description: Rate limited
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      headers:
        Retry-After:
          description: Number of seconds to wait before retrying the request.
          required: true
          schema:
            type: integer
            minimum: 0
    InternalError:
      description: Internal error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    ServiceUnavailable:
      description: Service unavailable
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      headers:
        Retry-After:
          description: Number of seconds to wait before retrying the request.
          required: true
          schema:
            type: integer
            minimum: 0
  securitySchemes:
    HTTPBearer:
      type: http
      description: Organization API key (sl_…).
      scheme: bearer

````