Documentation
Everything you need to integrate Dispatch into your application. Send your first notification in under 5 minutes.
Getting Started
Get your API key and send your first notification in minutes.
1. Get Your API Key
Sign up at dispatch.wejoona.com and create an API key from the dashboard. Keys are prefixed with dp_live_ for production and dp_test_ for sandbox.
2. Install an SDK (Optional)
Use the REST API directly, or install one of the official SDKs.
# Node.js
npm install @dispatch/node
# Python
pip install dispatch-sdk
# Go
go get github.com/joonapay/dispatch-go3. Send Your First Notification
curl -X POST https://api.dispatch.wejoona.com/v1/send \
-H "Authorization: Bearer dp_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": { "email": "[email protected]" },
"channels": ["email"],
"template": "welcome",
"data": { "name": "Jane" }
}'import { Dispatch } from '@dispatch/node';
const dispatch = new Dispatch('dp_live_your_key');
await dispatch.send({
to: { email: '[email protected]' },
channels: ['email'],
template: 'welcome',
data: { name: 'Jane' },
});4. Check Delivery Status
Every send returns a notification ID. Use it to check delivery status.
curl https://api.dispatch.wejoona.com/v1/notifications/ntf_abc123 \
-H "Authorization: Bearer dp_live_your_key"{
"id": "ntf_abc123",
"status": "delivered",
"channels": {
"email": {
"status": "delivered",
"delivered_at": "2025-01-15T10:30:02Z"
}
},
"created_at": "2025-01-15T10:30:00Z"
}Channels
Dispatch supports 6 notification channels. Each channel includes automatic retries and failover.
Transactional email with automatic DKIM/SPF/DMARC handling. Supports HTML and plain text with full delivery tracking.
SMS
Send SMS globally with automatic carrier routing. Delivery receipts and character encoding handled for you.
Push
Push notifications to mobile and web. Supports FCM v1 API and Apple Push Notification Service.
Send WhatsApp messages via the official Business API. Template messages, session messages, and media support.
Webhooks
Deliver notifications to any HTTP endpoint. HMAC-signed payloads with configurable retry logic.
In-App
Store notifications in user inboxes. Query via API or subscribe via WebSocket for real-time delivery.
Multi-Channel Send
Send to multiple channels in a single API call. Dispatch routes each channel independently with its own delivery tracking.
{
"to": {
"email": "[email protected]",
"phone": "+233241234567",
"device_token": "fcm_token_here",
"whatsapp": "+233241234567",
"webhook_url": "https://hooks.example.com/notify",
"user_id": "usr_abc123"
},
"channels": ["email", "sms", "push", "whatsapp", "webhook", "in_app"],
"template": "order-shipped",
"data": {
"order_id": "ORD-7291",
"tracking_url": "https://track.example.com/ORD-7291"
}
}Templates
Templates use Handlebars syntax with per-channel content. Variables, conditionals, loops, and partials are supported.
Create a Template
{
"name": "order-shipped",
"channels": {
"email": {
"subject": "Your order {{order_id}} has shipped!",
"html": "<h1>Hi {{name}},</h1><p>Your order <strong>{{order_id}}</strong> is on its way.</p><p><a href='{{tracking_url}}'>Track your package</a></p>"
},
"sms": {
"body": "Hi {{name}}, your order {{order_id}} has shipped! Track: {{tracking_url}}"
},
"push": {
"title": "Order Shipped",
"body": "{{name}}, your order {{order_id}} is on its way!"
},
"whatsapp": {
"template_name": "order_shipped",
"parameters": ["{{name}}", "{{order_id}}", "{{tracking_url}}"]
}
}
}Variables and Conditionals
{{! Simple variable }}
Hello {{name}},
{{! Conditional }}
{{#if premium}}
Thank you for being a premium member!
{{else}}
Upgrade to premium for priority delivery.
{{/if}}
{{! Loop }}
{{#each items}}
- {{this.name}}: ${{this.price}}
{{/each}}Preview and Test
Preview rendered templates before sending. Pass test data to see exactly what recipients will receive.
{
"channel": "email",
"data": {
"name": "Jane",
"order_id": "ORD-7291",
"tracking_url": "https://track.example.com/ORD-7291"
}
}API Reference
Base URL: https://api.dispatch.wejoona.com/v1
Authentication
All requests require a Bearer token. Include it in the Authorization header.
Authorization: Bearer dp_live_your_keyEndpoints
/v1/sendSend a notification to one or more channels
/v1/send/batchSend to up to 10,000 recipients in one call
/v1/notifications/:idGet notification status and delivery details
/v1/notificationsList notifications with filtering and pagination
/v1/templatesCreate a notification template
/v1/templatesList all templates
/v1/templates/:nameUpdate an existing template
/v1/templates/:nameDelete a template
/v1/keysCreate a new API key
/v1/analytics/channelsDelivery analytics per channel
/v1/webhooksRegister a webhook endpoint
/v1/webhooksList registered webhook endpoints
/v1/webhooks/:idRemove a webhook endpoint
Errors
All errors follow a consistent format with machine-readable error codes.
{
"error": {
"code": "invalid_template",
"message": "Template 'welcome' not found. Create it first via POST /v1/templates.",
"status": 404
}
}Rate Limits
Webhooks
Receive real-time notifications about delivery events. Dispatch sends webhook events for status changes across all channels.
Register a Webhook
{
"url": "https://your-app.com/webhooks/dispatch",
"events": ["notification.delivered", "notification.failed", "notification.bounced"],
"secret": "whsec_your_signing_secret"
}Event Types
notification.sentNotification accepted and queued for deliverynotification.deliveredSuccessfully delivered to the recipientnotification.failedDelivery failed after all retry attemptsnotification.bouncedEmail bounced (hard or soft)notification.openedRecipient opened the notification (email)notification.clickedRecipient clicked a link in the notificationWebhook Payload
{
"id": "evt_abc123",
"type": "notification.delivered",
"timestamp": "2025-01-15T10:30:02Z",
"data": {
"notification_id": "ntf_abc123",
"channel": "email",
"recipient": "[email protected]",
"template": "order-shipped"
}
}Verifying Signatures
Every webhook request includes an X-Dispatch-Signature header. Verify it using HMAC-SHA256 with your webhook secret.
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry Policy
Failed webhook deliveries are retried up to 5 times with exponential backoff (1s, 5s, 30s, 2min, 10min). If your endpoint returns a non-2xx status code, the delivery is marked as failed and retried.
Need help? Open an issue on GitHub or email [email protected]