Scheduled Publishing
Schedule individual records for future publish or unpublish, or group many publishable items into a single coordinated rollout that ships them all at one moment — with pause, resume, retry, and rollback controls.
Overview
Scheduled publishing lets you prepare content ahead of time and ship it automatically at a specific date and time. Instead of manually pressing Publish at the right moment, you set a schedule and Foir handles the rest.
Two concepts cover the whole feature:
- Scheduled dates on a record — set a future publish or unpublish date on any record version. The record stays in its current state until the scheduled moment, then flips.
- Rollouts — package any number of publishable items (records, models) into one named batch and ship them together. Rollouts can be scheduled or triggered on demand, paused mid-flight, retried after a partial failure, and rolled back after they complete.
How scheduling works
When you set a scheduled date on a record version, Foir queues the operation and executes it at the specified time. The record remains in its current state until the scheduled moment.
Record: "Summer Campaign Page"
Version: v3 (draft)
Scheduled: Publish at 2026-06-01 09:00 UTC
Timeline:
─────────────────────────────────────────────
Now (draft) June 1 09:00 (published)You can schedule both publish and unpublish operations. Schedule a promotional page to publish on June 1 and unpublish on June 30 to create a time-boxed release.
A rollout is the same idea applied to many items at once: instead of scheduling each record individually, you build a single rollout with N items and one scheduledAt. Everything ships together; if any item fails, the rollout marks itself Partial and you can retry just the failures without re-running the rest.
In the admin
Scheduling a single record
- Open the record and navigate to the version you want to schedule.
- Click Schedule (next to the Publish button).
- Choose the operation: Publish or Unpublish.
- Set the date and time in your local timezone — the admin converts to UTC.
- Click Confirm.
The version shows a scheduled badge with the date. You can reschedule or cancel any time before the scheduled moment.
Scheduled publishing dashboard
Navigate to Content → Scheduled to see everything that’s queued across your project:
- Upcoming and past rollouts, with status badges (Scheduled, Processing, Completed, Partial, Failed, Cancelled).
- Filter by model, date range, or status.
- Drill into any rollout to see its items and per-item status.
Working with rollouts
A rollout bundles many publishable items into one named batch. Items can be:
- Record versions — the most common case. The rollout publishes the specified version of each record.
- Models — schema changes that should ship alongside the content that depends on them.
The platform plans for adding more item kinds (operations, auth providers) under the same primitive; this list is what ships today.
Creating a rollout
- Go to Content → Scheduled → Rollouts.
- Click New Rollout.
- Name it and optionally describe what’s in it (e.g. “Spring ‘26 launch”).
- Set
scheduledAt— the date and time the rollout fires. Leave blank to create a draft you’ll trigger manually. - Add items using the picker — pick a record (and optionally a specific version), or a model whose schema changes should ship together.
- Click Save.
The rollout sits in the Scheduled state until either its scheduledAt arrives or you trigger it manually. While Scheduled, you can edit the name, description, schedule, and item list.
Lifecycle controls
Once a rollout is running or complete you have these controls from the rollout’s action panel:
- Trigger now — ignore the schedule and start the rollout immediately.
- Pause / Resume — pause an in-flight rollout (items mid-flight finish; queued items hold) and resume it later.
- Retry — re-run only the items that failed. The successful items aren’t touched.
- Rollback — generate a reverse rollout that re-publishes each item’s previously-published version. Preview before committing.
- Delete — only available before the rollout has been triggered. After trigger, use Rollback instead.
Statuses
| Status | Meaning |
|---|---|
| Scheduled | Created, waiting for scheduledAt. Editable. |
| Processing | Items are being published. Pause, but don’t edit. |
| Completed | Every item succeeded. |
| Partial | Some items failed. Use Retry on the failures. |
| Failed | All items failed — typically a configuration or permissions issue, not a content one. |
| Cancelled | Deleted before it ran. |
Via the CLI
Scheduling a single record
# Publish a specific version (immediate)
foir records publish <versionId>
# Unpublish a record (immediate)
foir records unpublish <id>
# Cancel a scheduled publish or unpublish before it runs
foir records cancel-schedule <versionId>Scheduled publishing of a single record via CLI is set when you create or update the version with a scheduledAt — see foir records for the full surface.
Managing rollouts
# List rollouts (filter by status)
foir rollouts list --status scheduled
# Create a rollout with mixed item kinds
foir rollouts create --data '{
"name": "Spring 26 Launch",
"scheduledAt": "2026-06-01T09:00:00Z",
"items": [
{ "kind": "record", "versionId": "ver_abc123" },
{ "kind": "record", "versionId": "ver_def456" },
{ "kind": "model", "modelId": "mdl_collection" }
]
}'
# Inspect the rollout and its items
foir rollouts get rollout_abc123 --json
# Add or remove items
foir rollouts add-items rollout_abc123 --file ./additional-items.json
foir rollouts remove-items rollout_abc123 --data '{"itemIds": ["item_xyz"]}'
# Trigger immediately, skipping the scheduled time
foir rollouts trigger rollout_abc123
# Pause / resume an in-flight rollout
foir rollouts pause rollout_abc123
foir rollouts resume rollout_abc123
# Retry just the failed items
foir rollouts retry rollout_abc123
# Preview a rollback before executing
foir rollouts rollback rollout_abc123 --preview
# Execute the rollback
foir rollouts rollback rollout_abc123 --confirm
# Delete a draft rollout that never ran
foir rollouts delete rollout_abc123 --confirmSee foir rollouts for the full subcommand and option reference.
Via the API
Scheduled publishing and rollouts are managed through the admin app and the CLI today — the public GraphQL API does not yet expose rollout management. The reasoning: rollouts move publishable state across many resources at once, which is editor/operator territory rather than runtime traffic.
If you need automated rollout creation (e.g. weekly releases triggered from CI), use the CLI inside a scheduled job — foir rollouts create --file ./release.json is the supported pattern.
For per-record scheduled publish dates, set scheduledAt on the record’s publish mutation:
mutation Publish {
publishRecord(input: {
modelKey: "page"
naturalKey: "summer-sale"
scheduledAt: "2026-06-01T09:00:00Z"
}) {
id
status
scheduledAt
}
}The mutation queues the publish; the record version moves to Scheduled until the moment arrives, then publishes. Cancel before then with unpublishRecord or via the admin app.
Best practices
- Group everything that ships together into one rollout. If a landing page, three banners, and a product collection all need to go live for a campaign, build one rollout — it gives you a single thing to schedule, pause, and roll back as a unit.
- Schedule unpublish dates for time-limited content. Promotional pages, seasonal banners, and limited-run products should have an unpublish date set when you publish them, not added later as an afterthought.
- Use Retry, not a new rollout, on partial failures. Retry re-runs only the failed items and preserves the rollout’s history. Creating a new rollout for the failures fragments your audit trail.
- Preview rollbacks before committing. A rollback re-publishes each item’s previously-published version. If an item had no prior published version, that’s a deletion — the preview surfaces this before you commit.
- Set schedules in UTC when working across timezones. The admin converts from your local time, but the stored value is always UTC; reading the dashboard in UTC avoids ambiguity during DST shifts.