SMS Studio
← SMS Studio Blog

How to track SMS delivery with a webhook

Your app sent a booking confirmation. Now a customer says the text never arrived. The message ID lets you find the carrier’s delivery report without sending a second confirmation.

Save the message ID with the booking

Suppose a customer books a Friday appointment under reference BK-1042. Your app sends a confirmation through POST /api/v1/sms/send. When the response contains "status": "Ok", save its id alongside BK-1042 and mark the text as awaiting delivery. If you later send a reminder for the same booking, save its ID separately so you can tell which text reached the customer.

Set up the delivery webhook

Sign in to SMS Studio, open API, choose Delivery URL, enter the public HTTPS address of your receipt handler and select Update. SMS Studio posts delivery receipts to that account URL. Have the handler read the standard payload as application/x-www-form-urlencoded.

Example delivery receipt after your server decodes the form
id
d7160b84-90f9-4469-b012-ad2de7b599dd
status
delivered
phone
12025550123
date
2026-11-12 10:00:00

Look up the booking by the message id. The same phone number can have several bookings. When the carrier reports delivered, record that outcome for this text. The date field gives the original send time. If you need to know when your app received the callback, record that time yourself.

Save the update before returning an HTTP 2xx response. If the same ID and status arrive again, acknowledge the repeat without triggering a second customer notification.

Look up a confirmation when the webhook is missing

For BK-1042, take the saved message ID and query the status endpoint from your server with the same account token. You can check the original send without texting the customer a second time.

Status lookup for the example message
curl --get 'https://api.sms.studio/api/v1/sms/status' \
  -H "Authorization: Bearer $SMS_STUDIO_API_TOKEN" \
  --data-urlencode 'message_id=d7160b84-90f9-4469-b012-ad2de7b599dd'

Read status in the JSON response. A queued, sent or legacy sended result leaves delivery open. Check again later. A delivered result records the carrier’s delivery report. For failed, rejected or undelivered, record the outcome against the booking. An unknown result leaves you without confirmation from the carrier.

If you receive {"status":0,"message":"Message not found"}, check that you used the ID returned by the send request and the token for the account that sent it. If the lookup shows delivery but your app missed the callback, check the saved Delivery URL and your handler’s request and response logs.