Skip to Content
API keys are issued to organizations with a signed BAA. Request API access →
GuidesSend appointment reminders

Send appointment reminders

This guide builds a nightly job that reads tomorrow’s appointments from your scheduling system and posts a reminder into each patient’s BloomText conversation. Replies land in the same thread your front desk already works from.

You’ll need: an app user with conversations:read and messages:write, and a way to read appointments from your EMR or scheduler.

Map patients to conversations

The BloomText API doesn’t look up patients by name or phone. Your app keeps a mapping from your patient ID to the BloomText conversation ID, created when the patient’s conversation is set up.

schema.sql
create table bloomtext_conversations ( patient_id text primary key, -- your EMR's patient ID conversation_id uuid not null -- BloomText conversation ID );

Build the reminder text

Keep reminders short and free of clinical detail. Times, locations, and a reply instruction are enough.

Template
Reminder: you have an appointment tomorrow at {time} with {clinic}. Reply C to confirm or R to reschedule.

Send one message per appointment

Derive the idempotency key from the appointment ID and date, so rerunning the job never double-sends.

send-reminders.mjs
const API = 'https://api.bloomtext.com/v1' export async function sendReminders(appointments, lookupConversation) { for (const appointment of appointments) { const conversationId = await lookupConversation(appointment.patientId) if (!conversationId) continue // no BloomText conversation for this patient yet const response = await fetch(`${API}/conversations/${conversationId}/messages`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.BLOOMTEXT_API_KEY}`, 'Idempotency-Key': `reminder:${appointment.id}:${appointment.date}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ body: `Reminder: you have an appointment tomorrow at ${appointment.time}. Reply C to confirm or R to reschedule.`, }), }) if (response.status === 429) { await new Promise((r) => setTimeout(r, Number(response.headers.get('Retry-After')) * 1000)) continue // pick it up on the next run; the idempotency key keeps it safe } const message = await response.json() console.log(appointment.id, message.id) await new Promise((r) => setTimeout(r, 1100)) // stay under 60 requests per minute } }

Schedule it

Run the job once a day, in the evening, from cron or your job scheduler.

crontab
0 18 * * * node /srv/reminders/send-reminders.mjs >> /var/log/reminders.log 2>&1

Next

Turn “C” replies into confirmations in your EMR with Handle patient replies.

Last updated on