Skip to main content

Filtering

Some endpoints allow filtering on certain fields. Not all fields are filterable, and the available filter operations may vary between fields. Refer to a specific endpoint to discover what is possible. All filters follow the same structure:
Filtering on several fields returns the records that match all of them:

Matching any of several values

The in operator matches any of several values. Separate them with commas, or repeat value[]:
Each endpoint’s reference lists the fields that support in. Filters cannot be sent as JSON (filters={"updated_at":...}); that returns 400.

Filtering by condition

The list endpoints for employees (including POST /v1/org/employees/shape), time reports, organizational units, competences and employee competences also accept a condition_id: the id of an organization-wide condition, a saved rule over that domain’s records. Only the records the condition passes are returned, after any filters have been applied.
Find the id in the app under Conditions in the sidebar, or with GET /v1/org/conditions. Twine encrypts every record’s properties at rest, so the database cannot see the values a condition reads. The condition therefore runs in the application, after a page has been read and decrypted, and that shapes the paging behaviour below. What to expect when a condition is set:
  • A page may be shorter than first, even empty, while has_next_page is still true. Twine reads the page, decrypts it, drops the records that fail, and stops after a bounded number of records per request rather than scanning the whole organization. Keep requesting end_cursor until has_next_page is false; nothing is skipped.
  • pagination[last] and pagination[before] are not supported together with a condition and return 400.
  • The condition’s domain has to be the endpoint’s domain. A condition of another domain, or an id that does not exist in your organization, returns 400.
  • No permission on conditions is needed to filter by one: list on the resource is enough, since the response only ever contains that resource’s records. Reading the conditions themselves through GET /v1/org/conditions does need list on the Condition resource type.

Ordering

Some endpoints allow ordering on certain fields. Not all fields are orderable. Refer to a specific endpoint to discover what is possible. All ordering follows the same structure:

Lists of values

select, relations and references take a list of values. Separate them with commas:
The other ways HTTP clients commonly write a list are accepted too, and all of these mean the same:
  • Spaces around the commas are ignored.
  • An empty value (relations=) is the same as leaving the parameter out.
  • Brackets may be sent percent-encoded (relations%5B%5D=employee_mappings).
  • Values are case-sensitive, and an unknown value returns 400. Each endpoint’s reference lists the values it accepts.
These are not lists, and return 400: a JSON array (relations=["employee_mappings"]), and other separators such as ;, | or a space. select works the same way. Employee fields are selected by their full path:

Nested parameters

filters, order and pagination are objects. Write them with one bracketed key per field (OpenAPI deepObject style), and combine them freely:
The OpenAPI spec declares these parameters deepObject. Some client generators do not serialize two levels of brackets (filters[updated_at][op]); if yours sends anything else, build these parameters by hand.