Skip to main content

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

FilterTypeDescription
assetIdentifiersSet[String]Only return documents attached to these asset UIDs.
documentationIdentifiersSet[String]Only return documents linked to these documentation UIDs.
folderIdentifiersSet[String]Only return documents stored in these folder UIDs.

1.2 Business Context Filters

FilterTypeDescription
linkedAssetIdentifiersSet[String]Documents related to specific linked assets (e.g., building, apartments).
tenantIdentifiersSet[String]Documents belonging to or created by specific tenants.
linkedAssetStringPartial or full name match of the linked asset—useful when you don’t have the UIDs on hand.
hasLinkedAssetsBooleanFilter documents that have at least one linked asset (true) or none (false).

1.3 Basic Document Filters

FilterTypeDescription
identifierSet[String]Exact document UIDs to retrieve.
nameStringPartial or full name match (case-insensitive).
documentStatusStringOne of CLASSIFICATION, METADATA_EXTRACTION, COMPLETED.
hashSha256StringSHA-256 checksum of the document’s contents.
updatedAfterString(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.
createdAfterString(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

FilterTypeDescription
tagsSet[String]Documents tagged with one or more specified tags.
propertiesMap[String,String]Documents with matching metadata key-value pairs.
propertyKeyStringDocuments containing a specific metadata key (regardless of value).
hasMetadataBooleanFilter documents with exploitable metadata (true) or none (false).

1.5 Folder & Classification Filters

FilterTypeDescription
parentFolderNameStringPartial match on the parent folder’s name.
predictedFolderNameStringAI-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.
hasPendingSuggestionBooleanFilter 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

ParameterTypeDescription
pageNumberIntegerPage number for offset-based pagination (starts at 1; 0 is accepted for backward compatibility). Default 1.
pageSizeIntegerPage size for offset-based pagination. Default 20.
sortOrderStringSort order for offset-based pagination: ASC or DESC.
columnToSortStringColumn 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.
updatedAfterStringFilters 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.
createdAfterStringFilters documents created during or after this date. Same accepted formats as updatedAfter.
afterIdStringCursor for keyset pagination — see Cursor-based Pagination below.
afterValueStringCursor 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.

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 by id ascending. Pass afterId=0 to start a new walk; pass the previous response's nextCursor to fetch the next page.
  • afterValue — cursor value used together with afterId and columnToSort=updateDate to walk documents ordered by update date instead of id. 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 plain id-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 as afterId on the next call. null when there is no further page, or afterId was not used for this request.
  • nextCursorValue: cursor value to pass as afterValue on the next call, when using columnToSort=updateDate. null when there is no further page, or this mode was not used.

4. Error Handling

  • 400 Bad Request: Missing or invalid filters. For invalid updatedAfter/createdAfter values, 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.read scope
  • 404 Not Found: organizationCode not 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 linkedAsset for 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) over updatedAfter polling for reliably tracking document changes over time — see Cursor-based Pagination.

For full API reference, see the Stonal API specification.