Message search
Documentation: v0.24.0
tg messages search reads only the shared local archive, without networking or read receipts.
Start with one word you remember from the message:
tg messages search "invoice"It searches messages already saved on your computer. If the required period is missing, first fetch that chat’s history using the archive guide. The default matches exact words: Lucene is a query language for adding phrases, filters and conditions. For typos and forgiving matching, choose --language legacy. The examples below add filters; fields and regex are only needed for more complex queries.
Quick start
tg messages search 'invoice AND (kind:group OR kind:private)' --json
tg messages search 'from:"Alice Synthetic" date:[2026-01-01 TO 2026-02-01}' --timezone Europe/Madrid --json
tg messages search 'preset:secret kind:saved' --json
tg messages search 'text:/pass(port)?/' --json
tg messages search 'chat:"Work" AND body:/.*invoice.*/' --json
tg messages search 'has:file' --jsonReplace example names with your own. Words and phrases match strictly, with no automatic
correction or substring fallback. alpha OR beta gamma means (alpha OR beta) AND gamma;
alpha OR beta AND gamma means alpha OR (beta AND gamma). Use parentheses for clarity.
Fields and operators
text/body/from/chat/date/kind/has/topic/in/preset, Boolean and field groups, inclusive/exclusive ranges, bounded wildcard and Lucene regex are supported. topic requires one mandatory chat. kind:bot selects a peer; in:bots selects Bot API accounts. filename/mime/size/tag are explicitly unsupported, as are fuzzy/proximity/boost/interval functions. Unknown fields never become literal text.
Dates and regex
--timezone selects an IANA zone; a date without a time means a calendar day. An inclusive upper
boundary includes the whole day, an exclusive one excludes it; DST days are not always 24 hours.
Quote exact timestamps and include seconds and an offset.
text regex matches a whole normalized term; body regex matches the entire raw, case-sensitive body.
Use .* for a body substring. This is a Lucene subset, without JavaScript lookaround, backreferences or flags.
Exceeding row/byte/state/work/time budgets produces an explicit error; narrow the scope.
Archive and machine response
Empty hits do not prove that a message was never sent. JSON reports the query version,
completeness/coverage, accounts/chat and index readiness even with no hits. lastSyncedAt is currently null;
profile inventory is not considered complete. JSONL contains items only; use --json for coverage.
An unfinished word index requires tg store migrate; fetch history with tg store fetch.
Candidate presets do not verify credentials.
Legacy migration
tg messages search 'from:alice after:7d invoice -draft' --language legacy --json
tg messages search --regex 'invoice\s+\d+' --jsonLegacy preserves the old filters and discovery. --regex is a separate JavaScript iu full-body mode with an isolated worker and limits; --regex --language lucene is refused. The programmatic saved-query contract carries a language/version; the shared migration preview cannot preserve fuzzy discovery results.
Full reference
The canonical language guide contains operator/field tables, Unicode/escaping, presets, limits, errors and ten executable recipes. The technical specification describes the pinned grammar, AST/schema, reference fixtures and compiler. Archive covers fetching and completeness; commands lists current options.