UC-005 — Multi-Channel Send with Automatic Fallback
| Field | Value |
|---|---|
| ID | UC-005 |
| Goal | Send a message on WhatsApp with automatic fallback to RCS and SMS |
| Channel | WhatsApp -> RCS -> SMS |
| Complexity | Intermediate |
| Estimated time | 15 minutes |
| APIs involved | POST /api/message-server/whatsapp/send, GET /api/partner-gateway/v1/messages/status/{customerMessageId} |
Real-world scenarios
- Banca Adriatica — Transaction notification: The bank notifies the account holder of a suspicious transaction. WhatsApp priority for a rich message with confirm/block buttons, SMS fallback to guarantee receipt even if the customer does not use WhatsApp.
- TelcoMobile — Billing reminder: Invoice due date reminder with payment link. WhatsApp for the attached document, SMS as a safety net.
- FarmaExpress — Order ready: The online pharmacy notifies that the order is ready for pickup. WhatsApp with a pickup point map, SMS with a text address as fallback.
Prerequisites
Before you begin, make sure you have:
- Active API Key → How to get one
- Sufficient credit → Check in the Qlara Dashboard
- WhatsApp
phoneNumberId+ RCSagentId+ SMS sender
Add "simulation": true in the request body to validate the flow without actually sending messages and without consuming credit.
Fallback flow
The diagram illustrates the fallback chain: the system first tries WhatsApp, then RCS if available, and finally SMS as a last resort.
Step 1 — Compose the message with fallback chain
The request body includes the main message (WhatsApp) and two fallback objects: fallbackRcs for RCS and fallbackSms for SMS.
If you specify fallbackRcs, you must also include fallbackSms. You can, however, use only fallbackSms without RCS for a direct WhatsApp -> SMS fallback. The fallbacks apply only if your account supports mixed-channel sending: otherwise they are ignored, and the response carries only the whatsapp result.
Body structure
| Field | Type | Required | Description |
|---|---|---|---|
destination | string | Yes | Number in international format (e.g. +393401234567) |
phoneNumberId | integer | Yes | Sender WhatsApp Business number ID |
template | object | Yes* | Meta-approved template (*alternative to body) |
placeholders | object | No | Values to substitute in the template |
fallbackRcs.agentId | integer | Yes | Sender RCS agent ID |
fallbackRcs.templateId | integer | Yes* | RCS template (*alternative to body) |
fallbackSms.sender | string | Yes | SMS sender (alphanumeric or numeric) |
fallbackSms.text | string | Yes | SMS fallback message text |
Step 2 — Send the message
Call the WhatsApp endpoint with the complete fallback chain.
curl -X POST https://api.qlara.ai/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393401234567",
"phoneNumberId": 5,
"template": {
"id": 42
},
"placeholders": {
"nome": "Giulia",
"importo": "1.250,00",
"data": "09/04/2026"
},
"enableNotification": true,
"messageId": "txn-notifica-20260409-001",
"fallbackRcs": {
"agentId": 1,
"templateId": 10
},
"fallbackSms": {
"sender": "BancaAdri",
"text": "Gentile Giulia, e stata registrata una transazione di EUR 1.250,00 in data 09/04/2026. Se non riconosci questa operazione, chiama il numero verde 800.123.456."
}
}'
Response — Message accepted with the fallback chain
{
"messageId": "txn-notifica-20260409-001",
"simulation": false,
"results": {
"whatsapp": {
"accepted": true
},
"rcs": {
"accepted": true
},
"sms": {
"accepted": true,
"unicode": false,
"parts": 1
}
}
}
The API answers 202 Accepted. The RCS and SMS messages are prepared together with the WhatsApp one and sent only if the previous channel fails: that is why rcs and sms are already in the response, although nothing has been delivered yet. With fallbacks, whatsapp.accepted and rcs.accepted are always true; only the SMS can be rejected at this stage (sms.accepted: false, with its reasons). The send response therefore cannot tell you which channel will deliver: the fallback happens later.
Behind the scenes — How the fallback chain works
- WhatsApp attempt: The message is forwarded to Meta via WhatsApp Business API. If the recipient number is registered on WhatsApp and the template is approved, the message is accepted.
- RCS fallback: If WhatsApp fails (unregistered number, rejected template, network error), the system automatically tries RCS using the provided
agentIdandtemplateId. - SMS fallback: If RCS also fails (incompatible device, unreachable agent), the system sends an SMS with the specified
senderandtext.
Each level is independent: you can receive separate delivery callbacks for the channel that actually delivered. The messageId stays the same throughout the chain, enabling end-to-end correlation.
Step 3 — Check which channel delivered
The send response does not tell you which channel delivered, because the fallback happens after the call. Follow the delivery webhooks, or query the delivery status on the channels of the chain (the channel parameter is required). Here the message reached the recipient via SMS:
curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/messages/status/txn-notifica-20260409-001?channel=SMS" \
-H "X-Api-Key: YOUR_API_KEY"
Response — Delivered via SMS
{
"customerMessageId": "txn-notifica-20260409-001",
"channel": "SMS",
"destination": "+393401234567",
"deliveryStatus": "DELIVERED",
"deliveryStatusDescription": "delivered",
"sendDate": "2026-04-09T10:15:00+02:00",
"deliveryDate": "2026-04-09T10:15:04+02:00",
"readDate": null
}
The channel field echoes the channel you queried: it does not by itself tell you which channel delivered. Query the channels of the chain one by one, or use the channel field of the delivery webhook event.
Variant — Direct WhatsApp -> SMS fallback (without RCS)
If you do not have an RCS agent configured, you can skip the intermediate level by omitting fallbackRcs:
curl -X POST https://api.qlara.ai/api/message-server/whatsapp/send \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"destination": "+393489876543",
"phoneNumberId": 5,
"template": {
"id": 55
},
"placeholders": {
"cliente": "Marco Bianchi",
"scadenza": "15/04/2026",
"importo": "89,90"
},
"fallbackSms": {
"sender": "TelcoMob",
"text": "Gentile Marco Bianchi, la sua fattura di EUR 89,90 scade il 15/04/2026. Acceda all area clienti per il pagamento."
}
}'
{
"messageId": "d3f8a1b2-c4e5-6789-abcd-ef0123456789",
"simulation": false,
"results": {
"whatsapp": {
"accepted": true
},
"sms": {
"accepted": true,
"unicode": false,
"parts": 1
}
}
}
Without fallbackRcs, the response has no rcs result.
Common errors
Fallback SMS rejected
At send time only the SMS can be rejected: WhatsApp and RCS are accepted, and a failure of theirs arrives later, with the delivery webhooks. A rejected SMS shows accepted: false and its reasons:
{
"messageId": "txn-notifica-20260409-002",
"simulation": false,
"results": {
"whatsapp": {
"accepted": true
},
"rcs": {
"accepted": true
},
"sms": {
"accepted": false,
"unicode": false,
"parts": 1,
"reasons": ["SMS sender not allowed"]
}
}
}
Corrective actions table
| Situation | Action |
|---|---|
sms.accepted: false in the response | Check sms.reasons: use a sender enabled for your account, and verify the recipient number |
| Only SMS fails | Check the sender ID and text (length, special characters) |
| WhatsApp fails, RCS or SMS delivers | The recipient may not have WhatsApp — the fallback is working correctly |
400 error with code 32 or 33 | Invalid phoneNumberId (32), or template not found or not approved (33) |
400 error with code 30 or 31 | RCS agent (30) or RCS template (31) of fallbackRcs not found |
429 error | Rate limit exceeded — wait and retry |
Expected result
| Step | Action | Result |
|---|---|---|
| 1 | Compose body with fallbackRcs + fallbackSms | Fallback chain configured |
| 2 | POST /whatsapp/send | messageId returned, with a result for each channel of the chain |
| 3 | GET /messages/status/{id}?channel=SMS | deliveryStatus: "DELIVERED" on the channel that delivered the message |
Next steps
- UC-008 — Delivery Tracking with Webhooks: Receive real-time updates on which channel delivered
- WhatsApp Guide: Deep dive into templates, media, and the 24-hour window
- Channel Overview: Compare SMS, RCS, and WhatsApp to choose the right strategy