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
FileCreatedevent 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
eventMatchingPatternfor system event triggersA
scheduleMatchingPatternfor 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
filterto 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
timeZoneas an ISO country code or IANA timezone identifier.Optionally, one or more
holidayCalendarsto define business days. You can retrieve thescopeandcodeof your calendars by calling the ListCalendars API.
The
recurrencePatternfor when and how often to trigger the schedule, containing:timeConstraints:When the schedule should come into effect as
startDateOptionally, when the schedule should end as
endDateThe
timesOfDaythe schedule should trigger at. You can specify one or more cut labels, or specific times.
One of the following
dateRegularitytypes to define how often the schedule should repeat and on which specific dates:Day: Thefrequencyvalue tells the schedule to trigger everyxdays.SpecificMonth:The
frequencyvalue tells the schedule to trigger everyxmonths.The
daysOfMonthvalue tells the schedule to trigger on thexday of the month, for example-1defines this as the last day of the month.
RelativeMonth:The
frequencyvalue tells the schedule to trigger everyxmonths.The
daysOfWeekvalue tells the schedule to trigger on particular days.The
indexvalue tells the schedule the relative position in the month to trigger, for exampleFirst,Third, orLast.
Week:The
frequencytells the schedule to trigger everyxweeks.The
dayOfWeektells the schedule to trigger on particular days of that week.
Year: One or moremonthanddaycombinations that tell the schedule to trigger every year on a particular date.
One of the following
businessDayAdjustmentvalues to define the business day convention for the schedule:FollowingPrecedingModifiedFollowingModifiedPrecedingNone
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:
taskFieldsto populate static field values, as with system event handlersscheduleDependentTaskFieldsto set dynamic field values that transform the scheduled datetime for your task fields. For each task field, you can specify:dateAdjustmentto modify the date relative to the schedule trigger:A positive or negative number of days, weeks, months, and/or years to add or subtract:
deltaDaysdeltaWeeksdeltaMonthsdeltaYears
businessDayAdjustmentvalues to define the business day convention for the schedule:FollowingPrecedingModifiedFollowingModifiedPrecedingNone
timeAdjustmentto modify the time; you can use either:setToto set the value to a specific time:typevalue ofSpecifiedfor fixed timesAn
hoursvalue between0and23A minutes value between
0and59
addTimeto modify the existing scheduled time:An
hoursvalue between0and23A
minutesvalue between0and59
taskActivity
The taskActivity to perform when a matching system event occurs. There are two types of activity:
To create a new task, specify:
A
typevalue ofCreateNewTaskAn
initialTriggerto prompt a state transition when the task is kicked offtaskFieldsto define mapping for the task field values. For each task field you want to populate, specify the name and either:Use
mapFromto map the task field value from a particular event fieldUse
setToto set the task field to a particular value
To update existing open tasks, specify:
A
typevalue ofUpdateMatchingTasksOptionally, a
filterto update existing open tasks conditionally. See how to use LUSID filtering syntax.A
triggerto prompt a state transitiontaskFieldsto define mapping for the task field values. For each task field you want to populate, specify the name and either:Use
mapFromto map the task field value from a particular event fieldUse
setToto 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
mapFromwith the valueheader.userIdto map from the user ID of the user who created the event.Use
setToto 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.