Schedule a monthly visit on a weekday, not a date

Supply frequency_id, day_of_week, week_of_month and anchor_date together — a bare monthly frequency will not reliably produce the schedule you expect. Preview with confirm:false and read the anchor_check and computed dates before committing. The ordinal composes with seasonal months, quarterly cadences and last-of-month.

Set day_of_week and week_of_month on the service line, and anchor it to the first date you want served. "Second Tuesday of every month" is a first-class schedule, not a workaround.

Clients remember weekdays. Almost nobody remembers that you come on the 14th.

Why a bare monthly frequency is not enough

Picking a frequency called "Monthly" and nothing else will not reliably give you the schedule the client expects. The frequency is the shape; the weekday and ordinal are the phase.

Always supply all three:

InputWhat it doesExample
frequency_idThe monthly cadence templateMonthly
day_of_week0 = Sunday … 6 = Saturday2 for Tuesday
week_of_monthOrdinal positions; [-1] means last[2] for the second
anchor_dateThe first date to serve — drives the phase2026-08-11

That produces a durable recurrence rule — FREQ=MONTHLY;INTERVAL=1;BYDAY=TU;BYSETPOS=2 — and a human-readable label: "Every month on the 2nd Tuesday."

Check the preview before you commit

Every path that creates a recurring line previews first with zero writes: onboard_client and create_recurring_service both take confirm: false.

The preview returns an anchor_check — the date, its weekday spelled out, its ordinal position in the month, and whether it matches what you asked for:

anchor_check: { date: "2026-08-11", weekday: "Tuesday",
                ordinal: 2, matches_inputs: true }

plus the next several computed occurrences. Read those dates. If the second Tuesday is what the client agreed to, the dates in the preview are the dates on their calendar for the next year.

Reading next_occurrences honestly

get_contract_service_line returns upcoming dates, but they are bounded by a look-ahead window of roughly a year. Ask for six occurrences on a quarterly line and you will get about four — that is the window truncating, not the series ending.

The response tells you which is which: next_occurrences_window_days and next_occurrences_seasonally_filtered. Check them before concluding a schedule has run out.

The ordinal composes with other constraints

The nth-weekday anchor is not a special case. It combines:

  • With a seasonal month set. "Third Wednesday of odd months" is the monthly cadence with day_of_week: 3, week_of_month: [3], and months: [1,3,5,7,9,11]. You get a real recurrence rule and an honest six visits a year on the proposal, not twelve.
  • With quarterly, biannual, annual. "Second Tuesday, quarterly" is the same two fields on a quarterly frequency.
  • With last-of-month. week_of_month: [-1] gives the last Friday, regardless of whether the month has four or five.
  • With twice-monthly. [1, 3] gives the first and third weekday — a clean 24 visits a year, which is genuinely different from fortnightly's 26.

Phase-locking two lines to the same day

When a client has two services that should be done on the same visit — outside glass monthly, inside glass every second month — give both lines the same weekday and ordinal and use align_with_line_ref to lock the second line's anchor to the first.

Same weekday, same ordinal, same anchor means the visits co-land. Use line_label to tell the two apart on the proposal and the invoice.

When the label and the frequency name disagree

The frequency's catalogue name is a template name. The line's human_description is the authoritative label, derived from the actual recurrence rule.

If a line overrides the day of week, the catalogue name can lag behind. Trust human_description — it is what the client-facing documents render, and it is what the schedule actually does.

Related

Last updated 2026-08-28