For the complete documentation index, see llms.txt. This page is also available as Markdown.

Appointment Reminders with confirmation replies

Learn how to build an appointment reminder workflow with the Mobile Text Alerts API

This guide shows how to build a complete appointment reminder workflow with the Mobile Text Alerts API. This includes scheduling a personalized reminder ahead of time, letting the recipient respond by replying, and keeping your appointment records in sync with the user response. This use case uses multiple API endpoints, this guide shows how to use them together in one worked example.

Appointment reminder workflow overview

The following is the typical appointment reminder workflow:

Schedule a personalized reminder ahead of an appointment The recipient can reply to confirm, change or cancel the appointment Update your system for any appointment changes

Implementation steps:

  1. An appointment is created in your system.

  2. You schedule a reminder message to send ahead of the appointment. This is personalized with the recipient's name, time, and location.

  3. Mobile Text Alerts sends the reminder message at the scheduled time (in the recipient's local time).

  4. The recipient replies — to confirm, cancel, or ask to reschedule.

  5. Your webhook endpoint receives this reply and then updates the appointment record in your system.

  6. If the appointment time changes or is cancelled before it is sent, then the scheduled reminder is updated or cancelled.

This user guide walks through these steps, including the request fields and endpoints. It covers scheduledDate, properties, the message-reply webhook, and the Scheduled Messages endpoints.

Prerequisites

Before building this workflow you need to have:

  • Completed the steps in Getting Started and have a valid API key.

  • A verified sending number. Trial accounts and unverified numbers can only send templated content, which will limit how much you can personalize a reminder.

  • A webhook endpoint that is already registered and receiving message-reply events. See Setting up your first webhook if this has not been configured yet.

Store appointment data

Mobile Text Alerts holds the message and schedule, but the appointment itself is your data. At minimum, keep a record per appointment with the following fields:

Field
Purpose

appointmentId

Your own internal identifier for the appointment.

subscriberNumber

The recipient's phone number, in E.164 format.

appointmentDateTime

The appointment date and time.

recipientTimezone

The recipient's local timezone (IANA name, e.g. America/Chicago), used to compute the correct offset for scheduledDate.

externalId

The identifier you sent on the reminder's /send request — typically derived from appointmentId. Used to match an inbound reply back to this appointment.

messageId*

The messageId returned by /send when the reminder was created.

scheduledMessageId*

The scheduled message's own ID, returned when the reminder is created as a future send. Needed to later update or cancel the reminder before it fires.

status

This is the confirmation state, one of the following: pending, confirmed, cancelled, or reschedule_requested.

*Note messageId and scheduledMessageId serve different purposes:

  • messageId identifies the message record for reconciliation and delivery status

  • scheduledMessageId is used to update or delete the pending send itself

Schedule the reminder

Reminder messages are sent with a POST /send request, using the scheduledDate field as the scheduled delivery time.

Timezone handling

The scheduledDate field is an ISO 8601 string with an explicit UTC offset. For example, "20260615T143000-0500" represents 2:30 PM in a UTC-5 timezone. There is no separate timezone parameter. The offset in the string is the timezone.

Compute the offset for the recipient's local reminder delivery time.

Example scenarios with an offset:

  • For a reminder scheduled for 9:00 AM in America/Chicago, scheduledDate needs the America/Chicago offset for that delivery date, not your application server's offset.

  • Daylight saving transitions mean the correct offset for a June delivery (-0500 for Central Daylight Time) can differ from the offset in effect in December (-0600 for Central Standard Time). Always resolve the offset against the target delivery date using your timezone library, not a hardcoded value.

Code example:

The following resolves the reminder's local delivery time to scheduledDate and computes the offset for that delivery date.

Send the scheduled reminder

When sending the reminder message you need to set the externalId field to your own appointment identifier so it comes back on any webhook related to this message. Then store the messageId Mobile Text Alerts returns in response.

Use tags to carry extra context

The tags field is a general purpose key/value map of the outbound message and is echoed back on any related webhook event, including the reply. Unlike externalId, which is a single string, tags can hold multiple fields. This is useful for passing metadata your reply handler needs without an extra database lookup, such as appointmentId, locationId, or providerId.

Scheduling a message also creates a scheduled message record you can look up, update, or delete later — see Change or cancel a reminder message below.

Personalize the reminder

The properties field maps each recipient number to a set of Liquid template variables referenced in message with {{variableName}} syntax. Each subscriber gets their own set of values in the same request, which is what makes it possible to send one templated reminder to many recipients with different appointment details.

The following example uses firstName, appointmentTime, providerName, and location, but you can create variables that suit your use case.

If your reminder content is fixed and only the variables change, such as a standardized clinic reminder format, consider defining it as a reusable message template with templateId instead of inlining message on every request.

See Properties field for custom variables in messages to learn more.

Handle the message reply

How reply attribution works in SMS

It is important to note that SMS is not a threaded medium. There is no concept of a "conversation ID" that a phone enforces, instead replies simply appear in chronological order in the recipient's default messaging app, alongside every other message from that same number. When a subscriber replies, Mobile Text Alerts can only attribute that reply to the most recent outbound message sent to that number, because that is the only attribution the channel itself provides. This is exactly what externalId and tags deliver on the message-reply payload: MTA echoes back the identifying data from that last outbound send.

A subscriber could have more than one appointment reminder outstanding at the same time, such as two appointments in the same week. If they reply, the reply payload alone won't tell you which appointment "confirm" refers to if your message copy doesn't make it unambiguous. So the distinguishing detail has to live in the message text itself:

Example message:

Referencing a specific day/time in the reply prompt, as shown above, gives the recipient (and your own support team, if they ever look at the thread) an unambiguous anchor — even though your backend will still resolve the reply to a specific appointment via externalId/tags rather than by parsing the message text.

Read the webhook payload

When the recipient replies, Mobile Text Alerts posts a message-reply event to your configured webhook endpoint.

Relevant fields:

Field
Description

fromNumber

The subscriber's number the reply came from.

message

The full text content of the reply.

externalId

The identifier you set on the original outbound reminder — use this to look up the appointment.

tags

The tags object you set on the original outbound reminder.

replyId / messageId

MTA's internal identifier for this inbound reply.

timestamp

UTC ISO 8601 timestamp of the reply.

You need a handler that resolves a reply to the appointment and updates its status based on the recipient's response.

Example:

Webhook-driven handling vs. Automated Replies

Handle confirmations through the message-reply webhook, as shown above, rather than with Automated Replies. A confirmation may need to update a record in your system. Automated Replies work well for static information that does not depend on application state, such as a keyword that always responds with clinic hours or a cancellation policy. Anything that needs to change an appointment record belongs in a webhook handler. Note that both Automated Replies and webhook-driven replies can be used on the same number.

Change or cancel a reminder message

Appointments can be updated or cancelled after the reminder has already been scheduled. Because the reminder was created as a scheduled send, you can look it up to update or cancel it — no need to cancel and recreate.

View outstanding scheduled sends

Use the GET /scheduled endpoint to list all scheduled messages on your account, or call GET /scheduled/{scheduledMessageId} if you have the scheduledMessageId for an appointment.

Update a reminder when an appointment time has changed

If the appointment time changes, update the existing scheduled message with PATCH /scheduled/{scheduledMessageId} rather than deleting and re-creating it. This preserves the same scheduled message record and avoids a window where no reminder is scheduled at all.

Cancel a reminder message

If the appointment is cancelled outright, cancel the individual scheduled message so the reminder never goes out. Use POST /scheduled/{scheduledMessageId} for the endpoint and request details.

Update your own appointment record's status to cancelled in the same code path, so a webhook reply event arriving after the fact (see below) has a consistent state to check against.

Time between cancellation and delivery messages

Sometimes there is a narrow window where an appointment is cancelled after the reminder has already been handed off for delivery but before your cancellation request reaches Mobile Text Alerts. In this case the recipient gets a reminder for an appointment that no longer exists. This scenario can't be fully eliminated, but you can contain it:

  • Check appointment status before acting on a message-reply. If a reminder fires late for an already-cancelled appointment and the recipient replies "C", your webhook handler should see the appointment is already cancelled and avoid flipping it back to confirmed.

  • Where the workflow allows it, cancel the scheduled reminder as early as possible in your cancellation flow, rather than as a final step, to minimize the race window.

Recurring reminders

For standing repeating appointments you can use the repeat field on the original /send request instead of scheduling each occurrence individually.

repeat takes boolean flags for each day of the week, a type of week or month, and a frequency:

See Repeat scheduled message sends for the full field reference and behavior details.

Learn More

  • Send an SMS Message — this includes the full reference for properties, scheduledDate, and repeat.

  • Receive and Reply to Messages — the general pattern for two-way messaging this guide builds on.

  • Scheduled Messages — full API endpoint reference for listing, updating, and deleting scheduled sends.

  • Webhooks — see this page for event types and payload reference, including message-reply.

Last updated

Was this helpful?