Automating Patient Follow‑Ups: Building a Post‑Appointment SMS Workflow
Learn how to build a post-appointment SMS workflow using OhMD.
OhMD Team
Texting
Automating Patient Follow‑Ups: Building a Post‑Appointment SMS Workflow
Learn how to build a post-appointment SMS workflow using OhMD.
OhMD Team
TL;DR - Stop chasing no‑shows and post‑visit tasks manually. With OhMD’s Special Delivery API you can trigger a series of scheduled, consent‑aware texts the moment an appointment ends—collect feedback, push care‑plan reminders, and drive revenue cycle touch‑points automatically.
1. What Counts as a “Patient Follow‑Up”?
Goal
Typical Timing
SMS Example
Satisfaction Survey
1 hour after visit
“How was your visit with Dr. Oh? Reply 1‑5.”
Medication Reminder
Same night
“Remember to start amoxicillin tonight. Reply DONE when taken.”
Physical Therapy Video
+24 h
“Ready to stretch? Watch your Day‑1 video → {{link}}”
Invoice Reminder
+7 d
“Your copay is ready. Pay securely → {{pay‑link}}.”
Each is just a timed SMS tied to the same encounter—perfect for automation.
2. Architecture Overview
EHR / Practice Mgmt ──▶ OhMD API ──▶ Carrier ──▶ Patient SMS ▲ │ │ └─◀─ Webhooks (SOLICITED_RESPONSE_RECEIVED, MESSAGE_STATUS_CHANGE) └────── Encounter completed (event)
EHR fires an “appointment complete” event to your service.
Your service calls responseSolicitationStart to create the follow‑up workflow
OhMD sends timed messages; replies post to the same channel.
Webhooks feed responses/results back to the EHR.
3. Prereqs
Patient has SMS consent (see previous consent post).
You know the appointment’s external ID and end-time.
You’ve created any custom calendars (e.g. CLINIC_HOURS).
4. Kick‑Off the Workflow (responseSolicitationStart)
POST /api/responseSolicitationStart{"event":{"eventType":"APPOINTMENT","timelineType":"REQUEST",// follow‑ups begin after event"eventDate":"2025-06-27T15:00:00-04:00","identifier":{"id":"APPT_47832","authority":"EXTERNAL"},"owner":{"identifier":{"id":"0188bf4c-bd7d-…"}}},"workflow":{"name":"POST_VISIT_FOLLOW_UP","steps":[{"offset":{"hours":1},"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}},"device":{"phone":{"number":"+16464624000"}},"destinationCode":"SMS"}],"body":{"actualBody":"How was today’s visit? Reply 1‑5."},"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}},{"offset":{"hours":24},// 24 h after event"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}}}],"body":{"actualBody":"Watch your rehab video → {{link}}"},"trackableLinks":[{"url":"https://rehab.example.com/v/abc"}],"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}}]}}
POST /api/responseSolicitationStart{"event":{"eventType":"APPOINTMENT","timelineType":"REQUEST",// follow‑ups begin after event"eventDate":"2025-06-27T15:00:00-04:00","identifier":{"id":"APPT_47832","authority":"EXTERNAL"},"owner":{"identifier":{"id":"0188bf4c-bd7d-…"}}},"workflow":{"name":"POST_VISIT_FOLLOW_UP","steps":[{"offset":{"hours":1},"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}},"device":{"phone":{"number":"+16464624000"}},"destinationCode":"SMS"}],"body":{"actualBody":"How was today’s visit? Reply 1‑5."},"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}},{"offset":{"hours":24},// 24 h after event"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}}}],"body":{"actualBody":"Watch your rehab video → {{link}}"},"trackableLinks":[{"url":"https://rehab.example.com/v/abc"}],"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}}]}}
POST /api/responseSolicitationStart{"event":{"eventType":"APPOINTMENT","timelineType":"REQUEST",// follow‑ups begin after event"eventDate":"2025-06-27T15:00:00-04:00","identifier":{"id":"APPT_47832","authority":"EXTERNAL"},"owner":{"identifier":{"id":"0188bf4c-bd7d-…"}}},"workflow":{"name":"POST_VISIT_FOLLOW_UP","steps":[{"offset":{"hours":1},"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}},"device":{"phone":{"number":"+16464624000"}},"destinationCode":"SMS"}],"body":{"actualBody":"How was today’s visit? Reply 1‑5."},"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}},{"offset":{"hours":24},// 24 h after event"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}}}],"body":{"actualBody":"Watch your rehab video → {{link}}"},"trackableLinks":[{"url":"https://rehab.example.com/v/abc"}],"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}}]}}
POST /api/responseSolicitationStart{"event":{"eventType":"APPOINTMENT","timelineType":"REQUEST",// follow‑ups begin after event"eventDate":"2025-06-27T15:00:00-04:00","identifier":{"id":"APPT_47832","authority":"EXTERNAL"},"owner":{"identifier":{"id":"0188bf4c-bd7d-…"}}},"workflow":{"name":"POST_VISIT_FOLLOW_UP","steps":[{"offset":{"hours":1},"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}},"device":{"phone":{"number":"+16464624000"}},"destinationCode":"SMS"}],"body":{"actualBody":"How was today’s visit? Reply 1‑5."},"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}},{"offset":{"hours":24},// 24 h after event"function":"messageDispatch","body":{"recipient":[{"patientIdentity":{"identifier":{"id":"2000"}}}],"body":{"actualBody":"Watch your rehab video → {{link}}"},"trackableLinks":[{"url":"https://rehab.example.com/v/abc"}],"consentAgreementCode":"SMS","schedule":{"calendarCode":"FEDERAL_TCPA"}}}]}}
Why use responseSolicitationStart? It ties every outbound message and inbound reply to the same workflowId, simplifying audit & analytics.