
Schedule one-off, recurring and cron actions with retries and an admin dashboard, run by Payload's job queue.
Jobs & automationAdds a WooCommerce-style Action Scheduler to Payload. Actions are declared once in code and scheduled at runtime once, as soon as possible, on an interval or on a cron, then executed by the Payload job queue. A bounded ledger records each action, and the admin gets a Scheduled Actions view. Requires Payload 3.88 or newer.
WooCommerce Action Scheduler for Payload CMS: typed, scheduled and recurring actions with retries, a bounded ledger and a first-class admin view, executed by the Payload job queue.
Installation
npm i @payload-solutions/plugin-action-scheduler2
Stars
0
Forks
0
Open Issues
Today
Last Updated
4
Weekly Downloads
v0.3.0
npm Version
557.2 KB
Unpacked Size
1
Dependencies
Trends appear after 7 days of data. Daily snapshots have not started yet.
Shared by 5 plugins in mpresecan/payload-solutions.
Trends appear after 7 days of data. Daily snapshots have not started yet.
Each point is npm's rolling 7-day download count.
Health Score
Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.
Badge for your README
[](https://payloaddirectory.dev/plugins/1356812914-plugin-action-scheduler)<a href="https://payloaddirectory.dev/plugins/1356812914-plugin-action-scheduler"><img src="https://payloaddirectory.dev/badge/1356812914-plugin-action-scheduler.svg" alt="Payload Directory"></a>README
WooCommerce Action Scheduler for Payload CMS. Declare an action once in code, schedule it at runtime with arguments — once, as soon as possible, on an interval or on a cron — and let Payload's job queue run it. The plugin keeps a small, bounded ledger of every action and gives the admin a Scheduled Actions view with status tabs, a Run queue button, runner health, per-row Run now / Retry / Cancel and a log for every action.
await payload.scheduler.schedule('orders.remind', { orderId }, { scheduleAt: tomorrow })
await payload.scheduler.cron('reports.weekly', {}, { cron: '0 9 * * 1', tz: 'Europe/Warsaw' })
Design reference: notes/plugin-action-scheduler-spec.md in the payload-ecosystem repo.
pnpm add @payload-solutions/plugin-action-scheduler
Peer dependencies: payload ^3.88, @payloadcms/ui ^3.88, react, react-dom. croner (the cron engine Payload already uses) ships with the plugin.
// src/actions/orders-remind.ts
import { defineAction, SkipAction } from '@payload-solutions/plugin-action-scheduler'
export const ordersRemind = defineAction({
slug: 'orders.remind',
label: 'Remind customer about unpaid order',
group: 'orders',
inputSchema: [{ name: 'orderId', type: 'text', required: true }],
retries: 3, // default; exponential backoff 30 s → 1 h
timeout: '2m', // default '5m'
handler: async ({ args, req, log }) => {
const order = await req.payload.findByID({ collection: 'orders', id: args.orderId, req })
if (order.paid) throw new SkipAction('already paid')
await req.payload.emails.send('payment-reminder', { input: { order }, req })
log(`reminder sent to ${order.email}`)
return { note: 'reminder sent' } // ≤ 256 chars; nothing else is stored
},
})
Throw to fail the attempt (retried per policy), PermanentError to fail without retries, SkipAction(reason) to complete without doing anything. signal aborts on timeout.
import { actionScheduler } from '@payload-solutions/plugin-action-scheduler'
export default buildConfig({
plugins: [
actionScheduler({
actions: [ordersRemind, cleanupCarts],
recurring: [{ key: 'carts.nightly', hook: 'cleanup.carts', cron: '0 3 * * *', tz: 'Europe/Warsaw' }],
}),
],
jobs: { autoRun: [{ cron: '* * * * *' }] }, // or Vercel cron → /api/payload-jobs/run, or Payload Clock
})
Run payload generate:types and every hook and its arguments are typed through Config['scheduledActions'].
payload.scheduler.schedule(hook, args, { scheduleAt, group, unique, priority, queue, req })
payload.scheduler.enqueue(hook, args) // as soon as possible
payload.scheduler.recurring(hook, args, { every: '1h', startAt })
payload.scheduler.cron(hook, args, { cron: '0 9 * * 1', tz })
payload.scheduler.cancel(hook, { args, group }) / cancelAll / cancelByID(id)
payload.scheduler.next(hook, match) // Date | 'running' | null
payload.scheduler.has(hook, match)
payload.scheduler.find({ hook, status, group })
payload.scheduler.runQueue() // what the admin button calls
Function-style exports (scheduleAction(payload, …), unscheduleAction, nextScheduledAction, …) mirror the as_* API.
Every action keeps a timeline: attempts, errors, retries. |
A permanent failure with its error, arguments and log. |
Run now, Reschedule, Cancel, Duplicate — per row and in bulk. |
More in the documentation: https://payload.solutions/docs/plugins/payload-action-scheduler
Payload deletes successful jobs because each job stores its input and every log entry stores input, output and error again. This plugin never does that: arguments are stored once and capped (maxArgsBytes, 8 KB), handler output is never stored, only the latest error is kept (truncated), log lines are short and capped at 50 per action, retention purges finished rows, and the transport job carries only { actionId } and completes normally so Payload still deletes it.
Anything that runs Payload jobs runs actions: jobs.autoRun, payload jobs:run --all-queues --handle-schedules, Vercel cron calling GET /api/payload-jobs/run?allQueues=true, Payload Clock, or the admin's Run queue button. A scheduler-tick task (Payload's own schedule) promotes far-future actions, recovers lost attempts, purges by retention and records a heartbeat the admin turns into runner health. tick: false switches it off.
pnpm dev # admin on http://localhost:3310 ([email protected] / test)
pnpm test:unit # engine state machine + utilities, no database
pnpm test:int # real Payload on SQLite
pnpm test:e2e # Playwright against the dev app
Scaffolded with create-payload-app -t plugin (same layout as the other payload-solutions plugins: src/ is the plugin, dev/ is a Next + Payload app that uses it).
Topics
plugin vercel
A Deploy button for editors: trigger, track, cancel and roll back Vercel deployments from the Payload admin.
664/wk2v3
payload plugin scheduler
Date field that queues native Payload schedulePublish jobs for drafts in collections and globals
6720/wk32v3
payload plugin scheduling
Schedule future publication of draft documents in collections and globals via an isolated job queue and cron endpoint
66135/wk30v3
payload plugin outbound webhooks
Send signed HTTP webhooks on collection create, update and delete, delivered durably through the Jobs Queue
6011/wk0v3
n8n webhooks
Register n8n webhooks in Payload and trigger n8n flows from your code or admin
335/wk3v3
payload plugin netlify deploy
Publish button in the Payload admin that builds a Netlify site, streams the log and publishes a preview
6614/wk30v3