Find API
The Find API is the standard way to query and paginate through component model data. It returns a page of records along with total count metadata, and optionally resolves relation fields to their referenced documents.
When to use Find vs. other endpoints
| Use case | Recommendation |
|---|---|
| Paginated UI — fetching a page of results | Find API (this page) |
| Processing all records — exports, migrations | find(..., { stream: true }) |
| Complex aggregations — grouping, facets | Aggregation endpoint |
| Relation data exceeds 5 MB | find(..., { stream: true }) |
Usage (SDK)
const result = await platform.component('orders').find({
currentPage: 1,
perPage: 25,
sortBy: 'CreatedAt',
sortDesc: -1,
filter: 'paid',
filterOn: ['status'],
})
console.log(result.total) // total matching records
console.log(result.total_pages) // total pages
console.log(result.items) // records on this page
With an advanced filter (MongoDB query)
const result = await platform.component('orders').find(
{ currentPage: 1, perPage: 25 },
{
$adv: { status: 'paid', amount: { $gte: 100 } },
}
)
With a custom sort pipeline
const result = await platform.component('orders').find(
{ currentPage: 1, perPage: 25 },
{
$aggregate: [{ $sort: { 'data.amount': -1 } }],
}
)
HTTP API
All parameters are passed as URL query string values.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
offset |
integer | 1 |
Page number (1-based) |
limit |
integer | 250 |
Records per page. Clamped to 250 if 0 or greater than 250 |
sortBy |
string | CreatedAt |
Field to sort by |
sortDesc |
integer | -1 |
Sort direction: -1 descending, 1 ascending |
filter |
string | — | Full-text search term applied across filterable fields |
filterOn |
string | — | Comma-separated list of fields to restrict the text search to |
dateFrom |
string (ISO 8601) | — | Lower bound for date range filter |
dateTo |
string (ISO 8601) | — | Upper bound for date range filter |
dateField |
string | CreatedAt |
Field to apply the date range filter against |
$adv |
JSON string | — | Raw MongoDB query filter (serialised JSON object) |
$aggregate |
JSON string | — | Custom aggregation pipeline stages (JSON array). See pipeline rules |
disabled |
boolean | false |
When true, includes soft-deleted records |
Response
{
"items": [ /* array of model records */ ],
"total": 1234,
"total_filtered": 1234,
"total_pages": 50,
"page": 1
}
| Field | Description |
|---|---|
items |
Records on the requested page. Each record has uuid, data, CreatedAt, UpdatedAt, and resolved relation fields |
total |
Total matching records (capped at 5 000, see limits) |
total_filtered |
Same as total when a filter is active |
total_pages |
Total number of pages (capped to reflect the 5 000-record limit) |
page |
The current page number |
Pipeline validation
Pipelines supplied via $aggregate are validated before execution.
Allowed stages
| Stage | Description |
|---|---|
$match |
Filter documents |
$sort |
Sort documents |
$project |
Shape output documents |
$addFields / $set |
Add or overwrite computed fields |
$unset |
Remove fields |
$limit |
Limit result count |
$skip |
Skip documents (maximum value: 5 000) |
$group |
Group and aggregate |
$facet |
Multi-faceted aggregation |
$unwind |
Deconstruct arrays |
$count |
Count documents |
Forbidden stages
| Stage | Reason |
|---|---|
$lookup |
Expensive cross-collection joins are handled internally by the relation resolver |
$out / $merge |
Write operations are not permitted in query pipelines |
$sample |
Random sampling can be slow on large collections |
| Any other stage | Not on the allow-list |
Pipeline length
A pipeline may contain at most 10 stages. Requests with longer pipelines are rejected.
Limits
| Limit | Value |
|---|---|
Maximum records per page (limit) |
250 |
| Maximum records accessible (skip + limit) | 5 000 |
| Maximum pages shown | Derived from 5 000 ÷ limit |
| Maximum total reported | Capped at 5 000 even if more records exist |
| Relation data per page | 5 MB |
| Pipeline stages | 10 |
$skip value in user pipeline |
5 000 |
| Operation timeout | 30 seconds |
5 000-record cap
The Find API is designed for paginated UIs. If you need to access more than 5 000 records, use the streaming endpoint which supports up to 25 000 records with no relation-data cap per record.
Error responses
| HTTP status | Condition |
|---|---|
400 Bad Request |
Invalid filter, disallowed pipeline stage, page beyond the 5 000-record limit, pipeline too complex |
400 Bad Request |
Relation data for the page exceeds 5 MB — switch to the streaming endpoint |
408 Request Timeout |
Operation did not complete within 30 seconds |
Common error messages
pipeline too complex: has N stages, maximum allowed is 10
disallowed pipeline stage: $lookup
maximum allowed page is N (limited to 5000 records)
requested records exceed maximum limit of 5000
$skip value too high: N (maximum 5000)
relation data exceeds 5 MB limit; use the streaming endpoint
FAQ
Can I sort by a relation field?
Yes. Use $sort in the $aggregate pipeline targeting the internal _RefObj suffix field that the server embeds for relation fields (e.g., { $sort: { 'data.owner_RefObj.name': 1 } }).
Why is my total capped at 5 000? The Find API enforces a 5 000-record ceiling on offset-based pagination to protect query performance in a multi-tenant environment. Use the streaming endpoint for bulk access.
The relation data size error appears even with a small page size. Why?
Each record on the page may reference many documents in another collection. The 5 MB budget accounts for the total raw BSON size of all resolved relation data for the page — not just the number of records. Reduce perPage or switch to the streaming endpoint.