Guides

Search Queries

List endpoints across services share one query grammar for full-text search, filtering, sorting, and pagination. Any endpoint whose reference page shows the q / filter / sort_by parameters speaks it. (A few endpoints have bespoke list parameters instead - /api/v1/kv/search takes q/prefix/ tags - their reference pages show exactly what they accept.)

GET /api/v1/guilds?q=dragon&filter=visibility:eq:public&sort_by=created_at&sort_order=desc&page_size=2
ParameterTypeDescription
qstringFull-text search across the entity's searchable fields
filterstring, repeatablefield:operator:value filters, ANDed together
sort_bystringField to sort by (per-entity allowlist)
sort_orderstringasc or desc; defaults per field
pageinteger1-indexed; page=0 is rejected with a 400, not clamped
page_sizeintegerDefault 25, clamped to 1-100

Filters

Filters are field:operator:value. Multiple filter parameters are ANDed; multiple values inside one eq (split on | or ,) are ORed.

OperatorMeaningExample
eqEquals; OR-list with |status:eq:active|pending
rangeInclusive numeric range, either bound optionalmember_count:range:10,
prefixText prefixpath:prefix:config/
containsEvery query token occurs, any orderdescription:contains:error
exactAdjacent-token phrasename:exact:John Doe
fuzzyTypo-tolerantname:fuzzy:jonh

Field-type notes, all enforced with 400 rather than silently ignored:

  • Booleans use eq with exactly true or false (private:eq:false). Other operators on a boolean field are rejected.
  • Timestamps filter as epoch milliseconds on the logical field name: created_at:range:1704067200000,.
  • Text matching follows the search index's tokens, not raw bytes: punctuation separates tokens, so exact means token adjacency (a@b, a b, and a-b are the same phrase) and contains ANDs tokens without preserving order. When a value must match as one opaque scalar, the entity models it as a tag field and you use eq.
  • Filter field names are case-sensitive; operator tokens are not. sort_by names match case-insensitively against the entity's allowlist.

q tokenizes the query and prefix-matches each token across the entity's searchable fields - q=dragon knights finds "Dragon Knights Elite" and "Knighthood of Dragons". Combine freely with filters.

A real query

Executed against a live server (guild service, envelope trimmed):

GET /api/v1/guilds?q=dragon&filter=visibility:eq:public&sort_by=created_at&sort_order=desc&page_size=2
{
  "status": 200,
  "msg": "OK",
  "data": {
    "guilds": [
      { "guild_id": "...", "name": "Dragon Riders", "visibility": "public", "created_at": "2026-08-28T03:41:56.493756Z" },
      { "guild_id": "...", "name": "Dragon Knights", "visibility": "public", "created_at": "2026-08-28T03:41:56.421591Z" }
    ],
    "pagination": {
      "total": 2,
      "page": 1,
      "page_size": 2,
      "has_more": false
    }
  }
}

The items key is named after the entity (guilds, webhooks, ...); the pagination shape is identical everywhere.

Errors

Bad queries return 400 with a specific message - never a silently empty result:

MessageCause
Invalid filter syntax: {raw}Not exactly three field:operator:value parts
Unsupported filter operator: {op}Unknown operator token
Unknown filter field: {field}Field not filterable on this entity; names are case-sensitive
Invalid boolean value for {field}: ...Boolean value not exactly true/false
{field} filter only supports eq operatorWrong operator for a tag or boolean field
Invalid numeric value/bound: {value}Non-numeric value on a numeric field
Unsupported sort field: {name}sort_by not in the entity's allowlist

Which fields are filterable and sortable is entity-specific - each list endpoint's page in the API reference documents its parameters.

On this page