---
id: CAP-PFM-QRY-006
title: Save and share reusable questions
feature: FEAT-PFM-QRY-02
product_area: platform
module: queries
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-RPT-QRY-009
  - CAP-RPT-QRY-011
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - >-
    services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
    requested change)
  - 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D2'
  - 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D4'
  - 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D10'
purpose: >-
  Keep useful questions available to their authors and chosen audiences without extending anyone’s data
  permissions.
outcomes:
  - Stored questions can be reused.
  - Customer-private work remains owner-only.
  - Audience changes account for dependent reports.
concepts:
  - CON-PFM-QRY-002
actors:
  - ACT-PFM-013
  - ACT-PFM-014
  - ACT-PFM-007
  - ACT-PFM-015
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.saved-queries.read
    where_checked: api
    scope: tenant
  - key: platform.saved-queries.use
    where_checked: api
    scope: tenant
  - key: platform.saved-queries.share
    where_checked: service
    scope: record
  - key: platform.saved-queries.manage
    where_checked: service
    scope: record
  - key: <application>.<dataset>.query (the owner's key)
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-PFM-QRY-006-01
    proved_by: [ATS-PFM-QRY-006-01, TST-PFM-QRY-234]
    statement: >-
      A private saved query is visible only to its owner among customer users; colleagues and customer
      managers receive not-found responses.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#tells a manager the same thing, as
      404
    origin: >-
      services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
      requested change)
  - id: BR-CAP-PFM-QRY-006-02
    proved_by: [ATS-PFM-QRY-006-02, ATS-PFM-QRY-006-17, ATS-PFM-QRY-007-12, TST-PFM-QRY-234]
    statement: >-
      Role-shared queries are visible to their owners, managers and current active holders of a selected role;
      other users neither list nor open them.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#answers not found for a role the
      caller does not hold, and excludes the record from the list [E2E-SQ-09]
    origin: none
  - id: BR-CAP-PFM-QRY-006-03
    proved_by: [ATS-PFM-QRY-006-03, TST-PFM-QRY-231]
    statement: >-
      The library’s read permission allows listing, opening and running shared queries, while use is required
      for creation, replacement and deletion, so Read Only staff cannot write.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/read-tier.e2e.spec.js#is refused creating a saved query with
      403
    origin: 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D10'
  - id: BR-CAP-PFM-QRY-006-04
    proved_by: [ATS-PFM-QRY-006-04, TST-PFM-QRY-234]
    statement: >-
      Changing between private and organization visibility requires share permission, which is included by
      default for users allowed to save queries.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses making the query the
      organization’s without the power to share it as 403
    origin: >-
      services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
      requested change)
  - id: BR-CAP-PFM-QRY-006-05
    proved_by: [ATS-PFM-QRY-006-05, TST-PFM-QRY-234]
    statement: >-
      The owner can maintain a query, and managers can maintain shared queries, while customer managers cannot
      reach private queries.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a colleague editing the
      organization’s query as 403
    origin: >-
      services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
      requested change)
  - id: BR-CAP-PFM-QRY-006-06
    proved_by: [ATS-PFM-QRY-006-06, TST-PFM-QRY-413]
    statement: >-
      Rhythm staff using a workspace staff grant can read and maintain every saved query, including
      customer-private queries.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/unit/services/saved-queries/saved-query-access.spec.ts#lets
      staff write a colleague’s private query, which a non-staff caller may not
    origin: 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D4'
  - id: BR-CAP-PFM-QRY-006-07
    proved_by: [ATS-PFM-QRY-006-07, TST-PFM-QRY-234]
    statement: >-
      Role sharing accepts one to one hundred distinct active workspace roles, replaces the complete selected
      set, and excludes archived roles from membership matches.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#replaces the whole selected-role
      set rather than appending to it [E2E-SQ-07]
    origin: none
  - id: BR-CAP-PFM-QRY-006-08
    proved_by: [ATS-PFM-QRY-006-08, ATS-PFM-QRY-006-18, ATS-PFM-QRY-011-14, TST-PFM-QRY-231, TST-PFM-QRY-345]
    statement: >-
      Query audience narrowing is refused when a dependent report or dashboard would have a wider audience,
      with the blocking reports and owners identified.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-narrowing.integration.spec.js#refuses
      narrowing it to private with 409 saved_query_narrower_than_reports, naming the report
    origin: 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D2'
  - id: BR-CAP-PFM-QRY-006-09
    proved_by: [ATS-PFM-QRY-006-09, TST-PFM-QRY-231, TST-PFM-QRY-345]
    statement: >-
      A save preserves omitted visibility and preserves existing role selections when role visibility is
      supplied without a replacement set.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-narrowing.integration.spec.js#keeps
      a role-shared query’s visibility and roles when the save states no visibility
    origin: 'services-platform:docs/milestones/plans/RPT-M1-plan.md#D2'
  - id: BR-CAP-PFM-QRY-006-10
    proved_by: [ATS-PFM-QRY-002-18, ATS-PFM-QRY-005-18, ATS-PFM-QRY-006-10, ATS-PFM-QRY-008-11, TST-PFM-QRY-234]
    statement: >-
      Saving validates the definition for the saver without running it, refusing unauthorized or missing
      datasets and collecting the remaining definition problems.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a body whose definition
      cannot be run as written as 400
    origin: >-
      services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
      requested change)
  - id: BR-CAP-PFM-QRY-006-11
    proved_by: [ATS-PFM-QRY-006-11, TST-PFM-QRY-234]
    statement: >-
      The saved definition retains its exact values, fits within 64 KiB, and identifies the same dataset as
      its query record.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#leaves a criterion’s value exactly
      as the person typed it, spaces and all
    origin: >-
      services-platform:docs/queries/saved-queries-and-recipes.md#2026-10-11 — Final acceptance (after the
      requested change)
  - id: BR-CAP-PFM-QRY-006-12
    proved_by: [ATS-PFM-QRY-006-12, TST-PFM-QRY-234]
    statement: >-
      Saved-query names are unique for each owner within a workspace after case and surrounding-space
      normalization, while other owners or workspaces can reuse them.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a create whose name
      normalizes to one the owner already has, naming the trimmed proposed name as 400 [E2E-SQ-01]
    origin: none
  - id: BR-CAP-PFM-QRY-006-13
    proved_by: [ATS-PFM-QRY-006-13, TST-PFM-QRY-234]
    statement: >-
      Replacement requires the version previously read, rejects a missing version and reports a conflict when
      it is stale.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a replacement at a version
      that is no longer in force as 409
    origin: none
  - id: BR-CAP-PFM-QRY-006-14
    proved_by: [ATS-PFM-QRY-006-14, ATS-PFM-QRY-006-19, ATS-PFM-QRY-015-17, TST-PFM-QRY-233, TST-PFM-QRY-349]
    statement: >-
      A saved query used by a report, dashboard or schedule cannot be deleted, and the refusal identifies its
      dependencies.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses to delete a saved query a report
      presents as 409 saved_query_reported
    origin: >-
      services-platform:docs/migrations/query-scheduling-exports/README.md#D3. A schedule runs a pinned copy
      of the saved query (snapshot), and says when the saved query has changed
  - id: BR-CAP-PFM-QRY-006-15
    proved_by: [ATS-PFM-QRY-006-15, TST-PFM-QRY-234]
    statement: >-
      Library pages, counts and facets exclude colleagues’ private queries, while opening a query reports its
      current reader-specific problems rather than rejecting the entire read.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#leaves a colleague’s private query
      out of the numbered page too
    origin: none
scenarios:
  - id: SC-CAP-PFM-QRY-006-01
    given: A shared report depends on an organization-visible query.
    when: The author attempts to make the query private.
    then: The save is refused and the existing audience remains.
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-narrowing.integration.spec.js#leaves
      the query as it was after the refusal
  - id: SC-CAP-PFM-QRY-006-02
    given: A query has selected-role visibility.
    when: A save retains role visibility without supplying new roles.
    then: The stored role selection is preserved.
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-narrowing.integration.spec.js#keeps
      the roles when the save states "roles" and no roleIds
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-QRY-002
related:
  - CAP-PFM-QRY-007
  - CAP-PFM-QRY-011
  - CAP-PFM-QRY-015
journeys:
  - JNY-PFM-QRY-001
  - JNY-PFM-QRY-002
open_questions: []
operations:
  - createSavedQuery
  - listSavedQueries
  - getSavedQuery
  - updateSavedQuery
  - deleteSavedQuery
tables:
  - saved-queries.table.ts
  - saved-query-shared-roles.table.ts
evidence:
  - 'Pinned reference: services-platform:docs/migrations/query-scheduling-exports/README.md'
  - 'Pinned reference: services-platform:docs/milestones/plans/RPT-M1-plan.md'
  - 'Pinned reference: services-platform:docs/queries/saved-queries-and-recipes.md'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/read-tier.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/reports.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-narrowing.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/unit/services/saved-queries/saved-query-access.spec.ts
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-02-01, FAS-PFM-QRY-02-02, FAS-PFM-QRY-02-03, FAS-PFM-QRY-02-04, FAS-PFM-QRY-02-05, FAS-PFM-QRY-04-02, FAS-PFM-QRY-05-03]
suites: [TST-PFM-QRY-231, TST-PFM-QRY-233, TST-PFM-QRY-234, TST-PFM-QRY-345, TST-PFM-QRY-349, TST-PFM-QRY-413]
---

# Save and share reusable questions

## Purpose

Keep useful questions available to their authors and chosen audiences without extending anyone’s data permissions.

## How It Works

Staff save a question under a name so they can return to it. The stored definition has an owner and an audience. Colleagues find only the queries their audience and library access permit. Reading a stored query reports problems that may now prevent it from running. Changing it validates the definition again for the saver. Customer managers maintain shared work while private work stays with its owner. Reports and schedules can depend on the query. Narrowing or deletion therefore checks those dependencies and explains what must be changed first.

## Relationships

The saved-question library supplies definitions for execution, reports, dashboards and schedules.
