Introduction
Sharp's unified multi-channel notification engine for SMS, email, WhatsApp, and voice.
The Notifications API lets you send messages across multiple channels from a single endpoint. Instead of integrating each channel separately, you make one request and Sharp handles routing, delivery, and reporting. If the primary channel fails, automatic fallback ensures your message still reaches its recipient through the next available channel.
Unified Endpoint
One API call for SMS, email, WhatsApp, or voice. No channel specific integrations needed.
Automatic Fallback
Define fallback chains so messages are retried on alternate channels if delivery fails.
Workflow Presets
Save reusable channel sequences as workflows. Reference them by ID in any send request.
Scheduled Delivery
Defer delivery to a specific time using ISO 8601 timestamps. Ideal for planned campaigns and timed alerts.
Getting Started
Four steps to send your first multi-channel notification.
Get API Credentials
Open the Sharp Console and navigate to Settings → Developer. Generate an API key. You will use this key as a Bearer token in the Authorization header for all requests.
Check Enabled Channels
Not all channels are available to every organization. Call GET /api/notify/channels to see which channels are enabled for your account. Only enabled channels can be used in send requests.
curl "https://api.moaatech.com/api/notify/channels" \ -H "Authorization: Bearer YOUR_API_KEY"
Send Your First Notification
Use POST /api/notify/send with the channel of your choice. The example below sends an SMS.
curl -X POST "https://api.moaatech.com/api/notify/send" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "sms", "phone": "+2348031234567", "sender": "MTECH", "message": "Hello from Sharp Notifications!", "routeType": "transactional" }'
Set Up Fallback Chains
Add a fallbackChain array to your send request. If SMS fails, Sharp automatically tries the next channel in the chain. See the Fallback Chains section for details.
Channels Overview
Each channel requires different fields in the send request.
| Channel | Required Fields | Notes |
|---|---|---|
| sms | phone, sender | Sender must be an approved sender ID registered in the Console. |
| email, subject | From address is configurable per organization via email sender config. | |
| phone, message | Delivered via WhatsApp Business API. | |
| voice | phone, message | Message is converted to speech and delivered as a phone call. |
message field. The table above shows the additional fields specific to each channel.
Send Notification
Send a message through any available channel with optional fallback.
Sends a notification through the specified channel. If a fallback chain is provided, Sharp will automatically attempt delivery through each subsequent channel if the previous one fails.
| Field | Type | Description |
|---|---|---|
| channel required | string | One of: sms, email, whatsapp, voice |
| message required | string | The notification content. For voice, this text is converted to speech. |
| phone conditional | string | Recipient phone number in international format. Required for sms, whatsapp, voice. |
| email conditional | string | Recipient email address. Required for email channel. |
| sender conditional | string | Approved sender ID. Required for sms channel. |
| subject conditional | string | Email subject line. Required for email channel. |
| routeType optional | string | transactional or promotional. Defaults to transactional. Affects delivery priority and DND handling. |
| fallbackChain optional | string[] | Ordered array of channels to try if primary delivery fails. Example: ["email", "whatsapp"] |
| workflowId optional | uuid | Reference a saved workflow instead of specifying fallbackChain manually. |
| scheduledAt optional | string | ISO 8601 datetime to schedule delivery. Omit for immediate send. |
| Field | Type | Description |
|---|---|---|
| accepted | boolean | Whether the request was accepted for delivery. |
| message_id | uuid | Unique identifier for this notification. |
| channel | string | The primary channel used. |
| scheduled | boolean | Whether delivery is scheduled for a future time. |
| fallback_channels | string[] | Channels that will be attempted if primary fails. |
curl -X POST "https://api.moaatech.com/api/notify/send" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "sms", "phone": "+2348031234567", "sender": "MTECH", "message": "Your order #1042 has been confirmed.", "routeType": "transactional" }'
curl -X POST "https://api.moaatech.com/api/notify/send" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "email", "email": "customer@example.com", "subject": "Order Confirmation #1042", "message": "Your order has been confirmed and is being processed.", "routeType": "transactional" }'
const response = await fetch("https://api.moaatech.com/api/notify/send", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ channel: "sms", phone: "+2348031234567", email: "customer@example.com", sender: "MTECH", subject: "Order Update", message: "Your order #1042 has been shipped.", routeType: "transactional", fallbackChain: ["email", "whatsapp"] }) }); const data = await response.json(); // data.message_id — track delivery across all fallback attempts // data.fallback_channels — ["email", "whatsapp"]
{
"accepted": true,
"message_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel": "sms",
"scheduled": false,
"fallback_channels": ["email", "whatsapp"]
}
Fallback Chains
How automatic multi-channel retry works.
Fallback chains allow you to define an ordered sequence of channels to attempt when sending a notification. If the primary channel fails to deliver, Sharp automatically moves to the next channel in the chain until delivery succeeds or all channels have been exhausted.
| Step | Description |
|---|---|
| 1 | The primary channel is attempted first. |
| 2 | If delivery fails, the next channel in fallbackChain is tried automatically. |
| 3 | Your wallet is deducted for each attempt, at that channel's per-message rate. |
| 4 | All attempts are linked via the same parent_message_id for unified tracking. |
| 5 | If a workflow is referenced via workflowId, the saved channel sequence is used as the fallback chain. |
"channel": "sms" and "fallbackChain": ["email", "whatsapp"] will first try SMS. If SMS fails, it tries email. If email also fails, it tries WhatsApp. Each attempt is charged at the respective channel rate.
phone, sender, email, and subject in the request.
Error Handling
Common error responses from the Notifications API.
| Status | Error | Description |
|---|---|---|
| 400 | Missing recipient field | The request is missing a required field for the selected channel. For example, sending via SMS without a phone field, or via email without email and subject. |
| 402 | Insufficient balance | Your wallet balance is too low to cover the cost of this notification. Top up your wallet in the Console or via the wallet API. |
| 403 | Channel not enabled | The requested channel is not enabled for your organization. Check GET /api/notify/channels to see which channels are available, or contact support to enable additional channels. |
{
"error": "Channel not enabled",
"message": "The whatsapp channel is not enabled for your organization."
}
{
"error": "Insufficient balance",
"message": "Wallet balance too low. Required: 5.50, available: 2.30"
}
{
"error": "Validation error",
"message": "phone is required when channel is sms"
}