Authentication
Every request carries an API key as a Bearer token:
Authorization: Bearer <API key>All requests must use HTTPS. A request without a valid key returns 401 Unauthorized.
API keys belong to your account, not to a person. An account Owner or IT person creates them in BloomText under Settings → Account → API keys, picks their scopes, and chooses which organizations each one reaches. See API keys. API access is available to accounts with a signed BAA. Request API access to get started.
What a key reaches
Within its scopes, a key works in every organization it was given, across the whole organization:
- Patients: find them by phone number or MRN, and retrieve, create, update and delete them.
- Patient messages: message a patient, check delivery, and read and search patient messages and conversations.
- Phone numbers and the organization: list the organization’s numbers and read its details.
- Staff and organizations, with the member scopes: list the organizations the key reaches, add, change and remove members, place them on teams, and read member events. See Manage members.
A key never reads staff conversations (direct, group or team chats) and never lists every patient. See What the API can reach.
Scopes
A key’s scopes are chosen by the Owner or IT person who creates it. There is a read and a write scope for patient messages, another pair for patients, and three scopes for staff. No scope includes another. Request only what you need: a call outside the key’s scopes returns 403 with code: insufficient_scope, and every endpoint in the API reference lists the scope it needs.
| Scope | Allows |
|---|---|
messages.read | Patient messages and patient conversations in a time range, with search, a patient message’s delivery status, and the organization’s phone numbers |
messages.write | Message a patient by patient ID or phone number (a new number creates the patient), or many patients at once. The key sends as its API identity. Grants no read access on its own. |
patients.read | Find patients by phone number or MRN, and retrieve them by ID |
patients.write | Create, update and delete patients |
members.read | Organizations the key reaches, members and who manages each, teams, and member events |
members.write | Add, update and remove members |
teams.write | Add a member to a team and take them off |
audit.read | Read the account’s audit events. See Reporting and audit data. |
Some calls also need a feature on: campaigns and patient imports use messages.write and patients.write once BloomText turns them on for your account.
To change a key’s scopes, create a new key with the scopes you need and revoke the old one.
Common scope sets
Reminder service
Finds patients and texts them reminders.
patients.read messages.writeSending keys belong to an identity
Scopes say what a key may do; an API identity says who it does it as. An identity is an automated sender on your account, created under Settings → Account → API keys → API identities, with a name and avatar Owners and IT choose and the teams and phone numbers it may use. It isn’t listed in the Directory or People, isn’t a billable seat, and can’t sign in. Keys belong to an identity, and one identity can have several keys, so rotating a key never changes who messages come from.
| Key | Identity |
|---|---|
With messages.write | Required. The key sends as its identity, from the identity’s numbers. |
Read-only (messages.read, patients.read, members.read, report and audit reads) | Not needed |
Provisioning (members.write, teams.write, patients.write without messages.write) | Not needed |
A key never sends on behalf of a staff member. Until identities are turned on for your account, a sending key’s messages show the key’s name with an API marker.
Limits that narrow a key
Scopes say what a key can do. Limits say where. A sending key’s limits come from its identity once identities are on. A limit never adds an action; it only narrows reach.
| Limit | What it does |
|---|---|
| Organizations | The key reaches every organization on the account, including ones added later, or only the ones picked. A key that reaches several names one with org_id on every call. |
| Phone numbers | The key sends only from the numbers picked, and reads only the messages, conversations and numbers of each number’s team. Patients stay organization-wide. |
Choose the organization
A key that reaches several organizations names one with org_id on every call; a key that reaches one can leave it out. GET /orgs lists the ones it reaches. Without org_id, a call returns 400 with code: org_id_required, and an organization the key can’t reach returns 403 with code: org_not_reachable.
OAuth
OAuth is a second way to authenticate, for two cases:
- Client credentials: your server exchanges a client ID and secret for a short-lived access token for an existing API key, with that key’s scopes and limits. Use it when your security policy prefers rotating tokens over a long-lived key.
- Authorization code with PKCE: a person connects your app to their BloomText account, and your app works in their own conversations under
/me, including staff chats. For now, org admins can connect.
Both are covered in Connect with OAuth. With an authorization-code token, the same scopes apply, plus offline_access for a refresh token. Today, calls under /me and to the staff directory answer an API key with 403 and code: oauth_required.
Keep keys safe
- Store API keys like PHI: in a secrets manager or encrypted at rest, readable only by the people and systems that need them. A key with
messages.readcan read patient messages. - Keep keys out of models. If an AI agent calls the API, your code holds the key and makes the request. Never put a key in a prompt, a tool description, or chat history.
- Give each system its own key with the least it needs. A key that only sends reminders doesn’t need
patients.write. See Build an AI agent. - Set an expiry, and rotate keys when people with access leave. See Rotate or revoke a key.