Skip to content

Query Templates

Templates let agents and clients call named operations instead of writing raw QQL. Variables use {name} syntax. JWT claims are available as {claims.<field>}.

Enable templates
qql-go serve --templates templates.yaml
templates:
search_docs:
description: "Search documents"
query: "QUERY '{query}' FROM docs LIMIT {limit} USING HYBRID"
search_medical:
description: "Search medical records by specialty"
query: "QUERY '{query}' FROM medical LIMIT {limit} WHERE specialty = '{specialty}'"
tenant_scroll:
description: "Scroll caller's tenant data"
query: "SCROLL FROM docs LIMIT {limit}"
require_claims: [org_id] # JWT claims that must be present
tenant_search:
description: "Search with tenant isolation via claim"
query: "QUERY '{query}' FROM docs LIMIT {limit} WHERE org_id = '{claims.org_id}'"

Templates are invoked with a special TEMPLATE statement:

Invoke template
curl -X POST http://localhost:50051/qql.QQL/Exec
-H "Content-Type: application/json"
-H "Authorization: Bearer <jwt>"
-d '{"query": "TEMPLATE search_docs query="vector database" limit=10"}'
SyntaxSource
{variable}Request parameter
{claims.<field>}JWT claim value

Example with claim substitution:

If the JWT contains org_id = "acme-corp" and the template has:

query: "QUERY '{query}' FROM docs WHERE org_id = '{claims.org_id}' LIMIT {limit}"

The gateway resolves to:

QUERY 'search' FROM docs WHERE org_id = 'acme-corp' LIMIT 10

Templates with require_claims fail if the token is missing any listed claim:

require_claims: [org_id, department]

This ensures templates that embed claim values always have the data they need.

Templates interact with the policy engine normally:

  • The resolved QQL query is subject to all policy rules
  • AST injection (tenant filters, limit caps) applies after template resolution
  • A template that resolves to a DROP statement is still denied if the policy doesn't allow DROP