Campaigns
Use a campaign to send the same message to many patients, one at a time, from a clinic phone number: flu shot reminders, a new office address, forms everyone needs to fill out. Campaigns are the API version of BloomText’s broadcasts. Each patient gets the message in their own conversation on that phone number, so replies come back to the team like any other patient message.
Campaigns work with an API key or an org admin’s OAuth token. They need the messages.write scope to create, change, and run, and messages.read to check on them. Messages come from whoever created the campaign: the API key’s name, like “Reminder service”, or the admin, with your app recorded in sent_via.
The lifecycle
status | Meaning | You can |
|---|---|---|
draft | Created, not yet sent. | Edit everything, add and remove recipients, start, delete. |
running | Sending, one message every send_interval_seconds. | Add recipients, pause, stop. |
paused | Sending is on hold. | Edit the message, channel, and pace, add and remove recipients, start again to resume, stop. |
completed | Every recipient was sent to. | Archive. |
stopped | Stopped early. Unsent recipients were cancelled. | Archive. It can’t be restarted. |
Send a campaign
Create it
curl -X POST https://api.bloomtext.com/v1/campaigns \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Flu shot reminders, October",
"body": "Flu shots are available at Example Clinic. Reply here to book a time.",
"from": "+15125550100"
}'Every recipient gets the same body, up to 1,600 characters. name is for staff; patients never see it. Like single messages, campaigns are secure unless you set channel to sms.
from, the phone number to send from, defaults to the default number (the API key’s, or the admin’s). send_interval_seconds (0.5 to 30, default 1) sets the pace.
Add recipients
Add up to 10,000 patient IDs per request. To reach patients you’ve loaded from your EHR, import them first and use the IDs from the import results.
curl -X POST https://api.bloomtext.com/v1/campaigns/c4a7e2d1-9b3f-4e6a-8d2c-1f0e9b8a7c65/recipients \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"patient_ids": ["5a1c9e2b-7d44-4f1a-9c3e-2b8d6f0a1e77", "9e0d3f7a-2c1b-4e8d-a5f6-7b3c2d1e0f98"]}'{ "changed": 2, "skipped": [] }Unknown patient IDs come back in skipped with reason: not_found, and patients already on the campaign with already_added. Recipients are always patient IDs; there’s no “every patient” option.
To take patients off while the campaign is a draft or paused, use Remove campaign recipients.
Start it
curl -X POST https://api.bloomtext.com/v1/campaigns/c4a7e2d1-9b3f-4e6a-8d2c-1f0e9b8a7c65/start \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"BloomText sends to one recipient every send_interval_seconds, in the order they were added. A campaign of 400 patients at the default pace takes about seven minutes.
Watch it go
Retrieve the campaign for its counts, or list its recipients for each patient’s status:
{ "recipients": 412, "pending": 148, "sent": 264, "delivered": 251, "failed": 6, "skipped": 0 }Recipient status
status | Meaning |
|---|---|
pending | Waiting its turn. |
sending | Being sent now. |
sent, delivered, opened | On its way, confirmed delivered, or the secure link was opened. |
failed, undelivered | Didn’t reach the patient. error says why, like landline. |
skipped | Couldn’t be sent, like opted_out for an SMS campaign or no_contact_method. |
cancelled | The campaign was stopped before this patient’s turn. |
List only the ones that need attention with ?status=failed. Each sent recipient has a message_id, and the message sits in that patient’s conversation on the campaign’s phone number. Messages a campaign sent carry its campaign_id. To pick up replies, read messages from the campaign’s start with q=from:patient.
Change a campaign
Update a campaign with only the fields you want to change:
- Name, message, channel, phone number, and pace can change while the campaign is a draft or paused. Pause it first to fix a typo mid-send; patients already sent to keep the original.
- Phone number (
from) can change only while it’s a draft. archived: truehides a finished campaign from List campaigns. Archiving isn’t allowed while it’s running.archived: falsebrings it back.
A change the campaign’s status doesn’t allow returns 409 campaign_not_editable.
Pause, stop, and delete
- Pause holds sending after the message in progress. Start it again to carry on where it left off.
- Stop ends the campaign for good; recipients who haven’t been sent to are
cancelled. To send to them later, create a new campaign. - Delete removes a draft. Once a campaign has started, its messages are in patients’ conversations, so it can’t be deleted; archive it instead.
Good to know
- Plain SMS campaigns put the message on patients’ phones and the carrier’s network. Keep clinical detail out of them.
- In SMS campaigns, opted-out patients are skipped and show as
skippedwitherror: opted_out. - Every recipient gets the same text; campaigns don’t fill in names or other details yet. For personalized messages, loop over Send a message to a patient instead.