Skip to main content

Scheduler Module

Pause a workflow on a timer, start it on a schedule, or book a future run with custom data.

The Scheduler Module adds five time-based Tasks to your Process, plus the Reminder start. WaitFor and WaitUntil pause the current Session; ScheduleRecurring and ScheduleOnce start new Sessions on a recurring or one-time schedule; ScheduleReminder books a one-time future Session carrying custom data the classic appointment-reminder pattern; the Reminder start is where that Session begins, with the data as {reminder}. The Module does not require any Environment configuration.

How it works​

The five Tasks fall into two groups:

  • Pausing Tasks WaitFor and WaitUntil are Intermediate Catch Events. When the Token reaches one, the Session pauses; at the wake time it resumes from the same node and continues along the Sequence Flow.
  • Scheduling Tasks ScheduleRecurring and ScheduleOnce are Start Events: alternative entry points into your Process. Each time the schedule is due, a fresh, independent Session starts. ScheduleReminder is a regular Task: it books one future Session (optionally with data) and lets the calling Session continue immediately.

All schedule times are kept in UTC: the editor shows and takes them in the workspace time zone, but a stored time does not follow daylight saving. The platform checks due schedules about every 15 seconds, so anything you schedule fires within roughly 15 seconds of its due time. A Session started by a schedule begins on the Scheduler Channel, and a reminder on the Reminder Channel, unless you set the Task's Channel property. All five Tasks are generic they behave the same regardless of the Channel the Session runs on.

Deploying a new Process version updates your recurring and one-time schedules to match the diagram. It never cancels waits or reminders that are already in flight those belong to running Sessions and fire as planned. Every pending schedule, wait, and reminder is listed on the Scheduled tasks page, where you can also run, turn off or delete them, and set up repeats of your own.

Configuration​

This Module does not require Environment configuration.

Everything is configured on the Task nodes themselves in the Process Editor.

Limits​

  • A single wait or reminder can reach at most 1 year into the future.
  • Schedules fire within about 15 seconds of their due time do not rely on sub-second precision.
  • A scheduled time up to 5 minutes in the past is accepted (clock tolerance) and fires immediately; anything earlier is rejected.

Tasks​

WaitFor (Generic)​

Pauses the current Session for a fixed duration "wait 24 hours, then send the follow-up". Add it as an Intermediate Catch Event.

Properties​

PropertyTypeRequiredExampleDescription
AmountnumberYes24How many of the chosen unit to wait. Must be positive; the total wait (Amount × Unit) is capped at 1 year.
UnitselectionYesHoursTime unit applied to Amount. Options: Seconds, Minutes, Hours, Days, Weeks. Default: Hours.

Behavior​

  1. When the Token reaches this node, the Task computes the wake time the current time plus Amount × Unit and pauses the Session.
  2. At the wake time the Session resumes from this node and the Token continues along the outgoing Sequence Flow.

Example​

A welcome workflow sends a sign-up confirmation, then a WaitFor with Amount 24 and Unit Hours, then an onboarding tip message. A Session that reaches the wait on Tuesday at 10:00 UTC resumes on Wednesday at about 10:00 UTC and sends the tip.

tip

WaitFor is always relative ("24 hours from now"). If you need to wake at a specific moment "at 09:00 on December 31" use WaitUntil instead.

WaitUntil (Generic)​

Pauses the current Session until a specific UTC datetime, then resumes. Add it as an Intermediate Catch Event.

Properties​

PropertyTypeRequiredExampleDescription
Wait untilstringYes2026-12-31T09:00:00Z or {expiresAtUtc}The UTC instant to resume at. Accepts an ISO-8601 datetime (2026-03-25T10:00:00Z), an RFC 1123 datetime, or a {variable} holding one. A time up to 5 minutes in the past is accepted and resumes immediately; the maximum is 1 year ahead.

Behavior​

  1. The Task resolves any {variable} in the field against the Session, then parses the result as a datetime.
  2. The Session pauses at this node.
  3. At the given instant the Session resumes from this node and the Token continues.

Example​

A subscription workflow stores the expiry instant in expiresAtUtc = 2026-12-31T23:59:00Z. A WaitUntil node with Wait until {expiresAtUtc} pauses the Session until that moment; the next node then revokes the customer's access.

ScheduleRecurring (Generic)​

A Start Event that begins a new Session of your Process on a recurring schedule every five minutes, hourly, daily, weekly, monthly, or any custom cron cadence. You enter the time of day in the workspace time zone; it is kept in UTC, so after a daylight-saving change the run comes an hour earlier or later in local time. Each key in Data becomes a start variable.

Properties​

PropertyTypeRequiredExampleDescription
RepeatselectionYesDailyThe cadence. Options: EveryFiveMinutes, EveryHour, Daily, Weekly, Monthly, CustomCron. Default: EveryHour. Daily, Weekly, and Monthly show At; Weekly adds On; Monthly adds Day of month; CustomCron shows Custom cron.
AtstringYes, for Daily / Weekly / Monthly09:30Time of day the schedule fires, picked in the workspace time zone (Settings; your browser's when the workspace has none) and stored as UTC HH:mm. The hint under the field names the zone and the stored time, e.g. Europe/Rome · stored 07:30 UTC, and says when a daylight-saving change moves it. Times use the 24-hour clock (type 17:00, not 5:00 PM). Default: 09:00.
OnstringYes, for WeeklyMON,WED,FRIDay chips, stored as comma-separated weekday tokens. Allowed (case-insensitive): MON, TUE, WED, THU, FRI, SAT, SUN. Default: MON,TUE,WED,THU,FRI.
Day of monthnumberYes, for Monthly1Calendar day the schedule fires each month, 1–31. If a month has fewer days, the schedule simply skips that month. Default: 1.
Custom cron (UTC)stringYes, for CustomCron0 9 * * MONStandard 5-field cron expression minute, hour, day-of-month, month, day-of-week evaluated in UTC. The cron builder lists its next runs in the workspace time zone.
If runs are missedchoiceNoOnly the latestWhat happens to runs that were due while the platform was down (an outage, a restart): Run all of them (each with its own planned time, up to 1,000), Only the latest (one run, for the most recent missed time) or Skip them (wait for the next time). Runs skipped while the Environment was switched off are never made up. Default: Run all of them.
ChannelchoiceNoSchedulerThe Channel the new Session starts on: Scheduler · no user to chat with (the default, right for almost every flow), one of the Channels this Process's starts serve, or Custom… to type another (letters, digits and underscores only).
DataJSONNo{ "report": "weekly" }Optional JSON object; each top-level key becomes a start variable of every run ({report}). The field lists the keys it found as you type. Every run also gets {schedule} (planned time, kind, who set it up).
warning

On stores short uppercase tokens (MON, TUE, …) this is different from the Date Module, whose day-name fields take full English names like Saturday,Sunday. Don't mix the two formats; a full name here fails the Deployment with a clear error.

Under the schedule fields the form shows When it runs: the next runs in the workspace time zone (three in the narrow panel, five in the wide one). A run that a daylight-saving change moves is marked, e.g. Mon 26 Oct 08:00 · clocks change for a 09:00 Europe/Rome schedule set in summer. A custom cron shows the same list in its cron builder.

Behavior​

  1. When you deploy the Process, the schedule is validated an invalid time, weekday token, day of month, or cron expression fails the Deployment with a message naming the bad field.
  2. At each due time the platform starts a fresh Session of the Process from this node.
  3. Each Session is independent: no state is shared between fires, and a long-running Session does not delay the next fire overlapping runs are allowed.
  4. If the schedule fails to start 10 times in a row, it is disabled so it stops failing on every fire; re-deploying the Process or Turn back on on the Scheduled tasks page re-arms it.

Example​

A report workflow should run at 09:00 Rome time on Monday, Wednesday, and Friday, in a workspace set to Europe/Rome. In October set Repeat Weekly, At 09:00 (the hint says Europe/Rome · stored 07:00 UTC), On Mon Wed Fri, Data { "report": "weekly" }, and deploy. Every Monday, Wednesday, and Friday at 07:00 UTC a new Session starts with {report} set to weekly, fetches the data, and posts the report. After the clocks go back on 25 October that is 08:00 Rome time; set At to 09:00 again in winter to keep 09:00.

ScheduleOnce (Generic)​

A Start Event that begins a new Session exactly once at a set UTC datetime, then switches itself off.

Properties​

PropertyTypeRequiredExampleDescription
Fire atstringYes2026-05-01T09:00:00ZThe UTC instant to fire, as an ISO-8601 datetime. Validated when you deploy: a time more than 5 minutes in the past, or more than 1 year ahead, fails the Deployment.
ChannelchoiceNoSchedulerThe Channel the new Session starts on: Scheduler · no user to chat with (the default), one of the Channels this Process's starts serve, or Custom… to type another (letters, digits and underscores only).
DataJSONNo{ "campaign": "may" }Optional JSON object; each top-level key becomes a start variable of the run. The run also gets {schedule}.

Behavior​

  1. When you deploy the Process, the fire time is validated and the schedule is registered.
  2. At the given instant, a fresh Session of the Process starts from this node.
  3. After firing, the schedule disables itself it will not fire again. To re-arm it, set Fire at to a new future instant and deploy again.

Example​

A marketing campaign should launch at 09:00 UTC on May 1, 2026. Set Fire at 2026-05-01T09:00:00Z and deploy. At that moment one Session starts and runs the campaign workflow; the schedule then stays off until you give it a new date and re-deploy.

ScheduleReminder (Generic)​

Books a brand-new Session at a future time optionally carrying data while the current Session continues immediately.

Unlike WaitFor and WaitUntil, which pause the same Session, ScheduleReminder starts a separate Session that runs independently when its time arrives. The new Session is linked to the one that scheduled it, so the two appear grouped in Session Details and Logs.

Properties​

PropertyTypeRequiredExampleDescription
WhenselectionYesBefore another dateHow the fire time is decided. Options: After a delay (counts from now), At a specific date and time (an absolute instant), Before another date / After another date (offset from a datetime carried in a variable). Default: After a delay.
How muchnumberYes, for After a delay / Before another date / After another date24How many of the chosen unit. The total offset is capped at 1 year.
UnitselectionYes, for After a delay / Before another date / After another dateHoursTime unit applied to How much. Options: Seconds, Minutes, Hours, Days, Weeks. Default: Hours.
Date and timedatetimeYes, for At a specific date and time2026-12-31T09:00:00ZThe exact fire moment, chosen with a date and time picker. Use the time-zone dropdown to type the local wall-clock time the value is stored in UTC.
ReferencechoiceNothe variableWhere the other date comes from: the variable (a {variable} holding it, e.g. the appointment time of this run) or the date (a date and time you pick, in your time zone, stored in UTC). Default: the variable.
Reference datestringYes, for Before another date / After another date{appointmentTimeUtc}The reference moment: a {variable} holding an ISO-8601 datetime (2026-03-25T10:00:00Z) or an RFC 1123 datetime, or the picked date. The reminder fires How much × Unit before or after this moment.
Data to passJSONNo{ "appointmentId": "{appointmentId}" }JSON object the reminder carries. The target Process's Reminder start receives it as {reminder}: each key is a field ({reminder.appointmentId}). A target that still begins with the plain Start gets the keys as top-level variables ({appointmentId}). Supports {variable} interpolation against the current Session. Leave empty to send no data. A Payload that is not a JSON object (an array or a single value) is refused when the reminder fires.
Channel (Advanced)choiceNoReminderThe Channel the reminder Session starts on: Reminder · no user to chat with (the default; the Reminder start serves it) or Custom… to type another (letters, digits and underscores only).
Then runselectionNo(leave empty)Which Process and Environment the reminder starts. Picked with the Environment picker see Choosing the target below. Default: the same Environment the calling Session runs in.

Choosing the target​

The Then run picker supports three modes:

  1. Leave it empty the reminder starts another Session of the same Environment the calling Session runs in. This is the default and covers most cases.
  2. Pick a specific Environment choose a Process and one of its Environments; the reminder starts that Environment's workflow. The target must be in the same Workspace anything else is rejected.
  3. Match by name choose a target Process and enable Match by env name. When the Task runs, the platform picks the Environment of the target Process whose name matches the calling Session's Environment name so your development Environment books reminders into the target's development Environment, and production into production, without wiring each one by hand.

A broken target a missing Environment, a different Workspace, or no same-named Environment in the target Process is caught when you deploy, so you find out immediately instead of when the reminder silently fails to fire.

Behavior​

  1. When the Token reaches this node, the Task computes the fire time from the chosen mode (resolving any {variable}s). The result must be no more than 5 minutes in the past and no more than 1 year ahead, or the Session stops with an error.
  2. It resolves the target Environment (see above) and resolves the Payload's {variable}s against the current Session.
  3. It books the reminder and the calling Session continues immediately to the next node.
  4. At the fire time a new Session of the target Environment starts on the Reminder Channel, at the target Process's Reminder start, with the Payload as {reminder}, linked to the originating Session in Session Details and Logs.
note

Give the target Process a Reminder start: the reminder begins there, even when the Process also has a Chat or another Channel's start, and the Payload arrives as {reminder}. A target that still begins with the plain Start (flows built before the Reminder start) keeps working: the Payload's properties become top-level variables ({appointmentId}). If you set Channel to another Channel, such as Chat, that Channel's own start runs instead and the Payload is not turned into variables.

Example​

A booking workflow stores appointmentTimeUtc = 2026-06-20T15:00:00Z and appointmentId = apt-381. A ScheduleReminder with When Before another date, How much 1, Unit Days, Reference date {appointmentTimeUtc}, and Data to pass { "appointmentId": "{appointmentId}" } books a new Session for 2026-06-19T15:00:00Z. The booking Session continues and confirms the appointment; one day before the appointment the reminder Session starts at the Reminder start with {reminder.appointmentId} = apt-381 and sends the reminder message.

warning

The Payload is resolved when the reminder is booked, not when it fires changes to the calling Session's variables after this node have no effect on the reminder. The reminder Session receives only the Payload; it does not inherit the caller's other variables.

Reminder start​

The start event where a reminder's Session begins. A ScheduleReminder whose target is this Process starts the Session here, on the Reminder Channel, and the reminder's Payload arrives as one variable, {reminder}. A Process may have other starts next to it (a Chat start, a WhatsApp start...): a reminder always begins at the Reminder start.

Properties​

PropertyTypeRequiredExampleDescription
Reminder variablestringNo{reminder}The variable that receives the reminder. Default: {reminder}.
FieldsrowsNoappointmentId, text, requiredThe keys the reminder's Payload carries. Each row has a Name (the Payload key, case-sensitive), a Type (text, number, boolean, date, object), Required and a Description. Later steps suggest {reminder.<name>}. The names sentBy, dueAt, late, channel, isTest, from and to are the reminder's own fields and are refused.

The {reminder} variable​

PlaceholderExampleDescription
{reminder.<field>}apt-381Each key of the Payload ({reminder.appointmentId}), declared under Fields or not.
{reminder.sentBy.processId}The Process that booked the reminder.
{reminder.sentBy.executionId}The Session that booked it.
{reminder.dueAt}2026-06-19T15:00:00.0000000ZWhen it was due (UTC).
{reminder.late.catchUp}falseTrue when it started more than a minute late (an outage, an Environment switched off).
{reminder.late.seconds}4How many seconds after its due time the Session started.
{reminder.late.maxSeconds}86400The reminder's Don't run if late by more than, in seconds; 0 when it has none.
{reminder.channel}ReminderThe Session's Channel (Chat in a test).
{reminder.isTest}falseTrue when the start ran in the test chat.
{reminder.from}, {reminder.to}Empty for a reminder.

The Session also gets {schedule} (kind reminder, planned time, who booked it). A required field the reminder doesn't carry is logged as a warning on the Session and stays empty; the Session continues. A Payload key named like one of the reminder's own fields (channel, from...) is dropped with a warning: rename it in the ScheduleReminder's Payload.

Testing from the chat​

With the assistant's chat_start_session (startNodeId = the Reminder start's id, testData = {"appointmentId": "apt-1", "phone": "+39021234567"}), or as the only start of a Process tested in the editor's chat, the test values fill the fields, typed as the Fields declare them. {reminder.isTest} is true and the rest of the flow runs on the chat.

On any other Channel the Reminder start stops the Session with a "starts Reminder sessions only" error.

Scheduled tasks​

Everything your workflows run on their own is on the Scheduled tasks page, reachable from the sidebar. Times are shown in your browser's time zone, with UTC beside them. The page has five tabs:

  • Repeats: the schedules of your flows (their ScheduleRecurring and ScheduleOnce start events) and the repeats you set up on this page, grouped by Process. Each row shows the name, where it starts, the environment, the version its runs use, when it runs, the data it sends, the next run, its last 10 runs as dots and its status (Active, Held: missing data, Turned off, Paused, Stopped, Finished, Retrying). A schedule is held when the version it runs asks for an input it doesn't send (for example a new required input with no default): each run would stop at the start, so the page says which value is missing.
  • One-off runs: single runs scheduled from this page, by the assistant or by an outside system. You can edit or cancel them until they start.
  • Scheduled: runs a flow booked while it was running (a ScheduleReminder), for example a reminder the day before a delivery.
  • Waiting to resume: Sessions paused at a WaitFor or WaitUntil step, which start again at a set time. They can't be deleted here (they would wait forever): stop the Session instead.
  • Next 7 days: every run due in the coming week, by day. A schedule that is turned off, paused or stopped stays in the list with its times struck through and isn't counted.

Set up a schedule​

  1. Click New schedule.
  2. What runs: give it a name, pick the flow and one environment, and choose the version: Follow the environment's deployed version (a new deploy is picked up on the next run) or a pinned version, listed with its commit message, author and date. Only a version that has run in that environment can be pinned. If the flow has timer starts, choose where the run starts. To start from an existing schedule (or a deleted one), use Copy an existing schedule.
  3. Data: the values the run starts with. When the start step declares inputs, you get one field per input with its type and default: leave a field empty and the run gets the default, type a value to send this one instead. A required input with no default must be filled. Other values can still be added as names and values (or as JSON). Each becomes a variable the flow can use, like {customerId}; the run also gets {schedule}.
  4. When:
    • Now: the run starts in a few seconds.
    • Once, later: pick a preset (in 1 hour, tomorrow morning, tomorrow afternoon, Monday morning) or a date and time in your time zone, and choose what happens if it can't start on time.
    • Repeat: every few minutes, hourly, daily, weekly on the days you pick, or monthly, at up to four times a day; or Advanced, a cron built field by field (minute, hour, day of month, month, weekday) or typed directly. Choose the time zone, a start date, an end (never, a date, or a number of runs) and whether runs missed while the platform was down are made up. The preview shows the next runs and about how many runs a month the schedule makes.
  5. Save. Each run counts toward your plan's executions; on a live environment it can message real customers.

Change, turn off or delete a schedule​

Open a schedule from the list to see its page: its settings, its last runs and its history. From the row menu (⋯) or the schedule's page you can Edit, Duplicate, Run now, Turn off / Turn back on and Delete it. Turning a repeat back on continues from now: runs missed while it was off are not made up. A flow's own schedule is changed in the flow (redeploy it), and turned off in the environment's Scheduler settings.

History​

Every change to a schedule is kept: who created, changed, turned off, deleted or restored it, and what changed (before and after). The schedule's page lists its changes, its runs and the scheduler's events together; History at the top of the Scheduled tasks page lists the changes across the workspace. From any change you can Restore these settings, or Use as a new schedule (this also works for a deleted schedule).

Changing schedules requires the Member role or higher in the Workspace; Viewers can read them, see Collaboration.

Common recipes​

Send a daily usage digest​

Run a fresh Session every morning that fetches yesterday's numbers and mails them out.

  1. ScheduleRecurring Repeat Daily, At 06:00 (in UTC). Every day at 06:00 UTC a fresh Session starts.
  2. HttpTask Method GET, URL https://api.example.com/stats/daily, response stored in the variable stats.
  3. HttpTask Method POST to your email provider's API, with a body template that includes {stats}. The Session ends after the send.

Remind a customer the day before their appointment​

A chat booking workflow validates the appointment date, books a reminder Session for 24 hours before it, and confirms.

  1. Get Date (Date Module) Operation Current time, Format iso, output variable now the lower bound for the validation.
  2. InputTask collects the requested appointment date into the variable appointmentInput.
  3. Check Date Operation Validate, Input {appointmentInput}, Min date {now}, output variable appointmentTimeUtc. Label the three outgoing Sequence Flows valid, invalid, and outOfRange; on valid the normalized ISO-8601 UTC value is written to appointmentTimeUtc.
  4. ScheduleReminder (valid branch) When Before another date, How much 1, Unit Days, Reference date {appointmentTimeUtc}, Data to pass { "appointmentId": "{appointmentId}", "phone": "{phone}" }. The reminder Session begins at a Reminder start that lists appointmentId and phone as Fields, and sends the reminder message to {reminder.phone}.
  5. OutputTask (valid branch) confirms the booking to the customer.
  6. OutputTask (invalid branch) replies that the date couldn't be read and asks for it again; on the outOfRange branch, a third OutputTask explains the date is already in the past and asks for a future one.

Resume work at the start of the next business day​

Defer a non-urgent action that arrives on a weekend until the next working day, at the same clock time.

  1. Get Date (Date Module) Operation Current time, Format iso, output variable now.
  2. Transform Date Operation Next business day, Input date {now}, If already a business day same (the default), output variable resumeAt. A request arriving Saturday at 09:00 UTC gets {resumeAt} = Monday 09:00 UTC; one arriving on a working day keeps {resumeAt} = the current time, so nothing is deferred.
  3. WaitUntil Wait until {resumeAt}. A weekend arrival pauses the Session until Monday; a weekday arrival resumes immediately.
  4. HttpTask performs the deferred action on Monday morning.

Best practices​

  1. Think in UTC. Every schedule time is stored in UTC (the editor converts from the workspace time zone when you enter it, and a run moves by an hour when the clocks change) when your audience lives in another time zone, compute times with the Date Module's Transform Date (Operation Convert time zone) and display them with Extract Date (Operation Format text).
  2. Relative waits → WaitFor, absolute waits → WaitUntil. "In 24 hours" is WaitFor; "at 09:00 on December 31" is WaitUntil with an ISO-8601 instant or a computed {variable}.
  3. Design scheduled workflows to tolerate a duplicate run. In rare cases such as a platform restart at exactly the wrong moment a due schedule can fire twice. Make the actions it triggers safe to repeat.
  4. Forward everything the reminder needs in the Payload. A reminder Session does not inherit the caller's variables pass the ids, names, and numbers it needs explicitly.
  5. Prefer presets over custom cron. The Daily / Weekly / Monthly presets are validated field by field with clear Deployment errors; reach for CustomCron only when no preset fits.

Error codes​

CodeNameDescription
3005TaskInvalidDataAn amount, unit, datetime, weekday token, or cron expression is invalid, or a reminder's target Environment cannot be resolved. See full details
4001ModuleExceptionThe platform could not register the wait or reminder. The Session stops with this error instead of waiting forever. See full details