Authentication
The API accepts two credentials: an organization API key and an org admin’s OAuth access token. Send either one as a Bearer token:
Authorization: Bearer <API key or access token>All requests must use HTTPS. A request without a valid credential returns 401 Unauthorized.
API access is available to organizations with a signed BAA. Request API access to get started.
Choose a credential
| API key (Patient API) | OAuth access token | |
|---|---|---|
| Belongs to | Your organization, not a person | One org admin who connected your app |
| Made for | Servers doing patient communication, like an EHR sync, reminders, or bulk messaging | An admin working with their own conversations from your app |
| Patients | Manage, import, and delete patients; message a patient; read patient messages by time range, patient, or conversation | The same |
| Campaigns | Create, change, run, and delete | The same |
| Staff conversations | Never | Only the admin’s own: read, search, and send in the chats they’re part of |
| Messages come from | The key’s name, like “Reminder service” | The admin, with your app shown to staff |
| Who can get one | An org admin creates it in BloomText | Org admins only, for now |
Neither credential can list the patient directory or read staff conversations other than the connected admin’s own. See What the API can reach.
Scopes
API keys and OAuth use the same scopes. An admin picks them when creating a key and approves them when connecting an app. Request only what you need. A request outside the credential’s scopes returns 403 with code: insufficient_scope, and every endpoint in the API reference lists the scope it needs.
There’s a read and a write scope for messages, and another pair for patients.
| Scope | Approval screen says | Allows |
|---|---|---|
messages.read | Read your conversations and messages | Patient messages and patient conversations in a time range, with search, a patient message’s delivery status, campaigns, and phone numbers. With OAuth, also the person’s own messages and conversations under /me, reactions, participants, users, and the profile |
messages.write | Send messages as you | Message a patient by patient ID or phone number (a new number creates the patient) and create, change, and run campaigns. With OAuth, also send in the admin’s conversations and react. Grants no read access on its own. |
patients.read | See your organization’s patients | Find patients by phone number or MRN, and retrieve them by ID |
patients.write | Add and update your organization’s patients | Create, update, delete, and import patients |
offline_access | Keep access when you’re not signed in | OAuth only: a refresh token, so your app keeps working between the admin’s visits |
With OAuth, sending a message in a conversation marks it as read for the admin, as replying in BloomText does. Nothing else in the API changes read state.
To add a scope to an OAuth connection later, send the admin through the authorize URL again with the full set of scopes you need. For an API key, create a new key with the scopes you need.
Common scope sets
Reminder service (API key)
Finds patients and texts them reminders.
patients.read messages.writeKeep credentials safe
- Store API keys and refresh tokens like PHI: in a secrets manager or encrypted at rest, readable only by the people and systems that need them. Either one can read patient messages.
- Keep credentials out of models. If an AI agent calls the API, your code holds the key or token and makes the request. Never put one in a prompt, a tool description, or chat history.
- Ask for the least you need. A key that only sends reminders doesn’t need
patients.write. See Build an AI agent.