Skip to main content

Instance Filtering Guide

Overview

The vNext workflow system provides powerful filtering capabilities for querying instances. You can filter on both Instance table columns and JSON data fields using either legacy format or GraphQL-style JSON format.

Supported Routes

Use this route for listing and filtering workflow instances (including GetInstancesTask and integrations that replaced the old workflow-level patterns):

GET /{domain}/workflows/{workflow}/instances?filter={...}

2. Function/Data route (instance-scoped data)

GET /{domain}/workflows/{workflow}/instances/{instance}/functions/data?filter={...}

Note: For bulk / workflow-level queries, prefer .../instances?filter=.... The unscoped GET .../workflows/{workflow}/functions/data pattern is not the supported path for GetInstancesTask as of (see release notes (Phase 3 — Release Notes)).

Both supported list/filter entry points use the same filter query parameter semantics where applicable.


Filter Formats

Legacy Format

Simple key-value format: field=operator:value

JSON-based format with logical operator support: {"field":{"operator":"value"}}

** breaking change:** The filter parameter must be a single expression (one JSON object or string). The previous array format "filter": ["expr1", "expr2"] is no longer supported. Use a single expression; combine conditions with and/or inside that expression (e.g. {"and":[{"status":{"eq":"Active"}},{"attributes.amount":{"gt":"500"}}]}).


Filterable Fields

Instance Table Columns

Direct database columns:

ColumnTypeDescriptionSupported Operators
keystringInstance keyeq, ne, like, startswith, endswith, in, nin
flowstringWorkflow nameeq, ne, like, startswith, endswith, in, nin
statusstringInstance statuseq, ne, in, nin
currentState (or state)stringCurrent stateeq, ne, like, startswith, endswith, in, nin
effectiveStatestringEffective state nameeq, ne, like, startswith, endswith, in, nin
effectiveStateTypeintEffective state type codeeq, ne, gt, ge, lt, le, in, nin
effectiveStateSubTypeintEffective state subtype code (+;: 7 = Cancelled, 8 = Timeout)eq, ne, gt, ge, lt, le, in, nin
createdAtDateTimeCreation timeeq, ne, gt, ge, lt, le, between
modifiedAtDateTimeModification timeeq, ne, gt, ge, lt, le, between
completedAtDateTimeCompletion timeeq, ne, gt, ge, lt, le, between
isTransientbooleanTransient flageq, ne

JSON Data Fields (attributes)

Any field stored in the instance's JSON data can be filtered using the attributes prefix.


Supported Operators

OperatorDescriptionExample Value
eqEquals"1111"
neNot equals"test"
gtGreater than"100"
geGreater than or equal"100"
ltLess than"100"
leLess than or equal"100"
betweenBetween (inclusive)["2024-01-01", "2024-12-31"]
likeContains (case insensitive)"workflow"
startswithStarts with"payment"
endswithEnds with"flow"
inIn list["Active", "Busy"]
ninNot in list["Completed", "Faulted"]
isnullNull or not nulltrue or false

Status Values

The status field accepts both code and name:

Status NameCodeDescription
ActiveAInstance is active
BusyBInstance is processing
CompletedCInstance completed successfully
FaultedFInstance encountered an error
PassivePInstance is passive

: Filtering on status and state (currentState) now works correctly in instance queries.


OrderBy / Sort

Instance list and data endpoints support sorting via the sort or orderBy query parameter.

Single field

?sort={"field":"createdAt","direction":"desc"}
?orderBy={"field":"status","direction":"asc"}

Multiple fields

?sort={"fields":[{"field":"status","direction":"asc"},{"field":"createdAt","direction":"desc"}]}
  • direction: "asc" or "desc" (case-insensitive). Defaults to "asc" if omitted.

Sortable fields

FieldNotes
createdAtCreation timestamp
modifiedAtModification timestamp
completedAtCompletion timestamp
statusInstance status
keyInstance key
currentState / stateCurrent state (state is alias)
attributes.fieldNameJSON path into instance data; nested paths supported (e.g. attributes.nested.path)

Instance columns are applied in the database; ordering by attributes.* uses the latest instance data JSON and is subject to the same schema/security as filtering.


GraphQL Format Examples

1. Simple Instance Column Filter

GET /banking/workflows/payment-workflow/instances?filter={"key":{"eq":"payment-12345"}}

2. Multiple Instance Column Filters (AND Logic)

Multiple fields at the same level are combined with AND logic:

GET /banking/workflows/payment-workflow/instances?filter={"status":{"eq":"Active"},"createdAt":{"gt":"2024-01-01"}}

3. JSON Data Field Filter (attributes)

Filter on JSON data fields using the attributes prefix:

GET /banking/workflows/payment-workflow/instances?filter={"attributes":{"customerId":{"eq":"CUST-123"}}}

4. Mixed Filter (Instance + JSON Fields)

GET /banking/workflows/payment-workflow/instances?filter={"key":{"like":"payment"},"status":{"eq":"Active"},"attributes":{"amount":{"gt":"500"}}}

5. Date Range Filter

GET /banking/workflows/payment-workflow/instances?filter={"createdAt":{"between":["2024-01-01","2024-01-31"]}}

6. Status IN Filter

GET /banking/workflows/payment-workflow/instances?filter={"status":{"in":["Active","Busy"]}}

7. EffectiveState Filters

Filter by Effective State Name:

GET /banking/workflows/payment-workflow/instances?filter={"effectiveState":{"eq":"awaiting-approval"}}

Filter by Effective State SubType (Human Tasks):

GET /approvals/workflows/approval-flow/instances?filter={"effectiveStateSubType":{"eq":"6"}}

Filter by Effective State SubType (Busy Tasks):

GET /processing/workflows/order-flow/instances?filter={"effectiveStateSubType":{"eq":"5"}}

Combined Status and EffectiveState Filter:

GET /core/workflows/payment/instances?filter={"status":{"eq":"Active"},"effectiveStateSubType":{"eq":"6"}}

EffectiveState SubType Values:

  • 0 - None
  • 1 - Success
  • 2 - Error
  • 3 - Terminated
  • 4 - Suspended
  • 5 - Busy (processing in progress)
  • 6 - Human (human interaction required)

Logical Operators

AND Operator

Combines multiple conditions where all must be true:

{
"and": [
{"status": {"eq": "Active"}},
{"attributes": {"amount": {"gt": "500"}}}
]
}

OR Operator

Combines multiple conditions where any can be true:

{
"or": [
{"key": {"eq": "payment-12345"}},
{"key": {"eq": "payment-12346"}}
]
}

NOT Operator

Negates a condition:

{
"not": {"status": {"in": ["Completed", "Faulted"]}}
}

Complex Nested Example

{
"and": [
{"status": {"eq": "Active"}},
{
"or": [
{"attributes": {"priority": {"eq": "high"}}},
{"attributes": {"amount": {"gt": "10000"}}}
]
}
]
}

Group By and Aggregations

Group By with Count

GET /banking/workflows/payment-workflow/instances?filter={"groupBy":{"field":"attributes.status","aggregations":{"count":true}}}

Response:

{
"groups": [
{"name": "pending", "count": 45},
{"name": "approved", "count": 123},
{"name": "rejected", "count": 12}
]
}

Group By with Multiple Aggregations

GET /banking/workflows/payment-workflow/instances?filter={"groupBy":{"field":"attributes.currency","aggregations":{"count":true,"sum":"attributes.amount","avg":"attributes.amount","min":"attributes.amount","max":"attributes.amount"}}}

Response:

{
"groups": [
{"name": "USD", "count": 150, "sum": 450000, "avg": 3000, "min": 10, "max": 50000},
{"name": "EUR", "count": 75, "sum": 180000, "avg": 2400, "min": 50, "max": 25000}
]
}

Supported Aggregations

AggregationDescription
countCount of items in group
sumSum of numeric field
avgAverage of numeric field
minMinimum value
maxMaximum value

Best Practices

1. Use GraphQL Format for Complex Queries

GraphQL format is more readable and supports logical operators.

Good:

{
"and": [
{"status": {"eq": "Active"}},
{"attributes": {"amount": {"gt": "500"}}}
]
}

2. Use Specific Fields for Better Performance

Filter on indexed Instance columns when possible.

Better Performance:

{"key": {"eq": "payment-12345"}}

Slower:

{"attributes": {"unindexedField": {"eq": "value"}}}

3. Use Status Names for Readability

{"status": {"eq": "Active"}}

is equivalent to:

{"status": {"eq": "A"}}

4. Use Group By for Analytics

When you need statistics, use group by instead of fetching all records.

{
"groupBy": {
"field": "attributes.status",
"aggregations": {"count": true, "sum": "attributes.amount"}
}
}

5. Always Use Pagination

Always use page and pageSize parameters:

GET /banking/workflows/payment-workflow/instances?filter={...}&page=1&pageSize=20

Error Handling

Invalid Filter Syntax

{
"error": {
"code": "invalid_filter",
"message": "Invalid filter syntax. Valid JSON expected."
}
}

Unsupported Operator

{
"error": {
"code": "unsupported_operator",
"message": "'regex' operator is not supported",
"supportedOperators": ["eq", "ne", "gt", "ge", "lt", "le", "between", "like", "startswith", "endswith", "in", "nin", "isnull"]
}
}

Invalid Column Name

{
"error": {
"code": "invalid_column",
"message": "'invalidColumn' is not a valid Instance column. Use 'attributes.fieldName' for JSON fields.",
"validColumns": ["key", "flow", "status", "currentState", "createdAt", "modifiedAt", "completedAt", "isTransient"]
}
}

Performance Tips

  1. Use Pagination: Always use page and pageSize parameters
  2. Filter on Indexed Columns: Prefer key, status, createdAt for better performance
  3. Limit Group By Fields: Use maximum 2-3 fields for optimal performance
  4. Use Date Ranges Wisely: Narrow date ranges improve query performance
  5. Avoid Wildcard Searches on Large Datasets: Use startswith or endswith instead of like when possible