Scheduled Sending
Schedule notifications to be sent at a specific future time. Useful for reminders, time-zone-aware delivery, drip campaigns, and delayed notifications.
Overview
Instead of sending immediately, provide a scheduled_at timestamp when creating a notification. Zyphr holds the message and delivers it at the specified time.
Supported channels: email, push, SMS.
Quick Start
Schedule a Message
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Your trial expires tomorrow",
"html": "<p>Just a reminder — your free trial ends tomorrow.</p>",
"scheduled_at": "2026-03-01T09:00:00Z"
}'
await zyphr.emails.send({
to: 'user@example.com',
subject: 'Your trial expires tomorrow',
html: '<p>Just a reminder — your free trial ends tomorrow.</p>',
scheduledAt: '2026-03-01T09:00:00Z',
});
The message will be held and delivered at 9:00 AM UTC on March 1st.
Managing Scheduled Messages
List Scheduled Messages
curl "https://api.zyphr.dev/v1/scheduled?channel=email&status=scheduled&page=1&per_page=25" \
-H "X-API-Key: zy_live_your_api_key"
Query Parameters
| Parameter | Type | Description |
|---|---|---|
channel | string | Filter by channel: email, push, sms |
status | string | Filter by status: scheduled, processing, queued, cancelled, failed |
page | number | Page number (1-indexed) |
per_page | number | Results per page (default: 25, max: 100) |
Get a Scheduled Message
curl https://api.zyphr.dev/v1/scheduled/MSG_UUID \
-H "X-API-Key: zy_live_your_api_key"
The response includes a seconds_until_send field showing the countdown for scheduled messages.
Cancel a Scheduled Message
Cancel a message before it's sent:
curl -X DELETE https://api.zyphr.dev/v1/scheduled/MSG_UUID \
-H "X-API-Key: zy_live_your_api_key"
await zyphr.scheduled.cancel(messageId);
Messages can only be cancelled while in scheduled status. Once a message moves to processing or queued, it cannot be cancelled.
Message Lifecycle
| Status | Description |
|---|---|
scheduled | Message is held, waiting for the scheduled time |
processing | Scheduled time reached, message is being prepared |
queued | Message handed off to the delivery pipeline |
cancelled | Message was cancelled before delivery |
failed | Scheduling or delivery failed |
Statistics
Get an overview of scheduled message activity:
curl https://api.zyphr.dev/v1/scheduled/stats \
-H "X-API-Key: zy_live_your_api_key"
Returns:
- Count of currently scheduled messages by channel
- Count of messages delivered today
- Count of cancelled messages
Best Practices
Time Zones
Always use UTC timestamps for scheduled_at. If you need to send at a user's local time, convert on your server before scheduling:
// Send at 9:00 AM in the user's timezone
const userTz = 'America/New_York';
const sendAt = new Date('2026-03-01T09:00:00');
const utcTime = zonedTimeToUtc(sendAt, userTz);
await zyphr.emails.send({
to: user.email,
subject: 'Good morning!',
scheduledAt: utcTime.toISOString(),
});
Scheduling Window
- Minimum: 1 minute in the future
- Maximum: 30 days in the future
Messages scheduled outside this window will be rejected.
Idempotency
Use idempotency keys when scheduling to prevent duplicate messages if your request is retried:
curl -X POST https://api.zyphr.dev/v1/emails \
-H "X-API-Key: zy_live_your_api_key" \
-H "Idempotency-Key: trial-reminder-user123-20260301" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"subject": "Trial reminder",
"scheduled_at": "2026-03-01T09:00:00Z"
}'
Plan Limits
| Plan | Scheduled Sending |
|---|---|
| Free | Not available |
| Starter | Available |
| Pro | Available |
| Scale | Available |
| Enterprise | Available |
API Reference
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/scheduled | List scheduled messages |
GET | /v1/scheduled/stats | Get scheduling statistics |
GET | /v1/scheduled/:id | Get scheduled message details |
DELETE | /v1/scheduled/:id | Cancel a scheduled message |
Scheduled messages are created through the standard channel endpoints (e.g., POST /v1/emails) by including the scheduled_at parameter. The /v1/scheduled endpoints are for managing and viewing already-scheduled messages.
Next Steps
- Notification Digests - Batch notifications into periodic summaries
- Notification Workflows - Automate multi-step delivery pipelines
- Templates - Create reusable message content