Providing you are a LUSID user with sufficient privileges, you can create a system event handler that automatically creates or updates a task in the Workflow Service when:
A system event occurs in LUSID, for example, you could create an event handler for the
FileCreated
event that creates a new task to import quotes and check them for outliers when a CSV file arrives in DriveWhen a business calendar-aware schedule is triggered
Methods
Call the CreateEventHandler API. The fields you must supply depend on your matching pattern type.
For an eventMatchingPattern
, the following example creates an event handler that creates an Import-Quotes-From-File task when a file is uploaded to the /quotes
folder in Drive:
curl -X POST "https://<your-domain>.lusid.com/workflow/api/eventhandlers"
-H "Authorization: Bearer <your-api-access-token>"
-H "Content-Type: application/json-patch+json"
-d "{
"id": {
"scope": "Finbourne-Examples",
"code": "New-Quotes-File"
},
"displayName": "NewQuotesFileInDrive",
"description": "Event handler that creates a quote import and data quality check task when a new file arrives in the quotes folder in Drive.",
"status": "Active",
"eventMatchingPattern": {
"eventType": "FileCreated",
"filter": "body.filePath startswith '/<your-domain>/quotes'"
},
"runAsUserId": {
"setTo": "00uji4ve5haBc1Hlf2p7"
},
"taskDefinitionId": {
"scope": "Finbourne-Examples",
"code": "Import-Quotes-From-File"
},
"taskActivity": {
"initialTrigger": "start",
"type": "CreateNewTask",
"taskFields": {
"folder":
{ "mapFrom": "body.filePath" },
"quoteScope":
{ "setTo": "Finbourne-Examples" }
}
}
}"
For a scheduleMatchingPattern
, you might send the following in the request body to create a daily run-reconciliation task for the previous day, between the 1st and 8th August:
{
"id": {
"scope": "Finbourne-Examples",
"code": "Daily-Reconciliation"
},
"displayName": "Daily Reconciliation Schedule",
"description": "Creates reconciliation tasks on business days with appropriate effective dates",
"status": "Active",
"taskDefinitionId": {
"scope": "Finbourne-Examples",
"code": "run-reconciliation"
},
"runAsUserId": { "setTo": "00u5mi3egiUNgaCtW2p7" },
"scheduleMatchingPattern": {
"context": { "timeZone": "GB" },
"recurrencePattern": {
"timeConstraints": {
"startDate": "2025-08-01",
"endDate": "2025-08-09",
"timesOfDay": [ {
"type": "Specified",
"hours": 10,
"minutes": 30
}, {
"type": "Specified",
"hours": 10,
"minutes": 45
} ]
},
"dateRegularity": {
"type": "Day",
"frequency": 1
},
"businessDayAdjustment": "Following"
}
},
"taskActivity": {
"type": "CreateNewTask",
"scheduleDependentTaskFields": {
"effectiveDate": {
"dateAdjustment": {
"deltaDays": -1,
"businessDayAdjustment": "Following"
},
"timeAdjustment": {
"setTo": {
"type": "Specified",
"hours": 17,
"minutes": 0
}
}
},
"processingDate": {
"dateAdjustment": {
"deltaDays": 1,
"businessDayAdjustment": "Following"
},
"timeAdjustment": {
"setTo": {
"type": "Specified",
"hours": 9,
"minutes": 15
}
}
}
}
}
}
Coming soon.
Coming soon.
Once you have created an event handler, you can monitor tasks in the LUSID web app by navigating via the top left menu to Workflow Service > Dashboard:
Fields
You should specify either:
An
eventMatchingPattern
for system event triggersA
scheduleMatchingPattern
for scheduled triggers
eventMatchingPattern
For an event handler that can trigger task transitions when system events occur in LUSID, you must specify:
The system event you want to handle under
eventType
. See what system events you can handle.Optionally, a
filter
to handle the specified system event conditionally. See how to use LUSID filtering syntax.
scheduleMatchingPattern
For an event handler that can trigger task transitions on a schedule, you must specify:
The schedule
context
, containing:A
timeZone
as an ISO country code or IANA timezone identifier.Optionally, one or more
holidayCalendars
to define business days. You can retrieve thescope
andcode
of your calendars by calling the ListCalendars API.
The
recurrencePattern
for when and how often to trigger the schedule, containing:timeConstraints
:When the schedule should come into effect as
startDate
Optionally, when the schedule should end as
endDate
The
timesOfDay
the schedule should trigger at. You can specify one or more cut labels, or specific times.
One of the following
dateRegularity
types to define how often the schedule should repeat and on which specific dates:Day
: Thefrequency
value tells the schedule to trigger everyx
days.SpecificMonth
:The
frequency
value tells the schedule to trigger everyx
months.The
daysOfMonth
value tells the schedule to trigger on thex
day of the month, for example-1
defines this as the last day of the month.
RelativeMonth
:The
frequency
value tells the schedule to trigger everyx
months.The
daysOfWeek
value tells the schedule to trigger on particular days.The
index
value tells the schedule the relative position in the month to trigger, for exampleFirst
,Third
, orLast
.
Week
:The
frequency
tells the schedule to trigger everyx
weeks.The
dayOfWeek
tells the schedule to trigger on particular days of that week.
Year
: One or moremonth
andday
combinations that tell the schedule to trigger every year on a particular date.
One of the following
businessDayAdjustment
values to define the business day convention for the schedule:Following
Preceding
ModifiedFollowing
ModifiedPreceding
None
Click to expand example: Trigger a workflow on every hour, every day
...
"scheduleMatchingPattern": {
"context": {
"timeZone": "UTC"
},
"recurrencePattern": {
"timeConstraints": {
"startDate": "2025-08-01",
"endDate": "2025-09-01",
"timesOfDay": [
{
"type": "Specified",
"hours": 0,
"minutes": 0
},
{
"type": "Specified",
"hours": 1,
"minutes": 0
},
{
"type": "Specified",
"hours": 2,
"minutes": 0
},
{
"type": "Specified",
"hours": 3,
"minutes": 0
},
{
"type": "Specified",
"hours": 4,
"minutes": 0
},
{
"type": "Specified",
"hours": 5,
"minutes": 0
},
{
"type": "Specified",
"hours": 6,
"minutes": 0
},
{
"type": "Specified",
"hours": 7,
"minutes": 0
},
{
"type": "Specified",
"hours": 8,
"minutes": 0
},
{
"type": "Specified",
"hours": 9,
"minutes": 0
},
{
"type": "Specified",
"hours": 10,
"minutes": 0
},
{
"type": "Specified",
"hours": 11,
"minutes": 0
},
{
"type": "Specified",
"hours": 12,
"minutes": 0
},
{
"type": "Specified",
"hours": 13,
"minutes": 0
},
{
"type": "Specified",
"hours": 14,
"minutes": 0
},
{
"type": "Specified",
"hours": 15,
"minutes": 0
},
{
"type": "Specified",
"hours": 16,
"minutes": 0
},
{
"type": "Specified",
"hours": 17,
"minutes": 0
},
{
"type": "Specified",
"hours": 18,
"minutes": 0
},
{
"type": "Specified",
"hours": 19,
"minutes": 0
},
{
"type": "Specified",
"hours": 20,
"minutes": 0
},
{
"type": "Specified",
"hours": 21,
"minutes": 0
},
{
"type": "Specified",
"hours": 22,
"minutes": 0
},
{
"type": "Specified",
"hours": 23,
"minutes": 0
}
]
},
"dateRegularity": {
"type": "Day",
"frequency": 1
},
"businessDayAdjustment": "None"
}
},
...
For schedule-based handlers, you can use either:
taskFields
to populate static field values, as with system event handlersscheduleDependentTaskFields
to set dynamic field values that transform the scheduled datetime for your task fields. For each task field, you can specify:dateAdjustment
to modify the date relative to the schedule trigger:A positive or negative number of days, weeks, months, and/or years to add or subtract:
deltaDays
deltaWeeks
deltaMonths
deltaYears
businessDayAdjustment
values to define the business day convention for the schedule:Following
Preceding
ModifiedFollowing
ModifiedPreceding
None
timeAdjustment
to modify the time; you can use either:setTo
to set the value to a specific time:type
value ofSpecified
for fixed timesAn
hours
value between0
and23
A minutes value between
0
and59
addTime
to modify the existing scheduled time:An
hours
value between0
and23
A
minutes
value between0
and59
taskActivity
The taskActivity
to perform when a matching system event occurs. There are two types of activity:
To create a new task, specify:
A
type
value ofCreateNewTask
An
initialTrigger
to prompt a state transition when the task is kicked offtaskFields
to define mapping for the task field values. For each task field you want to populate, specify the name and either:Use
mapFrom
to map the task field value from a particular event fieldUse
setTo
to set the task field to a particular value
To update existing open tasks, specify:
A
type
value ofUpdateMatchingTasks
Optionally, a
filter
to update existing open tasks conditionally. See how to use LUSID filtering syntax.A
trigger
to prompt a state transitiontaskFields
to define mapping for the task field values. For each task field you want to populate, specify the name and either:Use
mapFrom
to map the task field value from a particular event fieldUse
setTo
to set the task field to a particular value
runAsUserId
A value for runAsUserId
to create or update the task on behalf of a service user. Read more about this. Either:
Use
mapFrom
with the valueheader.userId
to map from the user ID of the user who created the event.Use
setTo
to set the value to a particular service user ID.
taskDefinitionAsAt
A taskDefinitionAsAt
to control the task definition version used by the system event handler. If omitted, the value defaults to the current datetime.