Pagination, sorting and search
| Lists | Paging | Sort | Search |
|---|---|---|---|
| Employees, contractors, vacancies, teams, projects, custom attribute definitions | page, limit | sortBy, sortDir | search |
| Assignments | page, limit | sortDir (by start date) | — |
| Functional groups | offset, limit | By name | search |
| Salary adjustments, contractor rate adjustments | None; full history | — | — |
Page-based lists
| Parameter | Type | Default | |
|---|---|---|---|
page | integer ≥ 1 | 1 | |
limit | integer 1–100 | 20 | |
sortBy | string | per resource | Unrecognised values use the default. |
sortDir | asc | desc | asc | |
search | string | — | Case-insensitive substring match. |
An out-of-range page or limit, or any other sortDir, returns 400 VALIDATION_ERROR.
{
"data": [ … ],
"meta": { "page": 2, "limit": 50, "total": 142, "hasNextPage": true }
}
total counts every match across pages. Stop when hasNextPage is false:
async function* listAll(path) {
for (let page = 1; ; page++) {
const res = await fetch(`${BASE_URL}${path}?page=${page}&limit=100`, {
headers: { Authorization: `Bearer ${process.env.FLOWSTATE_API_KEY}` },
});
const { data, meta } = await res.json();
yield* data;
if (!meta.hasNextPage) return;
}
}
Paging is by position, so records created or deleted during a walk can shift between pages. For a full sync, sort by a stable field and match on externalId.
Sort and search fields
| Resource | sortBy | Default | search matches |
|---|---|---|---|
| Employees | lastName, firstName, email, startDate | lastName | firstName, lastName, email |
| Contractors | name, email, contractorType, startDate | name | name, email |
| Vacancies | role, status, targetStartDate, targetEndDate | role | role, description |
| Teams | name, teamType, createdAt | name | name, description |
| Projects | name, startDate, priority, projectCode | name | name, description, projectCode |
| Custom attribute definitions | sortOrder, name, createdAt, fieldType | sortOrder | name, description |
curl "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/employees?search=chen&sortBy=startDate&sortDir=desc&limit=25" \
-H "Authorization: Bearer $FLOWSTATE_API_KEY"
Assignments
GET /assignments/employees, /contractors, /vacancies and /teams take page, limit and sortDir, are ordered by startDate, and return meta. They list every assignment in the organisation; sortBy, search and filters are ignored.
For one record’s allocations, use include=assignments on GET /employees/{id}, GET /contractors/{id} or GET /vacancies/{id}.
Functional groups
GET /functional-groups:
| Parameter | Default | |
|---|---|---|
offset | 0 | Groups to skip. |
limit | 20 | 1–100. |
search | — | Case-insensitive match on name or description, up to 255 characters. |
parentId | — | Children of this group only. |
rootsOnly | — | true for top-level groups only. |
asOf | today | YYYY-MM-DD. |
Groups are ordered by name. The response has no meta; the count is in the body:
{ "data": { "groups": [ … ], "total": 37 } }
GET /functional-groups/tree returns the whole hierarchy, up to 500 groups, in one call. See Functional groups.
Unpaged lists
GET /employees/{id}/salary-adjustments and GET /contractors/{id}/rate-adjustments return the whole history as { "data": [ … ] }, with no meta.