blog
How to schedule a text message on iPhone, Android, and in apps
Schedule a text message on iPhone or Android, then build and test reliable scheduled SMS for reminders, alerts, and customer journeys.
The considerate text is often the one you remember five minutes after the considerate time to send it. A birthday message at breakfast, an appointment reminder the day before, or a note for someone in another time zone can all benefit from a little clockwork.
For a personal message, use the scheduler built into Apple Messages or Google Messages. For an application, store the intended send time in your own system and let a background worker send the SMS when it becomes due. Those are different jobs, so this guide covers both.
The quick answer
| Where you are sending | How to schedule it | Important detail |
|---|---|---|
| iPhone | Open a conversation, tap +, choose Send Later, select a time, write the message, and tap Send. | Apple documents Send Later as an iMessage feature and allows scheduling up to 14 days ahead. |
| Android with Google Messages | Write the message, touch and hold Send, then choose a suggested time or pick a date and time. | On Android 7.0 and later, an offline phone sends the message when it reconnects. |
| Your application or backend | Save a UTC send time, claim the job once when it is due, call the SMS provider, and record the result. | Treat time zones, consent, cancellation, retries, and duplicate protection as part of the feature. |
If the button names on your phone differ, check which messaging app is set as the default. Manufacturer apps can use a different menu even when the phone itself runs Android.
How to schedule a text message on iPhone
Apple's current Messages app includes Send Later. To use it:
- Open Messages and choose a conversation.
- Tap the + button beside the text field.
- Tap Send Later.
- Tap the proposed time and choose the date and time you want.
- Write the message and tap Send.
The scheduled message stays in the conversation with a dashed outline until it is sent. Tap Edit beside its scheduled time to change the time or send it immediately. Touch and hold the message if you need to edit or delete it before delivery.
There are two boundaries worth knowing. First, Apple documents Send Later as an iMessage feature, although the recipient can use any device. Second, Apple currently limits the schedule to 14 days ahead. You need an internet connection to edit, reschedule, or delete the pending message, but Apple says the message can still be delivered if your own devices are offline at send time.
If Send Later is missing, check that the conversation uses iMessage and that the iPhone software is current. A reminder is still a useful fallback when you want to review the wording yourself just before it leaves.
How to schedule a text message in Google Messages
Google Messages supports scheduled sending on phones running Android 7.0 or later:
- Open Google Messages and choose a conversation.
- Type the message.
- Touch and hold the Send button instead of tapping it.
- Choose one of the suggested times, or select your own date and time.
- Tap Send to place the message in the schedule.
A scheduled-message notice appears in the conversation. Tap the schedule icon beside that message to update it, send it now, or delete it.
Google notes that the phone needs Wi-Fi or mobile data at the scheduled time. If it is offline, Google Messages sends the text when the device reconnects. That is fine for a friendly reminder; it is not a dependable clock for a time-critical application alert. Application sends need server-side scheduling and monitoring.
Schedule SMS from an application
A business reminder has more moving parts than a phone shortcut. The useful unit is not merely "run this code at 9:00." It is a small, observable job with a recipient, message, time zone, send time, state, and history.
A dependable flow looks like this:
- Ask for the recipient's permission and collect their preferred time zone where it matters.
- Convert the chosen local time to a UTC timestamp and keep the original time-zone name for future edits.
- Store the message as
pending, with a stable job ID. - Let a worker atomically claim the job once it is due.
- Send from the intended phone number and save the provider's message ID.
- Mark the job
sent, or record a failure that can be inspected and retried safely. - Keep cancellation available until the worker claims the job.
That atomic claim is the quiet hero. Without it, two workers can wake up together and send the same reminder twice. A customer waiting for one dentist appointment does not need two tiny heart attacks.
MailSlurp provides real phone numbers for SMS workflows and a typed send SMS API. Your scheduler decides when a job is due; the current sendSmsFromPhoneNumber call sends it when the worker runs.
Here is the core of a TypeScript worker. claimDue should be an atomic database operation that returns a job only when it is pending and its time has arrived:
import MailSlurp from 'mailslurp-client'
type ScheduledText = {
id: string
phoneNumberId: string
to: string
body: string
}
type ScheduledTextStore = {
claimDue(id: string): Promise<ScheduledText | undefined>
markSent(id: string, sentSmsId: string): Promise<void>
markFailed(id: string, reason: string): Promise<void>
}
const apiKey = process.env.MAILSLURP_API_KEY
if (!apiKey) throw new Error('Set MAILSLURP_API_KEY')
const mailslurp = new MailSlurp({ apiKey })
export async function deliverScheduledText(
id: string,
store: ScheduledTextStore,
) {
const job = await store.claimDue(id)
if (!job) return
try {
const sent = await mailslurp.phoneController.sendSmsFromPhoneNumber({
phoneNumberId: job.phoneNumberId,
smsSendOptions: {
to: job.to,
body: job.body,
},
})
await store.markSent(job.id, sent.id)
} catch (error) {
const reason = error instanceof Error ? error.message : 'Unknown send error'
await store.markFailed(job.id, reason)
throw error
}
}
Do not put a MailSlurp API key in a browser bundle or mobile application. Keep it in a trusted service or test environment. Also decide how to handle an uncertain response: if the network fails after a send is accepted, a blind retry may duplicate the message. Record attempts and reconcile the sent-message result before retrying.
Test the schedule, not just the send call
A unit test can prove that a timestamp is parsed. It cannot prove that the job runner woke up, used the intended recipient, or delivered the message a person was expecting. Test the path with a real receiving number.
For a reminder scheduled in staging:
- Provision a MailSlurp phone number for the test.
- Record the test start and schedule the application message a short time ahead.
- Wait for the inbound SMS with
waitForLatestSmsinstead of adding a fixed sleep. - Assert the body, sender, recipient, and a reasonable arrival window.
- Exercise the customer action, such as using an OTP or opening the related appointment.
- Test cancellation and confirm that no message arrives.
- Run a duplicate-worker test and confirm that exactly one message is sent.
The wait API can narrow the search to messages received after the test began:
export async function waitForScheduledText(phoneNumberId: string) {
const testStartedAt = new Date()
// Trigger the real application flow and schedule its SMS for this number.
const sms = await mailslurp.waitController.waitForLatestSms({
waitForSingleSmsOptions: {
phoneNumberId,
timeout: 120_000,
unreadOnly: true,
since: testStartedAt,
},
})
if (!sms.body.includes('Your appointment is tomorrow')) {
throw new Error(`Unexpected scheduled SMS: ${sms.body}`)
}
}
Use a fresh number or a unique phrase when parallel tests could see one another's messages. Keep the timeout long enough for the real scheduler and provider path, but assert an arrival range rather than one magical millisecond. Clocks, queues, and carrier delivery all have edges.
Common scheduling failures
- The message arrives an hour early or late. Store the UTC instant and the named time zone. Test daylight-saving transitions rather than assuming every day has 24 tidy hours.
- A canceled message still sends. Make cancellation and worker claiming a single consistent state transition. The worker should recheck the state when it claims the job.
- The recipient gets duplicates. Give every scheduled message a stable ID, atomically claim it, and retain the provider result before retrying.
- The phone sends only after reconnecting. That is expected for Google Messages when the device is offline. Use a server-side scheduler for application alerts that must not depend on one handset.
- The iPhone option is missing. Send Later is an iMessage feature. Confirm that iMessage is active and that the conversation and software version support it.
- The SMS arrives but the journey fails. Check the actual link, code, appointment time, or reply action. Arrival is the middle of the story, not the ending.
A schedule should feel uneventful
The nicest scheduled message is almost boring: it arrives once, at a sensible time, with the right words, and gives the recipient a clear next step. Use the phone's built-in control for personal messages. For an application, keep the clock and retry logic on the server, send through a real phone number, and test the same path your customer will experience.
Continue with the MailSlurp SMS API guide, inspect the exact sendSmsFromPhoneNumber endpoint, or build an SMS OTP verification test.