Schedules
A schedule decides three things: when something is due, how often it comes back, and when it stops for good.
It sits on the assignment, not on the journey and not on the content. So the same questionnaire can be a one-off for one participant and a daily habit for another, with no second copy of anything.
Recurrence is the schedule's whole job. If something needs to happen every morning for six weeks, that is one assignment with one schedule — not forty-two nodes and not forty-two assignments.
Three cadences
{ "type": "once", "start": { "type": "instant" }, "end": { "type": "never" } }
{ "type": "weekly", "days": ["MO","WE","FR"], "times": ["08:00","20:00"],
"start": { "type": "instant" },
"end": { "type": "after", "after": 6, "period": "weeks" } }
{ "type": "custom", "every": 3, "period": "days", "times": ["09:00"],
"start": { "type": "after", "after": 1, "period": "weeks" },
"end": { "type": "responses", "maxResponses": 12 } }
once for anything that happens one time: a welcome card, a consent screen, an
end-of-programme survey. It can still be timed, because start and end work on it.
weekly for anything anchored to days of the week. Weekday check-ins, a Monday reading, a
Sunday reflection.
custom for everything else: every third day, every other week, every four hours.
The cadences count in hours, days and weeks. To repeat roughly monthly, use custom with
every: 4, period: "weeks", and expect it to drift against the calendar rather than land on a
date.
The cadence
| Setting | Applies to | What it accepts | What it does |
|---|---|---|---|
type | all | once, weekly, custom | The cadence. |
days | weekly, and custom with period: "weeks" | any of MO TU WE TH FR SA SU | Which days it is due on. Ignored on any other cadence. Always write it out: with no days, weekly recurs on the one weekday the participant happened to be given it on. |
times | weekly, and custom with a period of days or weeks | 24-hour "HH:mm" | Adds slots within a due day. Ignored when the period is hours, because an hourly cadence already has its own grid. |
every | custom | a whole number, 1 or more | How many periods between occurrences. Defaults to 1. |
period | custom | hours, days, weeks | The unit every counts in. |
A schedule with a cadence the platform doesn't know, or a key it doesn't read, is refused when it is written.
The bounds
Every schedule carries both a start and an end. An open bound is written out rather than
left off, so nothing has to be guessed from a missing key.
start is one of:
| Written | Means |
|---|---|
{"type": "instant"} | Available from the moment it is assigned. |
{"type": "after", "after": 2, "period": "weeks"} | Available two weeks after assignment. period is days, weeks or months. |
{"type": "at", "at": "2026-10-06T09:00"} | Available from that date and time. |
end is one of:
| Written | Means |
|---|---|
{"type": "never"} | It never stops. |
{"type": "after", "after": 6, "period": "weeks"} | It stops six weeks after it was assigned. |
{"type": "at", "at": "2026-12-01T00:00"} | It stops at that moment. |
{"type": "responses", "maxResponses": 12} | It stops once twelve responses exist, however long that takes. A participant can respond ahead from History, so the count can run out before the calendar does. |
Offsets are measured in days, weeks or months, so the shortest delayed reveal is the next
day. For a delay of hours, hand the assignment out from a later node and gate the arrow into it
with an after When.
Dates and times are the participant's own wall clock, written with no timezone. A schedule set for 09:00 fires at nine in the morning wherever they happen to be. It does not shift when they travel.
Day boundaries are local midnight, and daylight saving is handled for you. A clock going back takes the earlier of the two possible moments; a clock going forward moves to the first real moment of that day. Neither loses a day.
How "due" works
Something appears on the home screen while it is inside one of its own windows, and not otherwise. When something is not showing, that is almost always the reason.
| Cadence | One occurrence is | Its window is |
|---|---|---|
once | the single occurrence | the whole span from start to end |
weekly | each chosen weekday | that whole day, in the participant's own time |
custom, period: "days" | each step of the count | the whole step — every third day means one occurrence to do at some point in those three days |
custom, period: "weeks" | each chosen weekday of an on-count week | that whole day |
custom, period: "hours" | each step of the count | that step |
Nothing is invented to fill a gap. A period with no occurrence in it produces nothing at all, rather than showing the last one again.
Something given part way through a day is not backdated. The first occurrence opens at the moment of assignment rather than at the start of that day, so nothing appears as already missed on the day somebody joins.
What times actually does
times does not gate whether something shows. It splits a due day into separate things to
do.
- With no times, or one, a due day is one item.
- With two or more, a due day is that many items, one per time, and all of them are available all day. A participant can do the evening one at breakfast.
times is what tells a morning entry apart from an evening one in the record. It is not a lock.
Occurrence references
Every response is filed against the occurrence it belongs to, and the reference format tells you what kind it was.
| Reference | Means |
|---|---|
once | The single occurrence of a one-off. |
2026-09-14 | A daily or less frequent occurrence, named by its own date. |
2026-09-14T20:00 | One slot of a day that had several, or an hourly occurrence. |
2026-09-14T20:00:07 | A response added outside the schedule. |
The last one is the one to recognise. Seconds mark an out-of-schedule response, because a
scheduled occurrence never has them. Those only exist where unscheduledSubmission is switched
on.
What stops something coming back
Three separate things, and they behave differently.
- A time-based
end. Generation stops. Nothing more is due, ever. end.maxResponses. A lifetime count across every occurrence. Once that many responses exist, it is finished, whatever the calendar says.- Submitting today's occurrence. This only clears today. A recurring item whose
persistentis off leaves the screen when submitted and comes back at its next occurrence. That is the shape of a daily habit, and it is not the same as retiring it.
The same applies to dismissing: a dismissed occurrence is hidden, and the next one is not.
persistent decides whether a submitted item stays on screen, and the schedule does not.
persistent: true leaves it there with a tick until its window closes; false takes it away
the moment it is submitted. Both come back at the next occurrence.