Skip to content

Status Callbacks

Status callbacks let your AI agent (or backend system) receive real-time updates about notification delivery. This enables agents to react to delivery outcomes, retry failures, or escalate to alternative channels.

Include a callback_url in your notification request:

POST /v1/agent/notify
{
"intent": "Remind Sarah about her appointment",
"urgency": "normal",
"context": { "user_id": "sarah@example.com" },
"callback_url": "https://your-server.com/webhooks/smooven"
}

Smooven sends a POST request to your callback URL with the following payload:

{
"event": "notification.delivered",
"notification_id": "ntf_abc123def456",
"channel_used": "sms",
"status": "delivered",
"timestamp": "2026-03-05T08:00:15Z",
"recipient": {
"user_id": "sarah@example.com",
"channel_address": "+61400000000"
},
"metadata": {
"intent": "Remind Sarah about her appointment",
"urgency": "normal"
}
}
EventDescription
notification.queuedNotification accepted and queued for delivery
notification.sentHanded off to the delivery provider
notification.deliveredConfirmed delivery to the recipient
notification.failedPermanent delivery failure
notification.fallbackPrimary channel failed, falling back to another channel
notification.openedRecipient opened the notification (email, push)
notification.clickedRecipient clicked a link or action (email, push, RCS)

If you are building an AI agent that needs to confirm delivery before proceeding, use callbacks to create an asynchronous verification loop:

import asyncio
from aiohttp import web
# Store pending notifications
pending = {}
async def send_notification(intent, user_id):
response = requests.post(
'https://api.smooven.io/v1/agent/notify',
headers={'Authorization': 'Bearer YOUR_SECRET_KEY'},
json={
'intent': intent,
'context': {'user_id': user_id},
'callback_url': 'https://your-server.com/webhooks/smooven',
},
)
data = response.json()
pending[data['notification_id']] = asyncio.Event()
return data['notification_id']
async def webhook_handler(request):
payload = await request.json()
ntf_id = payload['notification_id']
if ntf_id in pending:
pending[ntf_id].set()
return web.Response(status=200)
async def send_and_wait(intent, user_id, timeout=30):
ntf_id = await send_notification(intent, user_id)
try:
await asyncio.wait_for(pending[ntf_id].wait(), timeout)
return True # Delivered
except asyncio.TimeoutError:
return False # Timed out
  • Smooven retries failed callback deliveries up to 3 times with exponential backoff (5s, 30s, 2min)
  • Callbacks include an X-Smooven-Signature header for request verification
  • Verify signatures using your Secret Key to ensure callbacks are authentic