Collection controls are declared per JSON:API operation. Do not assume every collection has the same default, maximum, sortable fields, filter object, or relationship includes. The API reference is authoritative for the individual path.
Bound every collection
Use deep-object page parameters and disable cURL's bracket globbing:
curl --silent --show-error --globoff \
--header "Accept: application/vnd.api+json" \
--header "Authorization: Bearer $TOKEN" \
"$HODOFLOW_BASE_URL/api/json/v1/workflows?page[limit]=10&page[offset]=0"
page[limit] is the maximum number of resources requested; page[offset]
skips matching resources. Some operations also expose keyset values such as
page[after] and page[before]. Follow returned links.next and links.prev
instead of constructing cursors yourself.
An operation without a page parameter does not accept pagination. In
particular, never infer that omission means a universal default page size.
Filters
Generated filters use a deep object. The available names and operators derive from reviewed public attributes. A simple equality filter looks like:
filter[is_active]=true
Nested operators, when declared, remain under the field name. Encode values as query data; do not interpolate untrusted text into a URL by hand. A field that is readable is not automatically filterable.
For user-provided filter values, use your HTTP library's query encoder. With
raw cURL, use --get --data-urlencode so reserved characters are encoded.
Sorting
The sort parameter is a comma-separated list of allowed fields. Prefix a field
with - for descending order:
sort=-inserted_at,name
Only fields matched by the operation's OpenAPI pattern are supported. Use a stable tie-breaker where the contract exposes one; otherwise follow the pagination links and do not assume ordering across concurrent writes.
Sparse fieldsets
Request only needed attributes with a fieldset keyed by JSON:API type:
fields[workflow]=name,is_active,version_number
The server still returns type and id. If included resources use another
type, provide a separate fieldset for that type. Sparse fields reduce response
size but do not grant access to hidden or non-public attributes.
Includes
When the operation declares relationship paths, include sideloads them into
the top-level included array:
include=steps,triggers
An include unsupported by that operation is an invalid request. Avoid broad include trees in polling loops; retrieve only the relationships required for the current decision.
Edge cases and recovery
- Invalid page values, filter names, or sort patterns are client errors; correct them instead of retrying unchanged.
- An empty page can be valid, especially after an offset reaches the end.
- A missing
nextlink means paging is complete. - Keep
x-request-idwhen a generated validation error is unclear. - A
429pauses the entire credential's request stream forRetry-After, not only the current page.
Apply these controls in List and inspect workflows.