Skip to main content

Sending Notifications

Send push notifications, emails, SMS, or webhook callbacks using channel-specific APIs on ductape.notifications. Each channel (.email, .push, .sms, .callback) exposes a .send() method so you can target that channel only.

Channel-Specific Methods

Push: notifications.push.send()

Send via the push channel only (Firebase, Expo):

const result = await ductape.notifications.push.send({
product: 'my-app',
env: 'prd',
notification: 'alerts:welcome',
input: {
device_tokens: ['device-token-1', 'device-token-2'],
title: { name: 'John' },
body: { message: 'Welcome to our app!' },
data: { action: 'open_home' },
},
});

console.log(result.success); // true
console.log(result.messageId); // unique ID

Email: notifications.email.send()

Send via the email channel only:

const result = await ductape.notifications.email.send({
product: 'my-app',
env: 'prd',
notification: 'emails:order-confirmation',
input: {
recipients: ['customer@example.com', 'admin@example.com'],
subject: { orderId: '12345' },
template: {
customerName: 'John Doe',
orderTotal: '$99.99',
},
},
});

console.log(result.success); // true

SMS: notifications.sms.send()

Send via the SMS channel only:

const result = await ductape.notifications.sms.send({
product: 'my-app',
env: 'prd',
notification: 'sms:verification',
input: {
recipients: ['+1234567890', '+0987654321'],
body: { code: '123456' },
},
});

console.log(result.success); // true

Callback: notifications.callback.send()

Send via the webhook/callback channel only:

const result = await ductape.notifications.callback.send({
product: 'my-app',
env: 'prd',
notification: 'webhooks:order-created',
input: {
body: {
orderId: '12345',
status: 'created',
timestamp: Date.now(),
},
headers: {
'X-Custom-Header': 'value',
},
},
});

console.log(result.success); // true

Multi-Channel Send

Send to multiple channels at once using notifications.send() with an input object that includes multiple channel keys:

const result = await ductape.notifications.send({
product: 'my-app',
env: 'prd',
event: 'alerts:order-shipped',
input: {
push_notification: {
device_tokens: ['token1'],
title: { status: 'Order Shipped!' },
body: { message: 'Your order is on its way' },
data: { trackingNumber: 'ABC123' },
},
email: {
recipients: ['customer@example.com'],
subject: { orderId: '12345' },
template: { trackingUrl: 'https://track.example.com/ABC123' },
},
sms: {
recipients: ['+1234567890'],
body: { tracking: 'ABC123' },
},
},
});

// Check results per channel
console.log(result.success); // true if at least one succeeded
console.log(result.channels?.push?.success);
console.log(result.channels?.email?.success);
console.log(result.channels?.sms?.success);

Scheduling Notifications

Schedule notifications for later using notifications.dispatch():

const result = await ductape.notifications.dispatch({
product: 'my-app',
env: 'prd',
notification: 'reminders',
event: 'payment-due',
input: {
push_notification: {
device_tokens: ['token1'],
title: { name: 'Payment' },
body: { message: 'Your payment is due' },
},
},
schedule: {
start_at: Date.now() + 86400000, // 24 hours from now
},
retries: 3,
});

console.log(result.job_id); // unique job ID
console.log(result.status); // 'queued'

Schedule Options

OptionTypeDescription
start_atnumber/stringTimestamp when to send
cronstringCron expression for recurring
everynumberInterval in milliseconds
limitnumberMax number of sends
endDatenumber/stringWhen to stop recurring
tzstringTimezone for scheduling

Using Session Data

Include session context for user-specific data. Pass session as a string in the format session_tag:jwt_token:

await ductape.notifications.push.send({
product: 'my-app',
env: 'prd',
notification: 'alerts:personalized',
input: {
device_tokens: ['token1'],
title: { greeting: 'Hi there!' },
body: { message: 'Check out your personalized recommendations' },
},
session: 'user-session:eyJhbGciOi...',
});

Optional Parameters

ParameterTypeDescription
sessionstringSession in format session_tag:jwt_token for authenticated requests
cachestringCache tag to avoid duplicate sends

Reference

Channel APIs

APIOptions typeDescription
notifications.email.send(options)IEmailOptionsSend via email channel only
notifications.push.send(options)IPushOptionsSend via push channel only
notifications.sms.send(options)ISmsOptionsSend via SMS channel only
notifications.callback.send(options)ICallbackOptionsSend via webhook/callback channel only

IPushOptions

Used by notifications.push.send():

interface IPushOptions {
product: string;
env: string;
notification: string; // format: notification_tag:message_tag
input: {
device_tokens: string[];
title?: Record<string, unknown>;
body?: Record<string, unknown>;
data?: Record<string, unknown>;
};
session?: string; // format: session_tag:jwt_token
cache?: string;
}

IEmailOptions

Used by notifications.email.send():

interface IEmailOptions {
product: string;
env: string;
notification: string;
input: {
recipients: string[];
subject?: Record<string, unknown>;
template?: Record<string, unknown>;
};
session?: string; // format: session_tag:jwt_token
cache?: string;
}

ISmsOptions

Used by notifications.sms.send():

interface ISmsOptions {
product: string;
env: string;
notification: string;
input: {
recipients: string[];
body?: Record<string, unknown>;
};
session?: string; // format: session_tag:jwt_token
cache?: string;
}

ICallbackOptions

Used by notifications.callback.send():

interface ICallbackOptions {
product: string;
env: string;
notification: string;
input: {
query?: Record<string, unknown>;
headers?: Record<string, unknown>;
params?: Record<string, unknown>;
body?: Record<string, unknown>;
};
session?: string; // format: session_tag:jwt_token
cache?: string;
}

INotificationResult

interface INotificationResult {
success: boolean;
channel: 'push' | 'email' | 'sms' | 'callback';
messageId?: string;
error?: string;
}

IMultiChannelNotificationResult

interface IMultiChannelNotificationResult {
success: boolean; // true if at least one channel succeeded
channels: {
push?: INotificationResult;
email?: INotificationResult;
sms?: INotificationResult;
callback?: INotificationResult;
};
}

Fetching notification message logs

Use notifications.getMessages() to fetch send history with time filters. Results are scoped to your workspace and include status (pending, sent, failed, reprocessing) and type (channel). All query parameters are optional.

const { items, total, hasMore } = await ductape.notifications.getMessages({
product_tag: 'my-app',
env: 'prd',
start_date: new Date(Date.now() - 7 * 864e5).toISOString(),
end_date: new Date().toISOString(),
status: 'failed',
type: 'email',
page: 1,
limit: 50,
});

See Notification Message Logs for full query options, response shape, and reprocessing.

See Also