Skip to main content

Messaging Endpoints

The Messaging module manages real-time conversations, chat messages, push notifications, SMS/email delivery, WebSocket connections, private messaging, device registration, and texting providers. It provides the communication layer used across all ChurchApps applications for both live streaming chat and asynchronous notifications.

Base path: /messaging

Conversations​

Base path: /messaging/conversations

MethodPathAuthPermissionDescription
GET/timeline/ids?ids=JWT—Load conversations by comma-separated IDs with first/last messages
GET/messages/:contentType/:contentIdJWT—Load conversations for content with paginated messages (?page=&limit=)
GET/postsJWT—Get post-type conversations for the current user's groups
GET/posts/group/:groupIdJWT—Get post-type conversations for a specific group
GET/current/:churchId/:contentType/:contentIdPublic—Get or create the current conversation for content (auto-decrypts contentId)
GET/:churchId/:contentType/:contentIdPublic—Load conversations by content type and ID
GET/:churchId/:idPublic—Load a single conversation by ID
POST/JWT—Create or update conversations (batch)
POST/startJWT—Start a new conversation with an initial comment message
DELETE/:churchId/:idJWT—Delete a conversation

Person notes access control​

Conversations with contentType: "person" (the Notes tab on a person record) or contentType: "personConfidential" (the Confidential Notes section) are gated on every read and write path, including the otherwise-public routes above, which return 401 for these content types. person requires the MembershipApi People / Edit permission; personConfidential requires People / View Confidential Notes. For scoped API keys, people:write carries both actions (the key's user must still hold the underlying role permission).

Example: Start a Conversation​

POST /messaging/conversations/start
Authorization: Bearer <token>

{
"groupId": "group-123",
"contentType": "group",
"contentId": "group-123",
"title": "Weekly Discussion",
"comment": "Welcome to this week's discussion thread!"
}
{
"id": "conv-456",
"churchId": "church-789",
"contentType": "group",
"contentId": "group-123",
"title": "Weekly Discussion",
"dateCreated": "2026-02-17T10:00:00.000Z",
"visibility": "public",
"allowAnonymousPosts": false,
"groupId": "group-123"
}

Messages​

Base path: /messaging/messages

MethodPathAuthPermissionDescription
GET/conversation/:conversationIdJWT—Load all messages for a conversation
GET/catchup/:churchId/:conversationIdPublic—Load all messages for a conversation (public catchup for live chat)
GET/:churchId/:idPublic—Load a single message by ID
POST/JWT—Save messages (batch). Sends real-time updates and triggers notifications. Updating an existing message requires being its author or holding content.edit; the stored author is never reassignable
POST/sendPublic—Send messages (batch, public). Sends real-time updates via WebSocket and triggers notifications
POST/setCalloutJWT—(legacy) Broadcast a callout message in real time. No active client; live stream chat no longer renders callouts
DELETE/:churchId/:idJWT—Delete a message and broadcast the deletion in real time. See Message moderation

Message moderation​

Deleting a message is allowed for:

  • the message's author;
  • staff with content.edit (anywhere in the church);
  • group leaders, for conversations with a contentType of group or groupAnnouncement whose contentId is a group they lead (leaderGroupIds on the JWT).

Person-note conversations (person / personConfidential) are never leader-moderated — they use the notes permissions (people.edit, people.viewConfidentialNotes) instead.

Leaders get delete only, not edit: rewriting another member's message stays restricted to the author and content.edit staff.

Example: Send a Message​

POST /messaging/messages/send

[
{
"churchId": "church-789",
"conversationId": "conv-456",
"personId": "person-123",
"displayName": "John Smith",
"content": "Hello everyone!",
"messageType": "comment"
}
]
[
{
"id": "msg-001",
"churchId": "church-789",
"conversationId": "conv-456",
"personId": "person-123",
"displayName": "John Smith",
"timeSent": "2026-02-17T10:05:00.000Z",
"content": "Hello everyone!",
"messageType": "comment"
}
]

Private Messages​

Base path: /messaging/privatemessages

MethodPathAuthPermissionDescription
GET/JWT—Load all private messages for the current user (includes last message per conversation, marks all as read)
GET/existing/:personIdJWT—Find an existing private conversation with a specific person
GET/:idJWT—Load a private message by ID (clears notification if addressed to current user)
POST/JWT—Send private messages (batch). Triggers push notification to recipient

Notifications​

Base path: /messaging/notifications

MethodPathAuthPermissionDescription
GET/unreadCountJWT—Get unread notification count for the current user
GET/myJWT—Load all notifications for the current user (marks all as read)
GET/tmpEmailPublic—Trigger daily email notification digest (debug/cron endpoint)
GET/:churchId/person/:personIdJWT—Load notifications for a specific person
GET/:churchId/:idJWT—Load a notification by ID
POST/JWT—Create or update notifications (batch)
POST/createJWT—Create notifications for multiple people. Body: { peopleIds, contentType, contentId, message, link }
POST/markRead/:churchId/:personIdJWT—Mark all notifications as read for a person
POST/sendTestJWT—Send a test push notification. Body: { personId, title }
POST/pingPublic—Create a notification from an external trigger. Body: { personId, churchId, contentType, contentId, message, triggeredByPersonId }
DELETE/:churchId/:idJWT—Delete a notification

Example: Create Notifications​

POST /messaging/notifications/create
Authorization: Bearer <token>

{
"peopleIds": ["person-123", "person-456"],
"contentType": "group",
"contentId": "group-789",
"message": "New event posted in your group",
"link": "/groups/group-789"
}

Notification Preferences​

Base path: /messaging/notificationpreferences

Extends standard CRUD. The base class provides POST / (create or update, no permission required).

MethodPathAuthPermissionDescription
POST/JWT—Create or update notification preferences (from CRUD base class)
GET/myJWT—Load notification preferences for the current user (auto-creates defaults if none exist)

Connections​

Base path: /messaging/connections

Manages WebSocket/real-time connections for chat, group conversations, private messages, and live streaming. See Real-time Architecture for the end-to-end protocol.

MethodPathAuthPermissionDescription
GET/:churchId/:conversationIdPublic—Load all connections for a conversation
POST/Public—Register connections (batch). Triggers an attendance broadcast on the conversation. Body items: { churchId, conversationId, socketId, displayName?, personId? }
POST/setNamePublic—Update the display name for a connection by socket ID. Body: { socketId, name }
DELETE/:churchId/:conversationId/:socketIdPublic—Drop a connection from a conversation. Triggers an attendance broadcast
POST/tmpSendAlertPublic—Send a notification alert to a person's connections. Body: { churchId, personId }

Devices​

Base path: /messaging/devices

Manages device registration for push notifications and content pairing (e.g., Lessons app on TV displays).

MethodPathAuthPermissionDescription
POST/enrollJWT—Enroll or update a device (mobile push registration). Matches by FCM token or device ID
POST/enrollAnonPublic—Enroll an anonymous device and generate a 4-character pairing code
POST/Public—Save devices (batch)
GET/pair/:pairingCodeJWT—Pair a device using its pairing code. Optional ?contentType=&contentId= to assign content
GET/status/:deviceIdPublic—Check pairing status of a device
GET/:churchIdJWT—Load all devices for a church
GET/:churchId/person/:personIdJWT—Load all devices for a person
GET/:churchId/:idJWT—Load a device by ID
DELETE/:churchId/:idJWT—Delete a device

Example: Enroll a Device​

POST /messaging/devices/enroll
Authorization: Bearer <token>

{
"fcmToken": "firebase-token-abc123",
"appName": "B1Mobile",
"label": "John's iPhone",
"deviceInfo": "iOS 17, iPhone 15"
}
{
"id": "device-001",
"churchId": "church-789",
"fcmToken": "firebase-token-abc123",
"appName": "B1Mobile",
"label": "John's iPhone",
"registrationDate": "2026-02-17T10:00:00.000Z",
"lastActiveDate": "2026-02-17T10:00:00.000Z"
}

Device Contents​

Base path: /messaging/devicecontents

Manages content assignments for paired devices (e.g., which lesson is displayed on a TV).

MethodPathAuthPermissionDescription
GET/deviceId/:deviceIdJWT—Load content assignments for a device
POST/JWT—Save device content assignments (batch)
DELETE/:idJWT—Delete a device content assignment

Texting​

Base path: /messaging/texting

Manages SMS texting providers, group text messaging, and delivery tracking.

MethodPathAuthPermissionDescription
GET/providersJWT—Load texting providers for the church (credentials are masked)
GET/preview/:groupIdJWT—Preview recipients for a group text (eligible, opted-out, no-phone counts)
GET/sentJWT—Load all sent text message records for the church
GET/sent/:id/detailsJWT—Load a sent text with per-recipient delivery logs
POST/providersJWT—Save texting providers (batch). Encrypts API credentials
POST/sendJWT—Send an SMS to all eligible members of a group. Body: { groupId, message }
POST/sendPersonJWT—Send an SMS to a single person. Body: { personId, phoneNumber, message }
DELETE/providers/:idJWT—Delete a texting provider

Example: Send Group Text​

POST /messaging/texting/send
Authorization: Bearer <token>

{
"groupId": "group-123",
"message": "Reminder: Service starts at 10 AM this Sunday!"
}
{
"totalMembers": 50,
"recipientCount": 42,
"successCount": 40,
"failCount": 2,
"optedOutCount": 5,
"noPhoneCount": 3
}

Email Templates​

Base path: /messaging/emailTemplates

Manages reusable email templates and sending templated emails to groups.

MethodPathAuthPermissionDescription
GET/JWT—Load all email templates for the church
GET/:idJWT—Load a single email template by ID
GET/preview/:groupIdJWT—Preview email delivery for a group (eligible recipient count, members with no email)
POST/JWT—Create or update email templates (batch)
POST/sendJWT—Send a templated email to all members of a group. Body: { groupId, subject, htmlContent }
DELETE/:idJWT—Delete an email template

Example: Send Email to Group​

POST /messaging/emailTemplates/send
Authorization: Bearer <token>

{
"groupId": "group-123",
"subject": "This Week's Update - {{churchName}}",
"htmlContent": "<p>Hello {{firstName}},</p><p>Here's what's happening this week...</p>"
}
{
"totalMembers": 50,
"recipientCount": 45,
"successCount": 44,
"failCount": 1,
"noEmailCount": 5
}

Supported merge fields: {{firstName}}, {{lastName}}, {{displayName}}, {{email}}, {{churchName}}

Blocked IPs​

Base path: /messaging/blockedips

(legacy) IP-blocking for live streaming chat. The B1App client no longer calls POST / — IP blocking was removed in the unified-delivery migration. The /clear route is still invoked server-to-server by StreamingServiceController when streaming services are saved.

MethodPathAuthPermissionDescription
POST/JWT—(legacy) Save blocked IPs (batch). No active client
POST/clearJWT—Clear all blocked IPs for specific services. Body: [{ serviceId, churchId }]

Delivery Logs​

Base path: /messaging/deliverylogs

Tracks delivery status for sent messages (SMS, push notifications, email).

MethodPathAuthPermissionDescription
GET/content/:contentType/:contentIdJWT—Load delivery logs by content type and ID
GET/person/:personIdJWT—Load delivery logs for a person. Optional ?startDate=&endDate= filters
GET/recentJWT—Load recent delivery logs for the church. Optional ?limit= (default 100)
GET/:idJWT—Load a delivery log by ID