Skip to content
Last updated

Sorting, filtering and pagination

Learn how to use OData query options to filter, sort, and paginate results in the LawVu API

The LawVu API supports a subset of the OData query language to enable filtering, sorting, and pagination of collection resources. This guide explains how to use these query options effectively.

Supported query options

The following OData query options are supported:

Query OptionDescription
$filterFilter the results based on field values
$orderbySort the results by one or more fields
$topLimit the number of results returned
$skipSkip a specified number of results (for pagination)

Use $top and $skip to paginate through large result sets.

$top

Limits the number of results returned in the response.

  • Default value: 30
  • Maximum value: 200
  • Minimum value: 1
# Limit results to 10 items
GET /v2/matters?$top=10

Skips a specified number of results. Use this in combination with $top to implement pagination.

  • Default value: 0
  • Minimum value: 0
# Skip the first 30 results and return the next 10
GET /v2/matters?$skip=30&$top=10

Pagination example

To retrieve results in pages of 10:

# Retrieve the first 10 results
GET /v2/matters?$top=10

# Skip the first 10 results and retrieve the next 10
GET /v2/matters?$top=10&$skip=10

# Page 3: Skip the first 20 results and retrieve the next 10
GET /v2/matters?$top=10&$skip=20

Sorting with $orderby

Sort results by one or more fields using the $orderby query option. Each field can be sorted in ascending (asc) or descending (desc) order.

Syntax

$orderby=field [asc|desc]
$orderby=field1 [asc|desc],field2 [asc|desc]

If no direction is specified, ascending order is used by default.

Examples

Sort by name in ascending order:

# Sort matters alphabetically by name (A-Z)
GET /v2/matters?$orderby=Name asc

Sort by name in descending order:

# Sort matters reverse-alphabetically by name (Z-A)
GET /v2/matters?$orderby=Name desc

Sort by multiple fields:

# Sort by name ascending, then by status descending
GET /v2/matters?$orderby=Name asc,Status desc

Note: Not all fields support sorting. Refer to the Supported resources section below for a list of sortable fields for each resource type.

Filtering with $filter

The $filter query option allows you to filter results based on field values using comparison operators, logical operators, and collection operators.

Comparison operators

OperatorDescriptionExample
eqEqualName eq 'Project Alpha'
eq nullEqual nullName eq null
neNot equalStatus ne 'Active'
ne nullNot equal nullName ne null
gtGreater thanCreated/DateUtc gt '2024-01-01'
geGreater than or equalCreated/DateUtc ge '2024-01-01T12:30:00Z'
ltLess thanId lt 1234
leLess than or equalFields/slider le 5
containsContainsContains(name, 'Alpha')

Filter examples

# Filter by exact match
GET /v2/matters?$filter=Status eq 'Active'

# Filter by greater than
GET /v2/matters?$filter=Created/DateUtc gt '2024-01-01'

# Filter where a field is null
GET /v2/matters?$filter=ExternalId eq null

# Filter where a field is not null
GET /v2/matters?$filter=ExternalId ne null

# Filter by contains
GET /v2/matters?$filter=contains(Name, 'Alpha')

Note: Not all fields support all comparisons. Refer to the Supported resources section below for a list of sortable fields for each resource type.

Logical operators

Combine multiple conditions using logical operators:

OperatorDescriptionExample
andLogical ANDStatus eq 'Active' and Restricted eq false
orLogical ORStatus eq 'Active' or Status eq 'Draft'

Collection operators

The any operator iterates over a collection and returns true if at least one item matches the specified condition.

collectionProperty/any(property:property <operator> <value>)
collectionProperty/any(property:property/subProperty <operator> <value>)

Where:

  • collectionProperty is the path to the collection
  • property is a lambda variable representing each item in the collection
  • subProperty is a reference to a sub property on the collection entity when the entity is another entity
  • operator is a comparison operator
  • value is the value to apply the operator to

Filter examples

# Filter matters where the lookup field contains 'option_a'
GET /v2/matters?$filter=Fields/lookup/any(lookup:lookup/value eq 'option_a')

# Filter matters where the lookup field contains either 'option_a' or 'option_b'
GET /v2/matters?$filter=Fields/lookup/any(lookup:lookup/value eq 'option_a' or lookup/value eq 'option_b')

Note: The any operator only supports or logic within the lambda expression. Using and logic within an any expression is not supported.

Note: Not all collection properties support the any operator. Refer to the specific endpoint documentation and the Supported resources section in this guide for details on which collections can be filtered.

Grouping with parentheses

Use parentheses to group conditions and control evaluation order:

# Filter for non-restricted matters that are either Active or Draft
GET /v2/matters?$filter=(Status eq 'Active' or Status eq 'Draft') and Restricted eq false

Nested properties

Some fields represent nested objects. Use the forward slash (/) to access nested properties in filter and orderby expressions.

Example:

# Filter matters by the owner's user ID
GET /v2/matters?$filter=Owner/Id eq '12345678-1234-1234-1234-123456789abc'

# Filter matters by the ID of the user who created them
GET /v2/matters?$filter=Created/User/Id eq '12345678-1234-1234-1234-123456789abc'

Error handling

When an invalid OData query is submitted, the API returns a 400 Bad Request response with details about the error.

Note: Refer to the Errors documentation for more information.

Common error scenarios

Unsupported field:

{
  "type": "https://api-docs.lawvu.com/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "OData filtering is not supported for 'unsupportedField'"
}

Unsupported operator:

{
  "type": "https://api-docs.lawvu.com/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "Operation 'gt' is not supported for 'Name'"
}

Invalid $top value:

{
  "type": "https://api-docs.lawvu.com/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "OData $top value must be less than 50"
}

Invalid query syntax:

{
  "type": "https://api-docs.lawvu.com/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "The OData query is invalid. Please check the syntax and try again"
}

Supported resources

The following sections describe the resources and the properties on the resource which are supported for OData filtering and ordering.

Field Options

All field types support the following base filtering:

PropertyFilter OperationsFunctionsSortable
Labeleq, necontains()
Valueeq, ne-

The following types additionally support filtering on properties:

LawVu Application TypePropertyFilter OperationsFunctions
DepartmentProperties.parentIdeq, eq null, ne, ne null-

Contracts

PropertyFilter OperationsFunctionsSortable
Ideq, ne-
Nameeq, necontains()
Type/Ideq, ne--
Owner/Ideq, ne-
ExternalIdeq, necontains()-
FieldsRefer to fields--
Restrictedeq, ne--
Statuseq, ne--
TeamAssigned/Ideq, ne-
Created/User/Ideq, ne--

Matters

PropertyFilter OperationsFunctionsSortable
Ideq, ne-
Nameeq, necontains()
DisplayIdeq, necontains()-
Type/Ideq, ne--
Owner/Ideq, ne-
Manager/User/Ideq, eq null, ne, ne null-
Manager/IntakeQueue/OrganizationIdeq, eq null, ne, ne null--
ExternalIdeq, necontains()-
FieldsRefer to fields--
Restrictedeq, ne--
Statuseq, ne--
TeamAssigned/Ideq, ne-
Created/User/Ideq, ne--

Fields on Matters and Contracts

Refer to the below table for supported operations when filtering or sorting by matters/contract field values.

Field TypeFilter OperationsFunctionsSortable
Texteq, eq null, ne, ne nullcontains()-
Decimaleq, eq null, ne, ge, le--
Decimal (Slider)eq, ne, ge, le--
Booleaneq--
Datege, lt, le--
Option/Valueeq, eq null, ne, ne null--
MultiOption/Valueeq--
User/Ideq, eq null, ne, ne null--

Note: Refer to fields documentation for information on how the field type maps to the LawVu application.