Send customer notifications
Send order confirmations, payment receipts, shipping updates, and reminders to your customers by SMS or email. Chime tracks delivery status and lets you retry safely with idempotency keys. This guide shows you how to notify customers immediately or schedule messages for future delivery.
Don't use Chimes for verification codes. If you need to authenticate or verify users with one-time passwords, use the OTP API instead. The OTP API handles token generation, expiry, validation, and rate limiting—critical security features that Chimes doesn't provide. See Verify customers with OTP to learn how to implement secure authentication flows.
How it works
Notifications work in two phases: create the Chime with your message content and recipient details, then query delivery status when you need confirmation. Messages send immediately or at a scheduled time. Chime routes SMS to phone numbers and email to email addresses. Every Chime tracks its transmission lifecycle—initialized, sent, delivered, or failed—so you can determine whether a transmission has started and whether delivery was confirmed.
For email recipients, include a top-level email object with subject, text, and from.address, and omit full_message. Commerce validates the sender, rejects header injection, scans links and HTML, and only sends sanitized content that passes the safety policy.
{
"recipient": {
"type": "email",
"email": {
"address": "[email protected]"
}
},
"email": {
"subject": "Your receipt is ready",
"text": "Your receipt is ready. View it at https://yourstore.example/receipts/or_7821.",
"from": {
"address": "[email protected]"
}
}
}
Step 1: Send a notification immediately
Send a notification right away when order status changes, payment completes, or any event requires immediate customer awareness. Call Send Chime with one of two recipient shapes: use type plus the matching phone.number or email.address for an inline contact, or use transport plus customer_id for a saved customer. Never combine transport with inline contact details.
Send notification
curl https://api.zebo.dev/chimes/send \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipient": {
"type": "phone",
"phone": {
"number": "+233544998605"
},
"name": "Gloria Kesewaa"
},
"full_message": "Your order #OR-7821 has been confirmed. Total: GHS 200.00. Expected delivery: Dec 18-20. Track here: https://pages.zebo.dev/invoices/track/OR-7821",
"sender": "YourStore",
"purpose": "notification",
"request_meta": {
"idempotency_key": "notify_order_OR-7821_confirmed"
},
"custom_data": {
"order_id": "OR-7821",
"event": "order_confirmed",
"customer_id": "cu_gloria_k"
}
}'
The Chime API responds immediately with a Chime ID and initial transmission status. Actual delivery happens asynchronously—SMS typically delivers within seconds, email within a minute.
Using idempotency keys
Pass request_meta.idempotency_key or the Idempotency-Key header to prevent duplicate notifications during retries. If your server crashes after sending but before recording the send, retry with the same key—Chime returns the original notification instead of sending again. This protects customers from receiving confusing duplicate messages for payment confirmations, order updates, and other critical events.
Attaching metadata
Use custom_data to link notifications back to your internal records. Store order IDs, customer IDs, event types, or any context you need for analytics and debugging. Query Chimes later to retrieve this metadata for reconciliation or support investigations.
Step 2: Check delivery status
Verify notification delivery by calling Lookup Chime with the Chime ID. The response includes transmission status, delivery timestamps, and all metadata from creation.
Check delivery
curl https://api.zebo.dev/chimes/lookup \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chime_id": "WkPvqTrqGsopu07wfC7ttoWqmfwt48ZW7BGvYU"
}'
Status values indicate message progress: initialized means a transmission exists but has not been sent, sent means the message was handed off but delivery is not confirmed, delivered means delivery was confirmed, and failed means the transmission could not complete.
Schedule notifications for future delivery
Schedule Chimes when you need notifications delivered at specific future times—subscription renewal reminders, appointment confirmations, or time-based marketing campaigns. Call Schedule Chime with the message, send_after, and recipient objects. Inline recipients use type plus a matching phone or email object; saved customers use transport plus customer_id.
Schedule notification
curl https://api.zebo.dev/chimes/schedule \
-H "Authorization: Bearer $COMMERCE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"recipients": [
{ "type": "phone", "phone": { "number": "+233544998605" } },
{ "type": "phone", "phone": { "number": "+233501234567" } }
],
"full_message": "Reminder: Your subscription renews in 3 days on Dec 18. Update payment details at https://pages.zebo.dev/invoices/billing or contact support.",
"send_after": "2025-12-15T09:00:00Z",
"sender_id": "YourBrand",
"purpose": "reminder"
}'
Scheduled Chimes deliver at or shortly after the specified time. Commerce resolves every saved customer and validates every inline phone number or email address before accepting the schedule. A malformed or unresolved recipient rejects the request; later transmission failures remain isolated to the affected recipient.
Crafting effective notifications
Front-load critical information
Put order numbers, amounts, dates, or urgency first. "Order #OR-7821 shipped. Arrives Dec 18-20" beats "We're excited to inform you that your recent order has been shipped and should arrive soon."
Include actionable links
Always provide next steps: order tracking URLs, payment confirmation pages, or support contact forms. Make URLs meaningful—checkout.zebo.dev/track/OR-7821 tells customers where they're going before they click.
Keep SMS under 160 characters
SMS charges per 160-character segment. Long messages split across multiple texts and confuse recipients. If you need more space, use email instead or shorten the message and link to details.
Use idempotency for critical messages
Payment confirmations, order receipts, and account alerts demand idempotency. Pass a unique key through request_meta.idempotency_key or the Idempotency-Key header constructed from the event—notify_payment_${payment_id}_confirmed—to prevent duplicate notifications during retries.
Next steps
- Chime API Reference — Complete endpoint documentation and response formats
- Product: Chime — Deep dive into Chime features and use cases
- OTP API — Send verification codes for authentication flows
- Orders — Trigger notifications from order events