Simulators
Search
search.messages, search.all and search.files answer a query the way Slack’s search does, with its modifiers, over the workspace’s messages and files. They take a user (xoxp-) token and answer a bot token not_allowed_token_type, as Slack does. Search as a seeded user for messages one person wrote in one channel, then try a bot token and an unknown modifier:
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
curl -s "$RYSTIC_URL/api/search.messages" -H 'Authorization: Bearer xoxp-anything' -H 'X-Rystic-Actor: UWDC0000001' --data-urlencode 'query=in:#help from:<@UWDC0000022> shared drive' | jq -c '{ok, total: .messages.total}'
# -> {"ok":true,"total":2}
curl -s "$RYSTIC_URL/api/search.messages" -H 'Authorization: Bearer xoxp-anything' -H 'X-Rystic-Actor: UWDC0000001' --data-urlencode 'query=in:#help "shared drive" before:2026-03-01' | jq -c '{ok, total: .messages.total}'
# -> {"ok":true,"total":7}
curl -s "$RYSTIC_URL/api/search.messages" -H 'Authorization: Bearer xoxb-local' --data-urlencode 'query=drive' | jq -c .
# -> {"error":"not_allowed_token_type","ok":false}
curl -s "$RYSTIC_URL/api/search.messages" -H 'Authorization: Bearer xoxp-anything' -H 'X-Rystic-Actor: UWDC0000001' --data-urlencode 'query=in:#help nosuchmodifier:x' | jq -c '{ok, total: .messages.total}'
# -> {"ok":true,"total":0}
What a caller can find
search.messages and search.all answer messages only from conversations the token’s user can read: every public channel and the private channels, DMs and group DMs the user is in. search.files and the file results of search.all still answer every file. A thread reply’s permalink ends in ?thread_ts=<the thread's ts>.
Modifiers
The messages of search.messages and search.all read Slack’s search modifiers, as Slack does:
in:names a channel (#name,name,<#C…>,<#C…|name>) or a DM (<@U…>,@name).from:names an author (<@U…>,@name,nameormefor the token’s user).has:takeslink,pinorreaction.before:,after:,on:andduring:name a date (YYYY-MM-DD,YYYY/MM/DD,today,yesterday,YYYY-MM, a month’s name orYYYY) in the token’s user’s time zone, whereafter:leaves the named day out.
Bare words match whole words in any case and every word must match; "a phrase" keeps its order and - excludes a word or a modifier. AND and parentheses group, while OR is an ordinary word. Two in: or two from: terms match either one. Modifiers don’t apply to files, so search.files and the file results of search.all match the whole query as text.
Forgiving input
No query is refused: an unknown modifier or an unreadable date matches nothing, and an unknown has: value is ignored. Unbalanced brackets or quotes are forgiven. highlight=true wraps each searched word in U+E000 and U+E001, never a modifier.
Not modeled
has::emoji: is ignored, where Slack narrows to that reaction. The unrelated low-score matches Slack appends to a query holding an unknown term are not returned.