Saved Queries

A saved query is a named, persisted record of an SQL query bound to a connection. It backs dashboard tiles and provides a stable reference for queries you want to reuse across users in your organization.

Required scope: query:execute for all operations. update and delete are additionally restricted to the saved query’s creator.

Visibility

Each saved query has a visibility value that controls who can see it:

VisibilityWho can see it
private (default)The creator only.
orgAnyone authenticated for the organization.
embedAnyone authenticated for the organization, plus embed contexts.

sql and connection_id are immutable after creation. To change them, create a new saved query and delete the old one.

List

GET /api/v1/saved-queries

Returns saved queries the caller can see — their own private rows plus everything visibility=org or visibility=embed for the organization. Admins see all rows including other users’ private ones.

List by dashboard

GET /api/v1/dashboards/{dashboard_id}/saved-queries

Returns the id and name of every saved query referenced by a tile on the given dashboard. Use this to discover the saved-query IDs powering a dashboard you already know — typically before calling POST /saved-queries/{id}/execute to pull the underlying data.

Tiles backed by ad-hoc inquiry turns are skipped. Soft-deleted saved queries are skipped. Results are de-duplicated when the same saved query backs multiple tiles. Standard dashboard read permissions apply (admins see everything in the org; dashboard-only users see only assigned dashboards).

Response

{
  "saved_queries": [
    { "id": "5f1c7e3a-…", "name": "Revenue by region" },
    { "id": "8a4b9d12-…", "name": "Active users (7d)" }
  ],
  "total": 2
}

Create from SQL

POST /api/v1/saved-queries

Returns 201 with the created saved query.

Request body

FieldTypeRequiredDescription
sqlstringYesThe SQL to persist
connection_idstring (UUID)YesConnection the SQL targets
namestringYesHuman-readable label, max 200 chars
descriptionstringNoLong-form description
visibility"private" | "org" | "embed"NoDefault "private"

Example

curl -X POST https://app.answerlayer.io/api/v1/saved-queries \
  -H "X-API-Key: $ANSWERLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Top customers by revenue",
    "sql": "SELECT customer_id, SUM(amount) FROM orders GROUP BY customer_id ORDER BY 2 DESC LIMIT 10",
    "connection_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "visibility": "org"
  }'

Create from an inquiry turn

POST /api/v1/saved-queries/from-inquiry-turn

Promotes the SQL the agent generated for an existing inquiry turn into a saved query. Useful for “save this answer” UX after a user finds a question they want to keep.

Request body

FieldTypeRequiredDescription
inquiry_turn_idstring (UUID)YesThe turn whose SQL to promote
namestringYesHuman-readable label, max 200 chars
descriptionstringNoLong-form description
visibility"private" | "org" | "embed"NoDefault "private"

The connection is inherited from the turn’s session.

Read

GET /api/v1/saved-queries/{saved_query_id}

Returns 404 if the row doesn’t exist or the caller’s visibility doesn’t include it.

Execute

POST /api/v1/saved-queries/{saved_query_id}/execute

Resolves the saved query, then runs its SQL against its connection in one call. Same response shape as POST /api/v1/query/{connection_id} — use this when you’d otherwise have to GET the saved query and then POST to /query/{connection_id} yourself.

The connection_id and sql come from the saved query record, not the request body.

Returns 404 if the saved query is missing or the caller’s visibility doesn’t include it, or if the underlying connection has been deleted. The audit log records resource_type=saved_query, resource_id=<saved_query_id> so the saved query is the audit subject — not a free-form SQL string.

Request body

FieldTypeRequiredDescription
paramsobjectNoOptional parameter map for parameterized queries
row_limitintNoCaps the rows returned. Default 1000, max 10000.
timeoutintNoSeconds. Default 30, max 120.

Example

curl -X POST https://app.answerlayer.io/api/v1/saved-queries/$SAVED_QUERY_ID/execute \
  -H "X-API-Key: $ANSWERLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"row_limit": 100}'

Update

PATCH /api/v1/saved-queries/{saved_query_id}

Partial update. Only name, description, and visibility are mutable.

Only the saved query’s owner or an organization admin may update it.

Delete

DELETE /api/v1/saved-queries/{saved_query_id}

Soft-deletes the row. Saved queries referenced by dashboard tiles remain referenced; the tile starts returning a not found error until the reference is updated. Returns 204.

Only the owner or an organization admin may delete.