Publish to WordPress on a Schedule with the REST API

Create scheduled WordPress posts through the REST API by sending the correct site-local date, uploading media first, recording a client-side identity, and deciding whether WordPress or an external worker owns the publishing clock.

By · · 10 min read

Drafted with AI assistance from our own research and Search Console data, and reviewed by Rahul A before publishing. Rules and prices change; check the linked official source before you act.

Should WordPress or your scheduler own the publishing clock?

WordPress should own the publishing clock when a small delay is acceptable, while an external scheduler should own it when timing and recovery need explicit control. The REST API can create a post with a future status and a date, leaving WordPress to make it public later. That approach is simple, but the site must process its scheduled-post work.

WordPress commonly relies on its internal scheduled-task mechanism, which is activated by site activity rather than being a continuously running clock. A quiet site, blocked requests, caching rules, or hosting configuration can delay the transition from scheduled to public. The post may therefore be stored correctly while remaining unavailable longer than expected.

Use WordPress scheduling for ordinary editorial queues where a flexible publication window is fine. Use an external worker for launches, coordinated campaigns, or a portfolio of sites where you need one queue, one audit trail, and one place to recover missed work. In that model, keep the WordPress post as a draft until the worker is ready, then publish it at the appointed time. Do not mix ownership casually. A system that creates future posts and also tries to publish them externally can create confusing state changes.

For more context, read How to Publish Social Posts Safely from an MCP Server.

How do I authenticate to each WordPress site safely?

Use a dedicated WordPress user with an application password and the narrowest practical role for the publishing task. Application passwords let a connection authenticate without sharing the user’s normal login password, and they can be revoked independently when a client leaves or a connection is compromised.

Create one publishing identity per site or client account, rather than using a single administrator identity everywhere. Grant the role needed to create, edit, upload, and publish the relevant content. A contributor may be unable to publish or upload media, while an administrator has broader access than an automation usually needs. Test the chosen role against the exact operations your integration performs.

Send requests only over HTTPS and store credentials in a secret manager, not in post content, logs, screenshots, or a shared spreadsheet. Keep the site address, user identity, credential reference, and capability test together in the connection record. When a credential stops working, mark the connection as needing attention instead of repeatedly submitting the same operation. For many accounts, separate credentials also make it clear which site needs repair and prevent one customer’s access change from disrupting every other customer.

For more context, read How to Verify That a Social Post Really Published.

Which date should the REST API send for a scheduled post?

Send a scheduled post’s publication date in the WordPress site’s configured timezone, and make the timezone conversion explicit before creating the post. A calendar time such as 9:00 AM is not complete until the system knows which site clock it belongs to.

A reliable connection record stores the site timezone and the intended time zone of the content plan. Convert the planned instant into the format expected by the WordPress endpoint, then preserve both the original plan and the converted value in your audit record. Avoid using the server’s local timezone as a hidden default, because hosting location and WordPress location can differ.

Daylight-saving changes make fixed numeric offsets unsafe for recurring plans. Use a named timezone when your scheduling system supports one, and recalculate future occurrences rather than adding a fixed number of hours. Before enabling a client, create a test post for a nearby future time and compare the displayed WordPress date with the planned time. Also decide how your product handles ambiguous or nonexistent local times during clock changes. A clear policy, such as moving an invalid time to the next valid minute, is better than silently choosing a different publication moment.

How do I publish an image with the post instead of after it?

Upload the image to WordPress first, capture its media identifier, and include that identifier when creating the post. A post body can contain an external image URL, but an uploaded attachment gives the site ownership of the asset and lets the post use WordPress media behavior such as a featured image.

Treat media preparation as a separate step with its own record. Preserve the original filename, content type, dimensions, checksum, returned media identifier, and the post or campaign that will use it. Check that the publishing identity can upload media and that the upload response represents the intended file before creating the post. If the same asset is reused, reuse the recorded media identifier rather than uploading another copy for every destination.

Set the featured media field during post creation when the image should appear as the post’s featured image. Put images in the content only when they belong at a particular point in the article. Generate alt text from the subject and purpose of the image, not from a filename or keyword list. Test captions, image sizes, and content rendering on the actual theme, because a valid REST payload does not guarantee that the front end presents media as the editor expects.

How do I stop an interrupted request creating duplicates?

Give every intended WordPress publication a stable client-side identity and check that identity before creating another post. WordPress does not provide a universal idempotency key for post creation, so a client must keep its own ledger or add a deliberately designed marker that it can search reliably.

Create the identity before the first request and keep it unchanged across timeouts, process restarts, and operator retries. The ledger should associate the identity with the site, content version, media identifiers, intended status, scheduled time, and any WordPress post identifier discovered later. Before submission, look for an existing completed or in-progress record. After an uncertain interruption, search or inspect the site using the marker or ledger before attempting creation.

Do not use the post title as the identity. Titles can legitimately repeat, change during editing, or be translated. A hidden custom field can work when it is registered for REST access and your integration can query it consistently, but adding a field alone does not make duplicate detection reliable. Keep a human-readable correlation label in your internal log, while treating the immutable identifier as the decision key. This rule matters most when several operators or workers can act on the same account.

What should happen when WordPress misses the scheduled time?

A missed WordPress schedule should become an explicit state that an operator or worker can resolve, not an invisible delay. WordPress can hold a future post until its scheduled-task mechanism runs, so a stored future post is not proof that the public transition occurred at the planned moment.

Choose a policy before launch. For flexible editorial content, allow the post to publish late and record the actual public time. For time-sensitive content, have an external worker own the final transition and use WordPress only for storage until that worker acts. For expired content, cancel it or return it to draft instead of publishing stale material. The correct choice depends on the campaign, but it must be attached to the post record rather than improvised during an incident.

A monitoring job should look for scheduled items whose intended time is past and whose state has not reached the policy’s acceptable outcome. It should show the site, post identity, planned time, current WordPress state, and next action. Avoid repeatedly changing the post status without recording why. The important distinction is between a post that was accepted for future scheduling and a post that crossed the publication boundary under the agreed timing policy.

How should one publishing queue represent many WordPress sites?

Model each WordPress site as an independent connection with its own timezone, credentials, content rules, media handling, and publication policy. A shared queue can coordinate many sites, but it should never assume that a payload valid for one site is valid for all of them.

Keep site configuration separate from content. The connection record should identify the base site, publishing identity, timezone, permitted post types, allowed status changes, media rules, and the last capability check. The content record should identify the intended site, content version, requested time, language or category mapping, media, and client-side publication identity. This separation lets an operator change a site’s credentials or timezone without rewriting the editorial item.

Use per-site work states rather than one global result. A campaign can succeed on one WordPress site, wait for approval on another, and need repair on a third. Operators should be able to pause one connection without blocking unrelated queues. Keep an audit trail of who changed the schedule, which content version was sent, and which WordPress post received it. For an agency, this structure prevents a shared retry or timezone setting from silently affecting several brands at once.

What is the smallest test that proves a WordPress schedule works?

The smallest useful test creates one harmless post with one image, schedules it a few minutes ahead, and checks the complete state change on the target site. A successful API response alone proves only that WordPress accepted a request, not that the configured schedule, media, permissions, and front end behave correctly.

Run the test with the same user role, site timezone, content shape, and worker path used in production. Confirm that the post appears as scheduled in the WordPress editor, that the image is attached as intended, and that the public page becomes available according to the chosen ownership policy. Record the planned time, the time WordPress stored, the media identifier, the post identifier, and the observed public result.

Then test the awkward cases deliberately. Edit the scheduled post, cancel it, repeat the submission with the same client identity, and interrupt the process after media upload but before post creation. Confirm that the resulting records remain understandable and that a second run does not create a duplicate. A short runbook should tell an operator how to reconnect a site, identify an uncertain operation, and decide whether a late post should publish. PostWharf can use that runbook as the shared operating contract across client connections.

Common questions

Can the WordPress REST API schedule a post without an external scheduler?

Yes. Create the post with a future publication date and the scheduled status, then WordPress can make it public when its scheduled-task mechanism runs. The timing is not always exact because that mechanism depends on site activity and hosting behavior. Use an external scheduler when the publication moment or recovery process requires tighter control.

Does WordPress have a built-in idempotency key for post creation?

No. WordPress does not provide a universal idempotency key for creating posts through the REST API. Store a stable identity in your own ledger and use it to detect an existing operation before creating another post. A registered custom field can support lookup, but only when your integration can query and enforce it consistently.

Should media be uploaded before the WordPress post?

Yes, when the post needs a WordPress-hosted image or featured image. Upload the media first, retain the returned media identifier, and send that identifier with the post payload. Separating the steps makes failures easier to diagnose and avoids creating a post that refers to an attachment your publishing identity could not create.

Which timezone does a scheduled WordPress post use?

A scheduled post should use the timezone configured for the target WordPress site, with the conversion performed explicitly by your scheduling system. Do not rely on the server’s location or an account-wide default. Store the original planned time and the converted value so an operator can explain why WordPress displays a particular schedule.

What happens if a scheduled WordPress post is late?

The post may remain scheduled until WordPress processes its scheduled work, especially on a quiet or unusually configured site. Your system should detect overdue items and apply a stated policy: publish late, keep waiting, return to draft, or cancel. Time-sensitive campaigns should let an external worker control the final transition.

PostWharf is priced per workspace rather than per connected channel, and every plan carries unlimited channels. See per-brand pricing.