recurrence. Each occurrence is a normal
scheduled message: it is sent by the evaluator, costs 2 credits,
and appears in the list and in the execution log on its own.
Add a recurrence
max_repeats and end_at are both optional and whichever comes first ends the series. With
neither, the series runs until you cancel it.
How the series runs
Only one occurrence exists ahead of time. When the evaluator sends one, it creates the next as a new scheduled message with its ownid, repeat_count one higher and source: "repeat"; the
one just sent stays in the list as sent. So at any moment the series has exactly one row with
status: "scheduled", and that row is the one to act on.
The next time is computed from the previous scheduled time, not from when the send actually
happened: send_at + interval_minutes. A tick that fires a minute late therefore does not push
every later occurrence a minute later. The series ends when repeat_count reaches max_repeats
or the next time would fall after end_at.
An occurrence that fails to send, or that expires under its
delivery conditions, does not create a next one. The series stops
there, and the failed or expired row carries the reason in error_message.
Everything else on the message travels with it: data, destination, schedule.timezone and
delivery_conditions are copied onto each new occurrence, and a max_delay_at deadline is
recomputed for each one from its own time. A PATCH to the scheduled occurrence therefore
changes the rest of the series as well.
Stop it
Cancel the occurrence that is currentlyscheduled:
PATCH it with "recurrence": null.
To find the series, list with ?template_id= and read repeat_count; the occurrence with
status: "scheduled" is the live one. On the web app’s Scheduled page a recurring message reads
as, for example, “Every 1 day, 10×, until 2026-12-31”.

