Scheduling
schedule_post, batches, moving and cancelling — and the timezone rule.
schedule_post takes everything publish_post takes, plus publish_at: an ISO 8601 timestamp in the future. It creates a native WordPress scheduled post — it appears in wp-admin under Scheduled and WordPress is what publishes it. Pressbotics does not run a second publishing engine.
schedule_post({
site: "myblog",
title: "Our Q3 roundup",
markdown: "## The quarter in short\n\n...",
publish_at: "2026-10-01T09:00:00-04:00",
idempotency_key: "q3-roundup-2026"
})A time with no timezone is rejected
publish_at must carry timezone information — either a Z for UTC or an explicit offset such as -04:00. A naive timestamp like "2026-10-01T09:00" is REJECTED, not guessed. Pressbotics will not silently pick a timezone on your behalf and publish something hours early or late.
The absolute instant is authoritative. Pressbotics also sends the matching site-local time when it knows the site's WordPress timezone; when it does not, it sends the absolute time only and lets WordPress derive the local value.
The scheduler tools
| Tool | Parameters | Returns |
|---|---|---|
| list_scheduled | site (optional), from / to (ISO 8601, optional), status (optional), page, limit | Scheduled posts with schedule_id, title, site, publish_at (absolute UTC), status (scheduled, published, cancelled, missed) and wp_post_id where known. |
| reschedule_post | schedule_id (required), publish_at (ISO 8601 with offset, required) | The updated row. Pressbotics only records the move after WordPress confirms it; a failure returns a code such as wp_reschedule_unverified and changes nothing. |
| cancel_scheduled | schedule_id (required) | The cancelled row. The WordPress post reverts to a draft. Cancelling an already-cancelled item returns already_cancelled rather than issuing a second call. |
| schedule_batch | site (required), posts[] — each an ordinary schedule_post payload with its own publish_at | One result per item, each with its own action id and outcome. Items are independent: one can fail while the rest schedule. |
A week at a time
schedule_batch takes a site and an array of ordinary schedule_post payloads, each with its own publish_at. Items are independent — one can fail while the rest schedule — so read every result, not just the first.
schedule_batch({
site: "myblog",
posts: [
{ title: "Monday", markdown: "...", publish_at: "2026-10-05T08:00:00-04:00" },
{ title: "Wednesday", markdown: "...", publish_at: "2026-10-07T08:00:00-04:00" }
]
})Moving and cancelling
reschedule_post moves a scheduled post; cancel_scheduled reverts it to a draft on WordPress. Both only record the change after WordPress confirms it. If WordPress cannot be verified you get a code — wp_reschedule_unverified or wp_cancel_unverified — and nothing in Pressbotics is changed, so the two records can never disagree.
Scheduling and approval
The approval policy still applies. On a site under review, a scheduled post waits in your approval queue first. Approving it is what sends it to WordPress, and WordPress then holds it until publish_at. Approve well before the intended time — an approval that lands after publish_at cannot go back in time.
Plan requirement
Scheduling, batching and recurrence are paid-plan capabilities. On Free these tools return plan_upgrade_required with a message naming the plan, its price and the upgrade link. Relay it; do not retry.
Checking it
list_scheduled shows scheduled posts with their times and state. get_post_status returns the current state of a single action. Once live, the action carries post_url and render_check. Until then render_check is "not_yet" — a scheduled post is not public, so there is nothing to fetch; the scheduler verifies the page the moment it goes live and writes pass or fail onto the action then.
What can go wrong
- publish_at in the past. Use publish_post instead.
- A naive timestamp with no offset. It is refused with ambiguous_publish_at, not interpreted. The same family covers nonexistent_local_time (a clock-forward DST gap), ambiguous_local_time (a clock-back repeat), invalid_calendar_date and invalid_utc_offset — send an offset or an IANA timezone.
- wp_schedule_unverified: WordPress did not hold the post as "future" at the exact instant asked for, so the post was reverted to draft rather than reported as scheduled.
- The post published on time but the featured image did not attach. Read image_status — scheduling does not change the partial-success contract.
- A retrying workflow creating several scheduled copies. Pass a stable idempotency_key.
- WordPress missing its own cron on a quiet site. Pressbotics detects this and marks the post Missed with a Publish now action.

