Servers & devices

Cron jobs

Set up the background schedule Zender needs to actually dispatch scheduled messages, wake up devices, expire subscriptions, and clean up old files — none of which happen on their own without it.

Zender doesn't run any background process of its own. Everything time-based — dispatching scheduled messages, prompting devices and WhatsApp accounts to fetch their queued sends, expiring subscriptions, and clearing old files — only happens when something calls one of the endpoints below from outside the app, on a schedule you set up yourself. Without cron configured, none of it runs on its own, no matter how long the site is up.

Every job is called the same way: /cron/{endpoint}/{token}, where {token} is your site's system token (see the Configuration page for where that value lives). A wrong or missing token is rejected and nothing runs. A super admin can see the exact command for every job below, pre-filled with your site's real token, from Admin → Overview — the Cron button there opens the same setup guide this page is describing.

Without cron running, scheduled SMS and WhatsApp messages never go out — they just sit queued forever — and expired subscriptions never get cleaned up or emailed about. If a customer reports scheduled sends "doing nothing," check cron before anything else.

Endpoints

EndpointPurposeRecommended interval
sender Pushes an FCM wake-up to every device and WhatsApp account with messages waiting in their queue, so they fetch and send immediately instead of waiting for their next poll. Every minute
sms.scheduled Finds SMS scheduled sends whose time (or repeat interval) has arrived, builds the recipient list from pasted numbers and/or contact groups, and queues the actual messages for sending. Every minute
wa.scheduled The WhatsApp equivalent of sms.scheduled — resolves due schedules, checks the target WhatsApp account is actually connected, and queues the messages before asking the WhatsApp server to send them. Every minute
subscription Warns subscribers by email 5 days before their package expires, and deletes (plus emails) subscriptions that have already expired. Every 5–15 minutes
cleaner Deletes WhatsApp received/sent media files older than the configured retention period, and asks every registered WhatsApp server to run the same garbage collection on its own stored files. Once daily
quota Resets usage quotas — see the warning below before scheduling this one. See below
quota is destructive and unconditional: every time this endpoint is hit, it wipes usage counters for every user on the site at once, not just whoever is due for a reset. Schedule it to match your site's actual reset cadence (daily or monthly, set from the Settings screen under Admin → Overview — the dashboard's cron setup guide shows you which one applies) and nothing more often. Adding it to a per-minute crontab line like the other jobs will reset every user's SMS/WhatsApp usage counters every minute.

Example crontab

Replace your-domain.com with your real site domain, prefixed with whichever scheme (http or https) your site actually runs under, and YOUR_SYSTEM_TOKEN with your real system token:

* * * * * curl -s "your-domain.com/cron/sender/YOUR_SYSTEM_TOKEN" > /dev/null
* * * * * curl -s "your-domain.com/cron/sms.scheduled/YOUR_SYSTEM_TOKEN" > /dev/null
* * * * * curl -s "your-domain.com/cron/wa.scheduled/YOUR_SYSTEM_TOKEN" > /dev/null
*/5 * * * * curl -s "your-domain.com/cron/subscription/YOUR_SYSTEM_TOKEN" > /dev/null
0 3 * * * curl -s "your-domain.com/cron/cleaner/YOUR_SYSTEM_TOKEN" > /dev/null
0 0 * * * curl -s "your-domain.com/cron/quota/YOUR_SYSTEM_TOKEN" > /dev/null

The last line assumes Daily reset mode and runs at midnight; on Monthly reset mode, move it to a monthly line (e.g. 0 0 1 * *) instead.