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

# Predefined Queries

> Named, parameterized queries with public endpoints

Predefined queries let you create named queries that can be executed via public endpoints without authentication. Define a query once with optional parameters, then expose it as a public API for frontend apps or third-party consumers.

## Creating a Predefined Query

Use `client.createQuery()` to define a named query with an optional set of parameters.

```typescript theme={null}
await client.createQuery({
  name: 'active_users_by_country',
  source_collection: 'users',
  base_query: {
    find: { status: { is: 'active' } },
    select: { email: true, name: true, country: true }
  },
  parameters: [
    {
      name: 'country',
      field_path: 'country',
      required: true,
      description: 'Filter by country code'
    },
    {
      name: 'limit',
      field_path: 'limit',
      default: 10,
      description: 'Max results to return'
    }
  ],
  description: 'Get active users filtered by country'
});
```

### Parameter Options

Each entry in the `parameters` array accepts:

| Field         | Type      | Description                                                  |
| ------------- | --------- | ------------------------------------------------------------ |
| `name`        | `string`  | Parameter name, used as the URL query parameter              |
| `field_path`  | `string`  | Field path in the query (e.g., `"market"` or `"price.$gte"`) |
| `default`     | `any`     | Default value when the parameter is not provided             |
| `required`    | `boolean` | If `true`, the parameter must be supplied at execution time  |
| `description` | `string`  | Human-readable description of the parameter                  |

### Advanced Options

`createQuery` also supports optional metadata fields for documentation purposes:

```typescript theme={null}
await client.createQuery({
  name: 'top_products',
  source_collection: 'products',
  base_query: {
    find: { in_stock: { is: true } },
    sort: ['-rating'],
    select: { name: true, rating: true, price: true }
  },
  parameters: [
    { name: 'category', field_path: 'category', required: false, default: 'all' }
  ],
  description: 'Top rated products by category',
  version: 1,
  example_request: { category: 'electronics' },
  example_response: [{ name: 'Widget', rating: 4.9, price: 29.99 }]
});
```

## Executing a Query

Use `client.executeQuery()` to run a predefined query. This calls a **public endpoint** -- no authentication is required.

```typescript theme={null}
const result = await client.executeQuery(
  'active_users_by_country',  // query name
  { country: 'US' },          // parameters
  1                            // version (optional)
);

console.log(result.data);          // Array of matching records
console.log(result.count);         // Number of records
console.log(result.query_time_ms); // Execution time in milliseconds
```

The response follows the `QueryDataResponse` format:

```typescript theme={null}
interface QueryDataResponse {
  success: boolean;
  query_name: string;
  data: any[];
  count: number;
  query_time_ms: number;
}
```

### Public API Endpoint

Under the hood, `executeQuery` calls:

```
GET /api/queries/{app_id}/{query_name}/data?country=US&v=1
```

This endpoint requires no API key, so you can call it directly from a browser or any HTTP client.

## Managing Queries

### List All Queries

```typescript theme={null}
const queries = await client.listQueries();
// Returns: QueryDefinition[]
```

Each `QueryDefinition` includes:

```typescript theme={null}
interface QueryDefinition {
  name: string;
  source_collection: string;
  base_query: any;
  parameters?: QueryParameter[];
  created_at: string;
  description?: string;
}
```

### Get a Single Query

```typescript theme={null}
const query = await client.getQuery('active_users_by_country');
console.log(query.name);              // 'active_users_by_country'
console.log(query.source_collection); // 'users'
console.log(query.parameters);        // Array of QueryParameter
```

### Delete a Query

```typescript theme={null}
const result = await client.deleteQuery('active_users_by_country');
// result: { success: boolean }
```

## Use Cases

* **Public API endpoints** -- Expose curated data from your collections without sharing app keys.
* **Parameterized queries for frontends** -- Let client-side code fetch data with query parameters, while the server controls the base query shape and accessible fields.
* **Rate-limited data access** -- Provide controlled read access to third parties without granting full API credentials.
* **Versioned queries** -- Use the `version` parameter to maintain backward compatibility when updating query logic.

## Next Steps

<CardGroup cols={2}>
  <Card title="SQL Interface" icon="code" href="/querying/sql">
    Query and insert data using SQL syntax
  </Card>

  <Card title="Query Builder" icon="magnifying-glass" href="/querying/query-builder">
    Fluent query API with type-safe conditions
  </Card>
</CardGroup>
