Skip to main content

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

ParameterTypeDescription
channelstringFilter by channel: email, push, sms
statusstringFilter by status: scheduled, processing, queued, cancelled, failed
pagenumberPage number (1-indexed)
per_pagenumberResults 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);
warning

Messages can only be cancelled while in scheduled status. Once a message moves to processing or queued, it cannot be cancelled.

Message Lifecycle

StatusDescription
scheduledMessage is held, waiting for the scheduled time
processingScheduled time reached, message is being prepared
queuedMessage handed off to the delivery pipeline
cancelledMessage was cancelled before delivery
failedScheduling 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

PlanScheduled Sending
FreeNot available
StarterAvailable
ProAvailable
ScaleAvailable
EnterpriseAvailable

API Reference

MethodEndpointDescription
GET/v1/scheduledList scheduled messages
GET/v1/scheduled/statsGet scheduling statistics
GET/v1/scheduled/:idGet scheduled message details
DELETE/v1/scheduled/:idCancel a scheduled message
note

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