Skip to main content
Sequences let you define recurring workflows where multiple hooks fire on a schedule. Steps can declare dependencies, so downstream hooks only run after their prerequisites succeed.

Overview

A sequence is defined by:
  1. Steps: The hooks to deliver, with optional dependencies.
  2. Schedule: When and how often the sequence runs (interval or calendar).
  3. Start time: When the first run begins.
  4. End time (optional): When the sequence stops running. After this time, no further runs are produced.
Sequences are created and managed in the Dashboard.

Steps

Each step defines a hook to fire when the sequence runs. Steps are configured using YAML, where each key is a step name.
syncData:
  path: /webhooks/posthook/sync
  data:
    source: "crm"
cleanupOldRecords:
  path: /webhooks/posthook/cleanup
notify:
  path: /webhooks/posthook/notify
  requires:
    - syncData
    - cleanupOldRecords
In the Dashboard, steps are defined using YAML. In posthook.toml, the same structure uses TOML syntax — see Managing sequences below.

Step fields

FieldDescription
pathEndpoint path for delivery (combined with your project domain)
dataOptional JSON payload delivered with the hook
requiresOptional list of step names that must succeed (2xx) before this step runs

Dependency graph

Steps without requires run immediately when the sequence fires. Steps with requires wait until all listed dependencies complete successfully. In the example above:
  • syncData and cleanupOldRecords have no dependencies, so they start in parallel.
  • notify waits until both complete with a 2xx response.
  • If a dependency fails, dependent steps do not run for that execution.

Limits

  • Maximum 5 steps per sequence (may vary by plan).
  • Maximum 64 KB of data per step.

Scheduling

Each sequence uses exactly one scheduling type: interval or calendar.

Interval scheduling

Interval schedules repeat at a fixed cadence from the start time.
UnitAllowed values
months1, 2, 3, 6, 12
days1, 2, 3, 5, 7, 14, 21, 28
hours1, 2, 3, 4, 5, 6, 12
minutes5, 10, 15, 20, 30, 60, 90
An interval of 7 days starting at 2026-03-01T09:00:00Z fires on March 1, March 8, March 15, and so on. In posthook.toml:
[[sequences]]
name = "weekly-sync"
start_at = "2026-03-01T09:00:00Z"

[sequences.interval]
count = 7
unit = "days"

Calendar scheduling

Calendar schedules run at specific clock times, on specific days, in a specific timezone.
FieldDescription
frequencyhourly, daily, weekly, or monthly
hourHour of day (0–23)
minuteMinute of hour (0–59)
timezoneIANA timezone (e.g., America/New_York)
onDaysDays of the week (e.g., ["monday", "wednesday", "friday"])
onDatesDays of the month (e.g., [1, 15], or negative values like [-1] for last day)
everyNRun every N intervals (e.g., every 2 hours, every 3 weeks)

Calendar field rules

Not all field combinations are valid.
FieldHourlyDailyWeeklyMonthly
hourForbiddenRequiredRequiredRequired
minuteOptional (defaults to 0)RequiredRequiredRequired
timezoneRequiredRequiredRequiredRequired
onDaysForbiddenForbiddenRequiredForbidden
onDatesForbiddenForbiddenForbiddenRequired
everyNOptionalOptionalOptionalOptional
Examples:
  • Daily at 9:00 AM Eastern: frequency daily, hour 9, minute 0, timezone America/New_York
  • Weekly on Mon/Wed/Fri at 8:30 AM: frequency weekly, hour 8, minute 30, timezone America/Chicago, onDays ["monday", "wednesday", "friday"]
  • Monthly on the 1st and 15th at noon: frequency monthly, hour 12, minute 0, timezone Europe/London, onDates [1, 15]
  • Every 2 hours at :00: frequency hourly, timezone UTC, everyN 2
  • Every hour at :30: frequency hourly, minute 30, timezone America/New_York
In posthook.toml:
[[sequences]]
name = "daily-report"
start_at = "2026-03-01T09:00:00Z"

[sequences.schedule]
frequency = "daily"
timezone = "America/New_York"
time = { hour = 9, minute = 0 }
everyN is anchored to the sequence’s start time, not the most recent run. For example, everyN: 2 with a weekly schedule starting on January 6 always fires on even-numbered weeks from that date, regardless of when the last run actually occurred.

Short months and leap years

If a monthly schedule is configured for a date that doesn’t exist in a given month, that month is skipped. There is no clamping.
  • A schedule on the 30th skips February (28 or 29 days) and runs in the other 11 months.
  • A schedule on the 31st only runs in months with 31 days (January, March, May, July, August, October, December).
To run on the last day of every month regardless of length, use a negative value: onDates: [-1]. Negative values count from the end of the month (-1 = last day, -2 = second to last, etc.).

DST handling

Calendar schedules handle Daylight Saving Time transitions automatically:
  • Spring forward (gap): If the scheduled time falls in a skipped hour (e.g., 2:30 AM when clocks jump from 2:00 to 3:00), the run shifts forward to the first valid time after the gap.
  • Fall back (fold): If the scheduled time occurs twice (e.g., 1:30 AM when clocks fall back from 2:00 to 1:00), the earlier occurrence is used.

Managing sequences

Define sequences in posthook.toml alongside your application code. This gives you version control, code review, and repeatable deployments. 1. Initialize — Pull your current project config into a TOML file:
npx posthook init
2. Define a sequence — Add a [[sequences]] block:
[[sequences]]
name = "daily-health-check"
start_at = "2026-03-01T06:00:00Z"

[sequences.schedule]
frequency = "daily"
timezone = "America/Chicago"
time = { hour = 6, minute = 0 }

[sequences.steps.check-api]
path = "/webhooks/health/api"
data = { service = "api" }

[sequences.steps.check-db]
path = "/webhooks/health/db"
data = { service = "database" }

[sequences.steps.report]
path = "/webhooks/health/report"
depends_on = ["check-api", "check-db"]
In TOML config, step dependencies use depends_on. In the Dashboard and API, the same concept is called requires.
3. Preview and deploy:
npx posthook validate   # Check syntax locally
npx posthook diff       # Preview what will change
npx posthook apply      # Deploy to Posthook
Check posthook.toml into git. Use multi-environment configs (posthook.staging.toml, posthook.prod.toml) to manage sequences across environments.
See the Config-as-Code guide for the full list of commands and TOML schema.

Dashboard

You can also create and manage sequences in the Dashboard.

Usage patterns