Manage members
An account API key can keep BloomText’s staff in step with your HR or identity system: add a new hire to the right organizations and teams, change their role, and remove them when they leave. Your account is the subscription your organizations share, and the key reaches all of them or the ones picked when it was made.
Get an account key
BloomText turns accounts on per account, on request; in an account without them, these endpoints return 403 with code: accounts_not_enabled. An Owner or IT person creates the key under Settings → Account → API keys, with the scopes it needs:
members.readto list organizations, members, teams, and member events.members.writeto add, change, and remove members.teams.writeto put members on teams and take them off.
See API keys for expiry, rotation, and storage.
Find the organization
List the organizations the key reaches. Pass one’s id as org_id on the other calls. A key that reaches only one organization can leave org_id out; a key that reaches several gets 400 org_id_required without it.
curl https://api.bloomtext.com/v1/orgs \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY"{
"data": [
{ "id": "6db1e3f5-9b7f-4f2b-8be1-0f1e1d7d7d8c", "name": "Northside Clinic", "is_default": true },
{ "id": "0c5a7e2d-3f41-4b8e-9d26-5a1c8e7f9b30", "name": "Eastside Clinic", "is_default": false }
],
"pagination": { "next_cursor": null, "has_more": false }
}Add a member
Add a person by email. A new email creates their BloomText user, owned by your account. They get an invite email only with send_invite_email: true; leave it false when they sign in another way or you’ll invite them later.
curl -X POST "https://api.bloomtext.com/v1/members?org_id=$ORG_ID" \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"email": "jordan.lee@clinic.example",
"first_name": "Jordan",
"last_name": "Lee",
"role": "user",
"title": "Front desk",
"send_invite_email": false
}'{
"id": "9f2c4b1a-7d3e-4a5b-8c6d-1e2f3a4b5c6d",
"org_id": "6db1e3f5-9b7f-4f2b-8be1-0f1e1d7d7d8c",
"email": "jordan.lee@clinic.example",
"first_name": "Jordan",
"last_name": "Lee",
"role": "user",
"account_role": null,
"managed_by": "api",
"managed_by_name": "HR sync"
}The member’s id is their BloomText user ID, the same in every organization. To add them to a second organization, repeat the call with that organization’s org_id.
Put them on a team
List the organization’s teams with GET /teams, then add the member by member_id:
curl -X POST "https://api.bloomtext.com/v1/teams/$TEAM_ID/members" \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "member_id": "9f2c4b1a-7d3e-4a5b-8c6d-1e2f3a4b5c6d" }'The member must already be in the team’s organization. It returns 201 with the team, also when they were already on it. Team calls take no org_id: the team names its organization.
Who manages a membership
Each membership has one manager, in managed_by:
managed_by | Who changes it | In BloomText it shows |
|---|---|---|
api | Only API keys. managed_by_name is the key that added it. | 🔒 Managed by API: HR sync, with no Manage or Remove |
admin | People in BloomText. The API answers 409 managed_by_admin. | A normal member row |
account | An Owner or IT person’s membership, in every organization, set on the Account page. The API answers 409 managed_by_account. | 🔒 Set on the Account page |
okta | The account’s Okta rules, through Directory Sync. The API answers 409 managed_by_identity_provider. | 🔒 Managed by Okta |
account_role is owner or it for Owners and IT, and null for everyone else. Account roles are set only in BloomText: no API call, and no Okta rule, makes someone an Owner or gives them the IT role.
admin in the API is what BloomText’s People list calls Manual. Everyone who joined before your sync started is admin, so a sync’s first run should read the members first and leave those rows to people in BloomText; the API manages only the members it adds.
The same rule covers teams: DELETE /teams/{teamId}/members/{memberId} takes off only people the API put on the team.
With Okta Directory Sync
When your account connects Okta, its rules decide which organizations, role and teams each person in Okta gets, and those memberships show managed_by: "okta". See SSO and Directory Sync. For the API that means:
- The API can’t change or remove a membership or team placement Okta manages. It answers
409 managed_by_identity_provider; change the person in Okta or in the account’s rules. - When an Owner or IT person saves a rule, Okta takes over the matching memberships that people in BloomText or an API key made. Their
managed_bybecomesokta, and from then on your sync gets409for them. - Deactivating, suspending or deleting someone in Okta removes every membership they have on the account, including the ones an API key made.
- The account’s Allow Admins to invite people outside Okta switch limits organization Admins in BloomText. It doesn’t limit API keys.
Pick one source of truth per person. Use Directory Sync when Okta is where your staff live; use the API for people Okta doesn’t cover, such as contractors, or when your HR system is the source.
Run a sync
A sync that keeps BloomText in step with an HR system usually runs on a schedule, once per organization:
- Read the organization’s members with
GET /members?org_id=…, followingnext_cursorto the end. Match them to your records by email. - Leave alone everyone whose
managed_byisn’tapi: people in BloomText, the Account page or Okta manage them. - Add the people who are missing with
POST /members. Derive theIdempotency-Keyfrom something stable, such as the employee ID and the organization, so a retried run never adds anyone twice. - Change role and title with
PATCH /members/{memberId}. For a line-of-business lead who should run their organization, setroletoadminin that organization. - Remove leavers with
DELETE /members/{memberId}?confirm_delete_user=true. - Put people on their teams with
POST /teams/{teamId}/members; list the teams withGET /teams. - Check the result with
GET /member-events.
Every call counts toward the organization’s limit of 300 requests a minute; see Rate limits.
Change a member
PATCH /members/{memberId} changes the role (admin or user) or title of a membership the API manages.
curl -X PATCH "https://api.bloomtext.com/v1/members/$MEMBER_ID?org_id=$ORG_ID" \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "role": "admin" }'Remove a member
DELETE /members/{memberId} removes a membership the API manages, and answers 204.
When this is the person’s only organization and your account owns their user, removing them deletes their BloomText user, and they can no longer sign in. The API asks you to confirm that. Without confirm_delete_user=true the call changes nothing and answers:
{
"type": "https://www.bloomtext.com/developers/api/errors/#confirmation_required",
"title": "Conflict",
"status": 409,
"code": "confirmation_required",
"reason": "would_delete_user",
"detail": "This is the person's only organization, so removing them deletes their BloomText user and they can't sign in. Repeat the call with confirm_delete_user=true to do that.",
"request_id": "0b6c2d1e-5f4a-4c3b-9a8d-7e6f5a4b3c2d",
"field_errors": []
}Repeat it with the confirmation to remove and delete them:
curl -X DELETE "https://api.bloomtext.com/v1/members/$MEMBER_ID?org_id=$ORG_ID&confirm_delete_user=true" \
-H "Authorization: Bearer $BLOOMTEXT_API_KEY"Someone who is also in another organization is only removed from this one, with or without the flag. A sync that offboards people can always send confirm_delete_user=true when it means “this person has left”.
See what changed
GET /member-events lists who was added, approved, or removed in an organization, newest first, and who did it. A change an API key made shows actor_name as API key: HR sync, and a change Okta made shows Okta directory. BloomText’s member history export names them the same way, and Owners and IT see the API’s changes in the account’s Audit log as API key: HR sync.
Errors
| Code | Status | Meaning |
|---|---|---|
org_id_required | 400 | The key reaches several organizations. Pass org_id. |
org_not_reachable | 403 | The key can’t reach the organization in org_id. |
accounts_not_enabled | 403 | Accounts are off for this account. Contact BloomText to turn them on. |
already_member | 409 | The person is already in that organization. |
patient_account | 409 | The email belongs to a patient’s BloomText account. |
managed_by_admin | 409 | People in BloomText manage this membership or team placement. |
managed_by_account | 409 | This is an Owner or IT person’s membership. |
managed_by_identity_provider | 409 | The account’s Okta rules manage this membership or team placement. Change it in Okta or in the rules. |
confirmation_required | 409 | Removing them deletes their user. Add confirm_delete_user=true. |
See Errors for the problem object and every other code.