sendpigeon
v1.12.0
Published
Official Node.js SDK for SendPigeon email API
Downloads
158
Maintainers
Readme
sendpigeon
Official Node.js SDK for SendPigeon - transactional email API.
Install
npm install sendpigeonQuick Start
import { SendPigeon } from "sendpigeon";
const pigeon = new SendPigeon("sp_live_your_api_key");
const { data, error } = await pigeon.send({
from: "[email protected]",
to: "[email protected]",
subject: "Hello!",
html: "<p>Welcome aboard.</p>",
});
if (error) {
console.error(error.message);
// error.code: "api_error" | "network_error" | "timeout_error"
// error.apiCode: "QUOTA_EXCEEDED" | "DOMAIN_NOT_VERIFIED" | ...
// error.status: 402
} else {
console.log(data.id); // "em_abc123"
}React Email
Use React Email components directly:
import { SendPigeon } from "sendpigeon";
import { WelcomeEmail } from "./emails/welcome";
const { data, error } = await pigeon.send({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome!",
react: <WelcomeEmail name="John" />,
});Requires @react-email/render as peer dependency:
npm install @react-email/renderConfiguration
const pigeon = new SendPigeon("sp_live_your_api_key", {
timeout: 30000, // request timeout in ms (default: 30s)
maxRetries: 2, // retry on 429/5xx (default: 2, max: 5, 0 to disable)
debug: true, // log requests/responses to console
});Retries use exponential backoff and respect Retry-After headers.
Local Development
Use @sendpigeon-sdk/cli to catch emails locally:
# Terminal 1: Start local server
npx @sendpigeon-sdk/cli dev
# Terminal 2: Run your app with dev mode
SENDPIGEON_DEV=true npm run devWhen SENDPIGEON_DEV=true, the SDK routes requests to localhost:4100 instead of production.
Tracking
Enable open/click tracking per email (opt-in):
const { data } = await pigeon.send({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome!",
html: "<p>Check out our <a href='https://example.com'>site</a>!</p>",
tracking: {
opens: true, // Track opens via invisible pixel
clicks: true, // Track link clicks
},
});
// Response may include warnings if tracking is disabled at org level
if (data.warnings) {
console.log("Warnings:", data.warnings);
}Configure organization defaults in Settings → Tracking.
Contacts
Manage your audience for broadcasts:
// Add a contact (e.g. on signup)
await pigeon.contacts.create({
email: "[email protected]",
firstName: "John",
tags: ["newsletter"],
});
// Batch import
await pigeon.contacts.batch([
{ email: "[email protected]", tags: ["newsletter"] },
{ email: "[email protected]", tags: ["newsletter"] },
]);
// List, filter, search
await pigeon.contacts.list({ tag: "newsletter", status: "active" });Broadcasts
Send emails to your contacts with tag-based targeting. Requires a paid plan.
// 1. Create a broadcast (draft)
const { data: broadcast } = await pigeon.broadcasts.create({
name: "March Newsletter",
subject: "What's new",
htmlContent: "<h1>Hello!</h1>",
fromEmail: "[email protected]",
fromName: "Your Company",
});
// 2. Send a test
await pigeon.broadcasts.test(broadcast.id, { email: "[email protected]" });
// 3. Send to contacts with tag targeting
await pigeon.broadcasts.send(broadcast.id, {
includeTags: ["newsletter"],
excludeTags: ["uninterested"],
});
// Or schedule for later
await pigeon.broadcasts.schedule(broadcast.id, {
scheduledAt: "2026-03-10T09:00:00Z",
includeTags: ["newsletter"],
});
// Get analytics (opens, clicks)
await pigeon.broadcasts.analytics(broadcast.id);Available Methods
// Send emails
pigeon.send(email)
pigeon.sendBatch(emails)
// Email status
pigeon.emails.get(id)
pigeon.emails.cancel(id)
// Contacts
pigeon.contacts.list(opts?)
pigeon.contacts.create(data)
pigeon.contacts.batch(contacts)
pigeon.contacts.get(id)
pigeon.contacts.update(id, data)
pigeon.contacts.delete(id)
pigeon.contacts.unsubscribe(id)
pigeon.contacts.resubscribe(id)
pigeon.contacts.stats()
pigeon.contacts.tags()
// Broadcasts
pigeon.broadcasts.list(opts?)
pigeon.broadcasts.create(data)
pigeon.broadcasts.get(id)
pigeon.broadcasts.update(id, data)
pigeon.broadcasts.delete(id)
pigeon.broadcasts.duplicate(id)
pigeon.broadcasts.send(id, targeting?)
pigeon.broadcasts.schedule(id, data)
pigeon.broadcasts.cancel(id)
pigeon.broadcasts.test(id, data)
pigeon.broadcasts.recipients(id, opts?)
pigeon.broadcasts.analytics(id)
// Events
pigeon.events.send({ email, eventName, properties?, contactProperties?, tags? })
pigeon.events.list({ name?, contactId?, since?, until? })
pigeon.contacts.events(id, { name?, since?, until? })
// Sequences
pigeon.sequences.list({ status? })
pigeon.sequences.create({ name, triggerType, triggerConfig? })
pigeon.sequences.get(id)
pigeon.sequences.update(id, data)
pigeon.sequences.delete(id)
pigeon.sequences.activate(id)
pigeon.sequences.pause(id)
pigeon.sequences.archive(id)
pigeon.sequences.duplicate(id)
pigeon.sequences.analytics(id)
// Sequence Steps
pigeon.sequences.steps.list(seqId)
pigeon.sequences.steps.create(seqId, { type, config })
pigeon.sequences.steps.update(seqId, stepId, data)
pigeon.sequences.steps.delete(seqId, stepId)
pigeon.sequences.steps.reorder(seqId, order)
pigeon.sequences.steps.analytics(seqId, stepId)
// Enrollments
pigeon.sequences.enroll(seqId, { contacts, triggerData? })
pigeon.sequences.enrollments.list(seqId, { status? })
pigeon.sequences.enrollments.get(seqId, enrollmentId)
pigeon.sequences.enrollments.pause(seqId, enrollmentId)
pigeon.sequences.enrollments.resume(seqId, enrollmentId)
pigeon.sequences.enrollments.exit(seqId, enrollmentId)
// Templates
pigeon.templates.list()
pigeon.templates.create(data)
pigeon.templates.get(id)
pigeon.templates.update(id, data)
pigeon.templates.delete(id)
pigeon.templates.publish(id)
pigeon.templates.unpublish(id)
pigeon.templates.test(id, data)
// Domains
pigeon.domains.list()
pigeon.domains.create({ name })
pigeon.domains.get(id)
pigeon.domains.verify(id)
pigeon.domains.delete(id)
// API Keys
pigeon.apiKeys.list()
pigeon.apiKeys.create({ name, mode?, permission? })
pigeon.apiKeys.delete(id)
// Suppressions
pigeon.suppressions.list(opts?)
pigeon.suppressions.delete(email)
// Tracking
pigeon.tracking.getDefaults()
pigeon.tracking.updateDefaults(data)
// Webhooks
pigeon.webhooks.getConfig()
pigeon.webhooks.enable(data)
pigeon.webhooks.update(data)
pigeon.webhooks.disable()
pigeon.webhooks.delete()
pigeon.webhooks.regenerateSecret()
pigeon.webhooks.test()
pigeon.webhooks.listDeliveries()Webhook Verification
import { verifyWebhook, verifyInboundWebhook } from "sendpigeon";
// Outbound events (delivered, bounced, complained)
const result = await verifyWebhook({ payload, signature, timestamp, secret });
// Inbound emails
const result = await verifyInboundWebhook({ payload, signature, timestamp, secret });Documentation
Full documentation with examples: sendpigeon.dev/docs
License
MIT
