Skip to content

GraphQL API Definition ​

The following document outlines the AireFlow GraphQL API, available at /api/graphql/v2.

Tasks ​

The tasks query can be used to read all instantiated tasks. There are currently no mutations available via GraphQL and any changes will need to be made via the REST API.

Query Structure ​

The following properties can be retrieved via the GraphQL API

query {
    tasks {
        nodes {
            id
            taskKey
            name
            description
            taskType
            subjectId
            correlationId
            assigneeId
            assigneeType
            canSetAssignee
            owner
            ownerType
            workflowDefinitionVersion
            workflowDefinitionId
            workflowDefinitionKey
            filters
            context
            created
            updated
            lastRun
            activityContext {
                status
                ...on ManualActivityContext {
                    due
                }
                ...on EmailActivityContext {
                    to
                    subject
                    body
                    retryCount
                }
                ...on HttpActivityContext {
                    url
                    body
                    contentType
                    headers
                    retryCount
                }
                ...on AireFrameCreateFormActivityContext {
                    key
                    version
                    subjectId
                    userId
                    retryCount
                }
                ...on PublishEventActivityContext {
                    eventKey
                    retryCount
                }
                ...on FormActivityContext {
                    key
                    version
                    instanceId
                    due
                }
            }
            state {
                key
                value
            }
            transitions {
                from
                to
                description
            }
        }

        # pageCount and itemCount count every matching task, which can be slow on large
        # result sets. Only select them when absolutely necessary. Not available with cursorPaging.
        pageCount
        itemCount

        # Only available when using cursor paging
        pageInfo {
            hasNextPage
            endCursor
        }
    }
}

Filtering ​

The filter parameter is used as follows. Each item in the filter array must be true for a task to be included in the result:

query {
    tasks (
        filter:[{
            property: "activityContext.status"
            condition: EQ
            value: ["New", "InProgress"]
    },
    {
            property: "assigneeId"
            condition: EQ
            value: "1"
    },    
    {
            property: "assigneeType"
            condition: EQ
            value: "Subject"
    },
    {
            property: "state[comments]"
            condition: INCLUDES
            value: "Some Comment"
    }
    ]) {
        ...
    }
}

Where property is the name of the property to filter, condition defines what type of filter is applied and value is the value the condition is checked against. The value can be a string or an array of strings (in some cases). In the above example, the status must be either new or in progress, the assigneeId must be 1 and there is a state item called "comments" who's value includes the substring "Some Comment".

In order to access a nested property, separate them using a '.' as above.

For dictionaries, use {property}.key to filter on the keys, use {property}[{key name}] to filter on the value of a specific key.

Types of Filter ​

Each property type has a subset of valid conditions listed here.

Property TypeValid ConditionsAccepts Array ValueTrue When
stringEQTrueProperty value equals one of the input values (Case-Sensitive)
NOTTrueProperty value does not equal one of the input values (Case-Sensitive)
INCLUDESTrueOne of the input values is a substring of the property value (Case-Sensitive)
DateTimeLTFalseProperty value is before than the input value
GTFalseProperty value is after the input value
IntEQFalseProperty value is equal to the input value
GTFalseProperty value is greater than the input value
LTFalseProperty value is less than the input value
ListAnyEqFalseProperty list contains the input value
NoneEqFalseProperty list does not contain the input value
EnumEQTrueProperty value equals one of the input values
NOTTrueProperty value does not equal one of the input values
INCLUDESTrueOne of the input values is a substring of the property value
Dictionary KeyAnyEqTrueInput value is a key in the dictionary
NoneEqTrueInput value is not a key in the dictionary
Dictionary ValueEQTrueProperty value equals one of the input values (Case-Sensitive)
NOTTrueProperty value does not equal one of the input values (Case-Sensitive)
INCLUDESTrueOne of the input values is a substring of the property value (Case-Sensitive)

Sorting ​

The sorting parameter is used as follows. The direction is either ASCENDING or DESCENDING.

query {
    tasks (
        sort: {
            property: "activityContext.due"
            direction: ASCENDING
        }
    ) {
        ...
    }
}

Paging ​

Two types of paging are supported: cursor paging and offset paging. Cursor paging is recommended where possible. Only one of cursorPaging and paging may be supplied in a query.

Cursor Paging ​

Cursor (keyset) paging returns results that stay consistent while tasks are being created or updated, and it performs better on large result sets than offset paging. Use the cursorPaging parameter as follows:

query {
    tasks (
        sort: {
            property: "updated"
            direction: DESCENDING
        }
        cursorPaging: {
            first: 50
        }
    ) {
        pageInfo {
            hasNextPage
            endCursor
        }
        nodes {
            ...
        }
    }
}

Where first is the number of tasks to return (between 1 and 1000) and after is an optional cursor to start from. To get the next page, pass the endCursor from the previous response as after, with the same filter and sort:

query {
    tasks (
        sort: {
            property: "updated"
            direction: DESCENDING
        }
        cursorPaging: {
            first: 50
            after: "<endCursor from the previous page>"
        }
    ) {
        ...
    }
}

Continue until hasNextPage is false. If a page contains no tasks, endCursor is null.

Cursor paging has the following restrictions:

  • The sort property must be created or updated. If no sort is supplied, tasks are sorted by created, descending.
  • pageCount and itemCount cannot be selected, because cursor paging never counts the full result set. Use offset paging if you absolutely must have a total (but be aware that performance will be poor for large data sets).
  • A cursor only works with the filter and sort it was returned for. If you change the filter or sort, start again from the first page without an after value.
  • Treat cursors as opaque strings. Don't construct or modify them.

Offset Paging ​

Offset paging is still supported for backwards compatibility. Use the paging parameter as follows:

query {
    tasks (
        paging: {
            pageNumber: 1,
            pageSize: 50
        }
    ) {
        ...
    }
}

pageCount and itemCount are only available with offset paging. pageInfo is only populated when cursorPaging is used.

Selecting pageCount or itemCount makes AireFlow count every task that matches the filter, which can be slow when there are a lot of tasks. The count only runs if one of these fields is selected, so leave them out unless you need a total.