> Public product help. This page has no customer entries, projects, chat transcripts, API keys, or horizon contents.
> Reading that data requires `Authorization: Bearer` (a signed-in app session JWT, or a Headless access token).
> Do not call Supabase `/rest/v1` with a Headless JWT. Data reads go through `/casc/v1/headless/v1/rest`.

# Filter Tools

Filter tools (`tool_kind: filter`) let agents retrieve **exact matching rows** by field predicates. They do **not** use vector embeddings and do **not** return aggregates.

> **Do not skip embedding for the whole pipeline.** Filter itself does not need embeddings, but
> **search tools** on the same groups do. After ingesting or syncing data, still run
> **Initiate Embedding** (or enable Auto-embed) on linked *search* tools before significant
> LLM chat that relies on semantic search. See [tools](tools.md).

## When to use filter vs search vs analytics

| Need | Tool kind |
| --- | --- |
| Find similar text, documents, descriptions | **Search** (requires embeddings after ingest) |
| All rows where `location = USA` (exact recall) | **Filter** (no embeddings for the filter itself) |
| Sum revenue, count tickets, group by region | **Analytics** |
| Current events on the web | **Web search** |

## Call shape

Agents send AND-combined filters plus optional pagination. **One call** can match several values or several keys — do not call the tool twice.

```
{
  "filters": [
    { "key": "status", "op": "in", "value": ["NoUrlExtracted", "UrlExtractionError"] }
  ],
  "limit": 1
}
```

Two keys at once (AND):

```
{
  "filters": [
    { "key": "type", "op": "in", "value": ["contact_research", "outreach_draft"] },
    { "key": "status", "op": "eq", "value": "Pending" }
  ],
  "limit": 1
}
```

OR across different keys (one array item with `or`):

```
{
  "filters": [
    {
      "or": [
        { "key": "status", "op": "eq", "value": "NoUrlExtracted" },
        { "key": "source", "op": "eq", "value": "manual" }
      ]
    }
  ],
  "limit": 1
}
```

`filters` must be an **array** (or `{ "and": [...] }` / `{ "or": [...] }`, which is rewritten). Wrapping predicates as `{ "filters": { "or": [...] } }` is accepted, but `limit` belongs next to `filters`, not inside the `or` object. Trailing commas are invalid JSON.

Supported ops: `eq`, `neq`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`, `contains`, `is_null`, `is_not_null`.

**Search field** is unused for filter tools (leave it empty). **Return fields** are the columns copied onto each result row — they are not the only keys you may filter on.

- `raw.status` reads the ingested column on the entry.
- `intrinsic.unique_key` reads the stored unique-key output (not a Postgres `max(jsonb)` aggregate).
- Unprefixed `status` / `created_at` mean `raw.status` / `raw.created_at` unless that exact name is a return field (then it is a canonical output key).

Response includes `items` (rows with `entry_id` + return fields) and `pagination` (`total_matching`, `has_more`, `next_page`). Keep calling with the same filters and `page=2,3,…` until `has_more` is false.

## Setup checklist

1. Ingestion group with approved entries and output keys populated.
2. **Settings → Tools → Add** — kind **Filter**, link groups, set **return fields** to the columns you want on each row (for example `raw.url`, `intrinsic.unique_key`).
3. Search field is unused. Leave it empty.
4. Attach tool to a prompt or rely on project global allowlist.
5. Test from project chat with a question that needs exact field recall (e.g. “list all entries where location is USA”).

## Scheduler and tool-chain runs

Scheduled runs and tool-chain steps do **not** receive chat arguments.
Human-language text in the tool description is not executed as a filter.
If the description contains a JSON object with a `filters` array, that JSON is used as a fallback.
Prefer setting **Default filter arguments** on the filter tool, or **step args JSON** on the scheduler step:

```
{
  "filters": [
    { "key": "raw.status", "op": "eq", "value": "New" }
  ],
  "order_by": [{ "key": "raw.created_at", "dir": "asc" }],
  "limit": 1
}
```

## Related

- [tools](tools.md) — tool kinds and embeddings
- [analytics](analytics.md) — aggregates over the same key space
