Notifications API
v1.0
Docs Home API Reference

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.

Base URL https://api.moaatech.com

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.

1

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.

2

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"
3

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"
  }'
4

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 email, subject From address is configurable per organization via email sender config.
whatsapp phone, message Delivered via WhatsApp Business API.
voice phone, message Message is converted to speech and delivered as a phone call.
All channels also require the 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.

POST /api/notify/send

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.

Request Body
FieldTypeDescription
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.
Response
FieldTypeDescription
acceptedbooleanWhether the request was accepted for delivery.
message_iduuidUnique identifier for this notification.
channelstringThe primary channel used.
scheduledbooleanWhether delivery is scheduled for a future time.
fallback_channelsstring[]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"]
200 Response
{
  "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.

How It Works
StepDescription
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.
Example: A send request with "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.
Ensure you provide the required fields for all channels in your fallback chain. For example, if your chain includes both SMS and email, you must include phone, sender, email, and subject in the request.

Error Handling

Common error responses from the Notifications API.

StatusErrorDescription
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.
403 Example Error Response
{
  "error": "Channel not enabled",
  "message": "The whatsapp channel is not enabled for your organization."
}
402 Example Error Response
{
  "error": "Insufficient balance",
  "message": "Wallet balance too low. Required: 5.50, available: 2.30"
}
400 Example Error Response
{
  "error": "Validation error",
  "message": "phone is required when channel is sms"
}