Core concepts
This page explains the objects the API works with and who can reach them. The rest of the docs build on it.
Accounts and organizations
Everything in BloomText belongs to an organization: a practice, a clinic, or one clinic of a larger group. Retrieve the organization to check which one a call acted on.
An account is the subscription your organizations share. Its Owners and IT people manage what spans every organization: API keys, people, settings, Okta single sign-on, Message reports and the Audit log. A group with several clinics, like Riverbend Health with its Northside Clinic and Eastside Clinic, runs each as its own organization on one account, so their patients, phone numbers and conversations stay apart while IT manages them in one place.
API keys and identities
An API key belongs to the account, not to a person. It reaches every organization on the account or only the ones picked, and it never sees an organization it wasn’t given. A key that reaches several names one with org_id on each call. Its scopes say what it can do in them. A key that sends belongs to an API identity, the automated sender it sends as; read-only and provisioning keys need none. See API keys and Authentication.
OAuth adds a second way to authenticate a key, and a way for a person to connect your app to their own conversations.
Members and teams
A member is a staff person in an organization, with the role admin or user. The same person can be a member of several organizations on the account. Account Owners and IT are set only in BloomText, never through the API.
Each membership records who manages it, in managed_by:
managed_by | Who changes it |
|---|---|
admin | The organization’s admins, in BloomText |
api | An API key. See Manage members. |
account | The account’s Owners and IT, on the Account page |
okta | The account’s Okta rules, through Directory Sync. See SSO and Directory Sync. |
A team is a group of members in an organization, like “Front desk”. Teams own phone numbers and the patient conversations on them.
What the API can reach
Access is narrow on purpose:
- Patients are always named. You find a patient record by patient ID, phone number, or MRN. No call lists the patient directory or searches it by name.
- Reads are bounded. Every read of patient messages or conversations is limited by a time range, a patient, or a conversation.
- Staff conversations stay private. An API key never reads direct, group or team chats between staff; those calls return
403withcode: oauth_required. With OAuth, a person who connected your app reaches only the conversations they’re in.
For the other protections and your responsibilities under the BAA, see Security and BAA.
Patients
A patient is someone your organization messages, with a name, mobile number, email, date of birth, and mrn (their ID in your system). Patients belong to the organization. Messaging a new phone number creates the patient. See Patients.
Phone numbers
Each clinic phone number belongs to a team, like “Front desk” at +1 512-555-0100. Texts to patients come from a phone number, and patients’ replies go back to that team’s conversation. Name the number with from when you send, or leave it out to use the key’s default number or the organization’s only number. An API key can send from any of the organization’s numbers, or only from its own with a phone-number limit. See Which number it comes from.
Conversations
A conversation is a thread between people in your organization and, often, a patient or family member. Its type is patient, direct, group, or broadcast. A patient conversation belongs to one phone number, so a patient who has texted two teams has two conversations. Participants can be staff or patients.
An API key reads patient conversations by time range, by patient (patient_id), or one conversation at a time; see Read messages. Other conversations follow the access rules above.
Messages, replies, and reactions
- A message carries either text (
body) or a file (file). It includes itssender(name, and whether they’re staff or a patient), itsconversationandpatient, and itschannel, so you can read a list of messages without extra lookups. - Messages to patients carry a
deliverystatus. See Send messages to patients. - A reply is a message with
reply_to_message_idset. A conversation’s messages include its replies; group them by that field to rebuild a thread. - Reactions are emoji on a message. They have no ID of their own; each is identified by the message, the user, and the emoji.
Messages sent through the API
Messages to patients go by secure link unless the request sets channel to sms. A message goes out from one of the organization’s phone numbers, in that number’s team’s conversation with the patient, and the patient’s reply lands in that team’s inbox like any other.
Your integration sends as an API identity: an automated sender on your account, like “Appointment reminders”, with a name and avatar, limited to the teams and numbers Owners and IT choose. It isn’t a person: it isn’t listed in the Directory or People, isn’t a billable seat, and can’t sign in. API keys belong to an identity, and a key that sends must have one. Staff see the identity in the thread marked as automated, and Owners and IT see it in Message reports and the Audit log (with an Automated filter); patients see its name in secure chat and the office’s number on SMS. Messages carry it as sender with kind: api_identity. Nothing is ever sent on behalf of a staff member.
Until identities are turned on for your account, a message sent with a key shows the key’s name, like “Reminder service”, with an API marker (kind: api_key).
Every message records what sent it, so an organization can always tell what came through the API. Make sure staff know what your integration sends. See Build an AI agent.
Read state
API keys have no read state: unread is always false, and reading through the API never marks anything as read in BloomText.
Finding and following messages
- Read messages:
GET /patient-messagesreturns every patient message in a time range, newest first, one by one or grouped by conversation, with a cursor. Narrow it to a patient or conversation. - Search: add
qfor words and filters, likerefill from:patient is:failed. - Keep up: ask again with
afterset to the newest message you’ve seen.
IDs, timestamps, and requests
| Convention | Detail |
|---|---|
| Base URL | https://api.bloomtext.com/v1 |
| Authentication | Authorization: Bearer <API key>. See Authentication. |
| IDs | Objects have a stable id, usually a UUID. Reactions have none; each is identified by its message, user, and emoji. |
| Timestamps | RFC 3339 strings in UTC, like 2026-09-21T12:00:00Z. |
| Bodies | JSON in and out. Send Content-Type: application/json. |
| Lists | Cursor-paginated. See Pagination. |
| Writes | Every POST takes an Idempotency-Key. See Idempotency. |
| Errors | RFC 9457 problem details. See Errors. |