Queries a collection. Send it with no options to page through everything, or add a
filter to match on document contents.💡 Results are paginated. Keep requesting the nextpage_numberuntil the response comes back with"eop": true.
Request
method is "listDocuments".Field | Type | Required | Description |
collection | String | Yes | The collection to query. |
filter | Object | Optional | Conditions a document must match. Omit to return everything. |
sort | Object | Optional | Field-to-direction map. -1 descending, 1 ascending. |
page_size | Number | Optional | Documents per page. Defaults to 50, capped at 200. |
page_number | Number | Optional | Page to retrieve, starting at 0. |
app_id | String | Optional | The app the collection belongs to. Defaults to the bot's own app. |
reference | String | Optional | Your id for this request. Echoed back in the response. |
Filters
A filter is an object of field conditions, all of which must hold. A bare value means equality:
json"filter": { "status": "shipped", "total": { "$gte": 100 }, "region": { "$in": ["EG", "AE"] }, "coupon": { "$exists": false } }
Operators
Operator | Matches when the field | Example |
bare value | equals the value | {"status": "shipped"} |
$eq | equals the value | {"status": {"$eq": "shipped"}} |
$ne | does not equal the value | {"status": {"$ne": "cancelled"}} |
$gt $gte | is greater than / at least | {"total": {"$gte": 100}} |
$lt $lte | is less than / at most | {"total": {"$lt": 50}} |
$in | is one of the listed values | {"region": {"$in": ["EG", "AE"]}} |
$nin | is none of the listed values | {"region": {"$nin": ["US"]}} |
$exists | is present ( true) or absent (false) | {"coupon": {"$exists": false}} |
$contains | is an array containing the value | {"items": {"$contains": "sku-1"}} |
$like | is a string containing the substring | {"name": {"$like": "ali"}} |
Nested fields use dots:
{"address.city": "Cairo"}.Notes on matching
Comparisons are typed from the value you send.
{"total": {"$gte": 100}} compares numerically; {"name": {"$gte": "m"}} compares as text. Send 100, not "100", when you mean a number — quoting it gives you a string comparison where "9" sorts after "100".$like matches substrings literally. % and _ in your value are treated as characters, not wildcards.⚠️ Filtering scans the collection — the document body is not indexed. It stays fast on collections of hundreds to low thousands. If a collection grows large and you query it often, promote the hot field into document_id so you can fetch by id instead.Not supported in this version:
$or / $and nesting, and regular expressions. Every condition in a filter is AND-ed.Response
listDocumentsResponse
Field | Type | Returned | Description |
method | String | Yes | "listDocumentsResponse" |
documents | Array | Yes | This page of results. Each entry has document_id and document. |
collection | String | Yes | Echoed from the request. |
page_number | Number | Yes | The page this result represents. |
eop | Boolean | Yes | End of pages. true when there is nothing more to fetch. |
app_id | String | Yes | Echoed from the request. |
reference | String | Optional | Echoed from the request. |
SDKs
SDK | Call | Callback |
Java | store.listDocuments(api, collection, filter, sort, pageSize, pageNumber, reference); | onDocumentResponse(DocumentResponse response) |
JavaScript | store.listDocuments(api, collection, reference, { filter, sort, pageSize, pageNumber }); | onDocumentResponse(response) |
Python | store.list_documents(api, collection, reference, filter=…, sort=…, page_size=…, page_number=…) | on_document_response(self, response) |
Java also has a short form for an unfiltered first page:
store.listDocuments(api, collection, reference).Example
Request
json{ "method": "listDocuments", "collection": "orders", "app_id": "90090684293000559", "reference": "123456789", "filter": { "status": "shipped", "total": { "$gte": 100 }, "region": { "$in": ["EG", "AE"] } }, "sort": { "created_at": -1 }, "page_size": 50, "page_number": 0 }
javaJSONObject total = new JSONObject(); total.put("$gte", 100); JSONObject filter = new JSONObject(); filter.put("status", "shipped"); filter.put("total", total); JSONObject sort = new JSONObject(); sort.put("created_at", -1); DocumentStore.getInstance() .listDocuments(api, "orders", filter, sort, 50, 0, "123456789"); // in the callback @Override public void onDocumentResponse(DocumentResponse response) { for (DocumentResponse.Entry entry : response.getDocuments()) { System.out.println(entry.getDocumentId() + " -> " + entry.getDocument()); } if (!Boolean.TRUE.equals(response.isEndOfPages())) { // request response.getPageNumber() + 1 } }
javascriptconst store = require('nandbox-bot-api/src/util/DocumentStore') store.listDocuments(api, 'orders', '123456789', { filter: { status: 'shipped', total: { $gte: 100 } }, sort: { created_at: -1 }, pageSize: 50, pageNumber: 0 }) // in the callback nCallBack.onDocumentResponse = response => { response.documents.forEach(e => console.log(e.document_id, e.document)) if (!response.eop) { // request response.page_number + 1 } }
pythonfrom nandboxbots.util.DocumentStore import DocumentStore DocumentStore.get_instance().list_documents( api, "orders", "123456789", filter={"status": "shipped", "total": {"$gte": 100}}, sort={"created_at": -1}, page_size=50, page_number=0, ) # in the callback def on_document_response(self, response): for entry in response.documents: print(entry.document_id, entry.document) if not response.eop: pass # request response.page_number + 1
Response
json{ "method": "listDocumentsResponse", "collection": "orders", "app_id": "90090684293000559", "reference": "123456789", "page_number": 0, "eop": true, "documents": [ { "document_id": "42", "document": { "status": "shipped", "total": 149.5, "region": "EG", "created_at": "2026-07-27T10:00:00Z" } }, { "document_id": "43", "document": { "status": "shipped", "total": 100, "region": "AE", "created_at": "2026-07-26T18:30:00Z" } } ] }