Search Documents
This guide covers all supported filters for querying documents in the Stonal platform. It details every filter you can use to refine your search queries.
Prerequisites
- A valid OAuth access token (see Authentication)
- Your organization code (used in the endpoint path)
1. Filter Groups & Fields
Each group represents a set of filters targeting different aspects of your documents.
1.1 Filing Location Filters
| Filter | Type | Description |
|---|---|---|
assetIdentifiers | Set[String] | Only return documents attached to these asset UIDs. |
documentationIdentifiers | Set[String] | Only return documents linked to these documentation UIDs. |
folderIdentifiers | Set[String] | Only return documents stored in these folder UIDs. |
1.2 Business Context Filters
| Filter | Type | Description |
|---|---|---|
linkedAssetIdentifiers | Set[String] | Documents related to specific linked assets (e.g., building, apartments). |
tenantIdentifiers | Set[String] | Documents belonging to or created by specific tenants. |
linkedAsset | String | Partial or full name match of the linked asset—useful when you don’t have the UIDs on hand. |
hasLinkedAssets | Boolean | Filter documents that have at least one linked asset (true) or none (false). |
1.3 Basic Document Filters
| Filter | Type | Description |
|---|---|---|
identifier | Set[String] | Exact document UIDs to retrieve. |
name | String | Partial or full name match (case-insensitive). |
documentStatus | String | One of CLASSIFICATION, METADATA_EXTRACTION, COMPLETED. |
hashSha256 | String | SHA-256 checksum of the document’s contents. |
updatedAfter | String | (Query parameter — see Query Parameters) Filters documents updated during or after this date. Accepts an ISO-8601 date (YYYY-MM-DD) or a full ISO-8601 date-time with a time zone/offset (e.g. 2026-07-01T00:00:00Z). Invalid or malformed values return 400 Bad Request. |
createdAfter | String | (Query parameter — see Query Parameters) Filters documents created during or after this date. Same accepted formats as updatedAfter. Invalid or malformed values return 400 Bad Request. |
1.4 Metadata Filters
| Filter | Type | Description |
|---|---|---|
tags | Set[String] | Documents tagged with one or more specified tags. |
properties | Map[String,String] | Documents with matching metadata key-value pairs. |
propertyKey | String | Documents containing a specific metadata key (regardless of value). |
hasMetadata | Boolean | Filter documents with exploitable metadata (true) or none (false). |
1.5 Folder & Classification Filters
| Filter | Type | Description |
|---|---|---|
parentFolderName | String | Partial match on the parent folder’s name. |
predictedFolderName | String | AI-predicted folder name after classification. |
folder | { name, locale } | Match folder by exact name and locale. |
documentClass | { name, locale } | Match classification class by name and locale. |
hasPendingSuggestion | Boolean | Filter documents with an AI classification suggestion pending human validation (true) or none (false) — i.e. an AI-predicted folder and document class exist but have not been manually validated yet. |
2. Search Document API Call
Filters go in the JSON request body. Pagination, sorting, and the date filters (updatedAfter/createdAfter) are passed as URL query parameters, not in the body.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
pageNumber | Integer | Page number for offset-based pagination (starts at 1; 0 is accepted for backward compatibility). Default 1. |
pageSize | Integer | Page size for offset-based pagination. Default 20. |
sortOrder | String | Sort order for offset-based pagination: ASC or DESC. |
columnToSort | String | Column to sort by for offset-based pagination (e.g. creationDate). Set to updateDate together with afterId to enable update-date cursor pagination — see Cursor-based Pagination below. |
updatedAfter | String | Filters documents updated during or after this date. Accepts an ISO-8601 date (YYYY-MM-DD) or a full ISO-8601 date-time with a time zone/offset (e.g. 2026-07-01T00:00:00Z). Invalid or malformed values return 400 Bad Request. |
createdAfter | String | Filters documents created during or after this date. Same accepted formats as updatedAfter. |
afterId | String | Cursor for keyset pagination — see Cursor-based Pagination below. |
afterValue | String | Cursor value used together with afterId and columnToSort=updateDate — see Cursor-based Pagination below. |
Example request
curl -X POST "https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/documents/search?pageNumber=1&pageSize=100&sortOrder=DESC&columnToSort=creationDate" \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-d '{
"name": "Invoice",
"tags": ["important","finance"],
"folderIdentifiers": ["folder-123"],
"assetIdentifiers": ["asset-456"],
"linkedAsset": "Unit A"
}'
Pagination is 1-based: use pageNumber=1 for the first page.
2.1 Cursor-based Pagination (recommended for polling)
When you need to reliably walk through documents ordered by modification date — for example, to periodically poll for documents changed since the last run — use cursor-based pagination instead of pageNumber/columnToSort/sortOrder. Unlike tracking max(updatedAfter) + 1 second client-side, this cannot silently skip documents that were updated within the same second.
afterId— cursor position, keyset-ordered byidascending. PassafterId=0to start a new walk; pass the previous response'snextCursorto fetch the next page.afterValue— cursor value used together withafterIdandcolumnToSort=updateDateto walk documents ordered by update date instead ofid. Omit it to start a new walk from the beginning.columnToSort=updateDate— switches the cursor walk to update-date ordering. Any other (or omitted) value falls back to plainid-ordered cursor pagination.
When afterId is present, pageNumber, sortOrder, and columnToSort (other than updateDate) are ignored.
Starting from a specific date instead of the beginning: pass your own afterValue alongside afterId=0 (it only defaults to the very beginning when omitted). afterValue must be a plain ISO-8601 date-time without a time zone/offset — e.g. 2026-01-01T00:00:00, not 2026-01-01T00:00:00Z (this differs from updatedAfter/createdAfter, which do accept a Z/offset). A malformed afterValue is not rejected with an error — it is silently ignored and the walk restarts from the very beginning instead, so double-check the format before relying on it.
First call — start an update-date-ordered walk from the beginning:
curl -X POST "https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/documents/search?afterId=0&columnToSort=updateDate" \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-d '{}'
The response includes nextCursor and nextCursorValue (see Response Format). Subsequent calls pass those values back as afterId/afterValue:
curl -X POST "https://api.stonal.io/document-storage/v1/organizations/{organizationCode}/documents/search?afterId=12345&afterValue=2026-07-17T14%3A32%3A10.123456&columnToSort=updateDate" \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-d '{}'
Keep polling with the latest nextCursor/nextCursorValue until the response no longer returns a nextCursor (there is no further page).
3. Response Format
200 OK with JSON:
{
"result": [],
"total": 42,
"pageable": {
"pageNumber": 1,
"pageSize": 100,
"sort": {}
},
"nextCursor": null,
"nextCursorValue": null
}
pageable.pageNumber is also 1-based in responses.
nextCursor and nextCursorValue are only populated when paginating with afterId (see Cursor-based Pagination):
nextCursor: opaque cursor to pass asafterIdon the next call.nullwhen there is no further page, orafterIdwas not used for this request.nextCursorValue: cursor value to pass asafterValueon the next call, when usingcolumnToSort=updateDate.nullwhen there is no further page, or this mode was not used.
4. Error Handling
- 400 Bad Request: Missing or invalid filters. For invalid
updatedAfter/createdAftervalues, the response body is a plain-text error message (not JSON), e.g.Invalid updatedAfter: 2026-07-00. Expected an ISO-8601 date (e.g. 2026-07-01) or date-time (e.g. 2026-07-01T00:00:00Z). - 401 Unauthorized: Invalid or missing access token
- 403 Forbidden: Missing
stonal.document.readscope - 404 Not Found:
organizationCodenot recognized
5. Best Practices
- Use UIDs whenever possible (
identifier,assetIdentifiers) for precise, performant queries. - Combine multiple filters to narrow down results (e.g., status + metadata + folder).
- Leverage
linkedAssetfor human-friendly searches when you don’t have exact UIDs. - Tag and property filters are ideal for contextual grouping across documents.
- Prefer cursor-based pagination (
afterId/afterValue/columnToSort=updateDate) overupdatedAfterpolling for reliably tracking document changes over time — see Cursor-based Pagination.
For full API reference, see the Stonal API specification.