Pagination, Filtering & Sorting
All list endpoints support pagination, filtering, sorting, and relation inclusion via query parameters.
Pagination
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
number | 1 |
Current page number (1-indexed) |
perPage |
number | 10 |
Number of items per page |
curl:
curl "https://api.incrm.app/api/v1/client?page=2&perPage=25" \
-H "X-Api-Key: incrm_your-key"
TypeScript SDK:
const { data } = await listClients({ query: { page: 2, perPage: 25 } })
Pagination Metadata
List responses include a meta object:
{
"success": true,
"data": [...],
"meta": {
"total": 150,
"lastPage": 6,
"currentPage": 2,
"perPage": 25,
"prev": 1,
"next": 3
}
}
| Field | Type | Description |
|---|---|---|
total |
number | Total number of matching records |
lastPage |
number | Last available page number |
currentPage |
number | Current page number |
perPage |
number | Items per page |
prev |
number | null | Previous page number, or null if on first page |
next |
number | null | Next page number, or null if on last page |
Traversing All Pages
To retrieve all records, iterate until meta.next is null:
import { InCRMClient, listClients } from '@incrm-app/sdk'
const incrm = new InCRMClient({
baseUrl: 'https://api.incrm.app',
apiKey: 'incrm_your-key',
})
let page = 1
const allClients = []
while (true) {
const { data: response } = await listClients({ query: { page, perPage: 100 } })
allClients.push(...response.data)
if (!response.meta.next) break
page = response.meta.next
}
console.log(`Fetched ${allClients.length} clients`)
Filtering (where)
The where parameter supports a powerful filter syntax for querying records.
Basic Equality
where=firstName:John
Operators
Use the operator syntax field:operator:value:
| Operator | Description | Example |
|---|---|---|
| (none) | Equals | where=status:ACTIVE |
gt |
Greater than | where=amount:gt:int(100) |
gte |
Greater than or equal | where=amount:gte:int(50) |
lt |
Less than | where=amount:lt:int(1000) |
lte |
Less than or equal | where=amount:lte:int(500) |
contains |
String contains | where=name:contains:john |
startsWith |
String starts with | where=name:startsWith:Jo |
endsWith |
String ends with | where=email:endsWith:.com |
Type Casting
Wrap values in type functions:
| Type | Syntax | Example |
|---|---|---|
| Integer | int(value) |
where=amount:gt:int(100) |
| Float | float(value) |
where=price:lt:float(99.99) |
| Boolean | bool(value) |
where=isActive:bool(true) |
| Date | date(value) |
where=createdAt:gt:date(2025-01-01) |
Multiple Conditions (AND)
Separate conditions with commas:
where=status:ACTIVE,firstName:contains:John
OR Conditions
where=OR:[status:ACTIVE,status:PENDING]
NOT Conditions
where=NOT:status:ARCHIVED
Examples
curl — Active clients created after Jan 2025:
curl "https://api.incrm.app/api/v1/client?where=isActive:bool(true),createdAt:gt:date(2025-01-01)" \
-H "X-Api-Key: incrm_your-key"
curl — Invoices over $1000:
curl "https://api.incrm.app/api/v1/invoice?where=totalAmount:gt:int(1000)" \
-H "X-Api-Key: incrm_your-key"
Sorting (orderBy)
Sort results using field:direction pairs, separated by commas:
orderBy=lastName:asc,firstName:asc
| Direction | Description |
|---|---|
asc |
Ascending |
desc |
Descending |
curl:
curl "https://api.incrm.app/api/v1/invoice?orderBy=createdAt:desc&perPage=50" \
-H "X-Api-Key: incrm_your-key"
TypeScript SDK:
const { data } = await listInvoices({
query: { orderBy: 'createdAt:desc', perPage: 50 },
})
Error on Invalid Sort
{
"success": false,
"error": {
"code": 400011,
"message": "Invalid sorting order"
}
}
Relation Inclusion (include)
Expand related entities using the include parameter. Provide a comma-separated list of relation names:
include=invoices,contacts
Prefix with - to exclude a default relation:
include=-contacts
curl:
curl "https://api.incrm.app/api/v1/client/6507a1b2c3d4e5f6a7b8c9d0?include=invoices,contacts" \
-H "X-Api-Key: incrm_your-key"
Response (with included relations):
{
"success": true,
"data": {
"id": "6507a1b2c3d4e5f6a7b8c9d0",
"firstName": "John",
"lastName": "Doe",
"invoices": [
{ "id": "...", "totalAmount": 500, "status": "PAID" }
],
"contacts": [
{ "id": "...", "type": "EMAIL", "value": "john@example.com" }
]
}
}
Available relations depend on the entity. Refer to the OpenAPI spec at GET /api/v1/openapi.json for the complete list of relations per resource.
Error on Invalid Include
{
"success": false,
"error": {
"code": 400019,
"message": "Invalid query format"
}
}