Skip to main content
Honcho provides a sophisticated filtering system that allows you to query workspaces, peers, sessions, and messages with precise control. The filtering system supports logical operators, comparison operators, metadata filtering, and wildcards to help you find exactly what you need.

Basic Filtering Concepts

Filters in Honcho are expressed as dictionaries that define conditions for matching resources. The system supports both simple equality filters and complex queries with multiple conditions.

Simple Filters

The most basic filters check for exact matches:

Logical Operators

Combine multiple conditions using logical operators for complex queries:

AND Operator

Use AND to require all conditions to be true:

OR Operator

Use OR to match any of the specified conditions:

NOT Operator

Use NOT to exclude specific conditions:

Negation and Unset Fields

A field can be unset, and negation has to account for it. NOT and the ne comparison operator both include rows where the field has no value at all: a field with no value is not the value you are excluding, so excluding that value keeps the row. Positive conditions work the other way around. An unset field matches nothing, so equality and contains never return those rows. To select them, filter on null directly: Of the filterable fields, only a conclusion’s session_id can be unset: a conclusion drawn across a whole workspace belongs to no single session. Every other field is always populated, so none of this affects filters on them. See Filtering Conclusions for what conclusions are.
To exclude a value and require the field to be set, combine the two with AND:

Combining Logical Operators

Create sophisticated queries by combining different logical operators:

Comparison Operators

Use comparison operators for range queries and advanced matching:

Numeric Comparisons

List Membership

A bare list is shorthand for in, so {"peer_id": ["alice", "bob"]} and {"peer_id": {"in": ["alice", "bob"]}} are equivalent:
Bare lists behave differently inside metadata — use {"in": [...]} there for OR matching.
The explicit form, plus the other comparison operators:

Metadata Filtering

Metadata filtering is particularly powerful in Honcho, supporting nested conditions and complex queries:

Basic Metadata Filtering

Advanced Metadata Queries

If you want to do advanced queries like these, make sure not to create metadata fields that use the same names as the included comparison operators! For example, if you have a metadata field called contains, it will conflict with the contains operator.

Wildcards

Use wildcards (*) to match any value for a field:

Resource-Specific Examples

Filtering Workspaces

Filtering Messages

Filtering Conclusions

Conclusions belong to an observer/observed peer pair (accessed via peer.conclusions for self-conclusions or peer.conclusions_of(target) for conclusions about another peer). The observer and observed are filled in automatically by the scope, so the filters you pass add to them. The most useful conclusion-specific field is level, the reasoning level:
  • explicit — extracted directly from messages
  • deductive / inductive / contradiction — derived later during dreaming
A common request is to surface only the directly-stated facts and exclude anything inferred during dreaming — filter level to explicit:

Value Types

A filter value has to be usable against the field it targets. Honcho validates this before running the query and returns a 422 with an explanation when it doesn’t hold, rather than failing mid-query or quietly returning nothing. Three consequences worth knowing:
  • Booleans must be real booleans. {"is_active": True} filters; the string {"is_active": "true"} is rejected.
  • Fixed-value fields are checked. {"level": "explicit"} filters; {"level": "typo"} is rejected instead of returning an empty list, so a misspelling doesn’t look like “no results”.
  • metadata takes only the two shapes above — bare, or under contains. Comparison operators don’t apply to the object as a whole, so {"metadata": {"ne": {...}}} is rejected. To compare within metadata, put the operator on the key — {"metadata": {"status": {"ne": "done"}}}. To negate a match, wrap the whole condition in NOT. See Metadata Filtering.
For every field other than metadata, the same rules apply however the value is wrapped — bare, under an operator, or inside an in list — so {"level": "explicit"}, {"level": {"ne": "explicit"}} and {"level": {"in": ["explicit"]}} all validate identically. An empty in list matches nothing:

Scoping Recall to Sessions

The chat endpoint and the representation endpoint accept a filters body too, but a deliberately narrow one: it defines a session allowlist, restricting what the request can recall to the sessions you name — conclusions on both endpoints, and on chat the messages the agent reads as well. This is how you restrict recall to more than one session. The session_id parameter pins a request to exactly one session; an allowlist accepts a set. Only the session_id key is supported here, in three shapes:
Both SDKs expose this as a sessions option, which goes on the wire as the filters body above:
If the same set of sessions is a boundary you reuse, name it: a scope is a persistent version of this allowlist, and querying a single scope recalls at full depth rather than explicit-only. sessions is the right tool when the set is decided per-request.

Rules

Unlike the list endpoints above, this filter fails closed: an unrecognized key or shape is rejected with 422 rather than ignored, because a silently dropped filter here would widen recall instead of narrowing it.
On chat, a peer-scoped key must be an active member of every session it names — the allowlist reaches message recall there — and the request is rejected with 401 otherwise. The representation endpoint runs no membership check: key scope already confines the caller to its own peer’s representation, which an allowlist can only narrow.

What Changes Under an Allowlist

Restricting recall by session narrows what the reasoning agent can draw on:
  • Only explicit conclusions are recalled. Dream-derived conclusions (deductive, inductive) are synthesized across sessions, so they can’t be attributed to one session and are excluded.
  • Reasoning-chain traversal is unavailable, since it walks into those derived conclusions.
  • Message recall is restricted to the allowlisted sessions across every search path — semantic, keyword, and date-range.
Because of this, an allowlisted request answers from directly-stated facts rather than higher-order inferences. If you want the full representation, omit filters and let the agent search everything.

Error Handling

Handle filter errors gracefully:

Conclusion

Honcho’s filtering system provides powerful capabilities for querying your conversational data. By understanding how to:
  • Use simple equality filters and complex logical operators
  • Apply comparison operators for range and pattern matching
  • Filter metadata with nested conditions
  • Handle wildcards and dynamic filter construction
  • Follow best practices for performance and validation
You can build sophisticated applications that efficiently find and process exactly the conversations, messages, and insights you need from your Honcho data.