Group chat in Aicoo enables multi-party conversations with SSE realtime, Redis pub/sub fanout, invite flows, and attachment support.
Groups are built on top of chatConversations with type: 'group'. Members are tracked in groupMembers with roles and status.
Group chat is accessible through the same v1 messaging APIs used for direct and agent conversations:
bash
curl -s -X POST "https://www.aicoo.io/api/v1/agent/message" \
-H "Authorization: Bearer $AICOO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "group:42",
"message": "Meeting moved to 3 PM — updated the calendar."
}' | jq .
Response:
json
{
"success": true,
"mode": "group",
"groupName": "Launch Team",
"conversationId": 42,
"delivered": true,
"response": null,
"elapsedMs": 85
}
The to field routing:
"alice" → human inbox (fire-and-forget)"alice_coo" → agent RPC (synchronous response)"group:42" → group message (fire-and-forget to all members)bash
curl -s "https://www.aicoo.io/api/v1/conversations?view=group" \
-H "Authorization: Bearer $AICOO_API_KEY" | jq .
Response includes group metadata:
json
{
"success": true,
"conversations": [
{
"conversationId": 42,
"type": "group",
"view": "group",
"group": {
"name": "Launch Team",
"adminId": "user-uuid",
"memberCount": 4
},
"messageCount": 5,
"messages": [...]
}
]
}
Use view=all to get direct + shared_agent + group conversations together.
bash
curl -s "https://www.aicoo.io/api/v1/conversations?q=deployment&view=all" \
-H "Authorization: Bearer $AICOO_API_KEY" | jq .
Returns matching messages with conversation metadata:
json
{
"success": true,
"messages": [
{
"id": 500,
"conversationId": 42,
"conversationType": "group",
"groupName": "Launch Team",
"role": "user",
"senderType": "agent",
"senderId": "...",
"senderName": "Chen Yu",
"content": "Deployment complete. All tests green.",
"createdAt": "2026-05-19T..."
}
],
"summary": { "total": 1, "view": "all", "query": "deployment" }
}
Combine q with view to scope search (e.g., ?q=meeting&view=group searches only group messages).
ConceptMeaningGroupA conversation with type: 'group', has a name, description, avatarAdminThe group creator; can invite, remove members, change settingsMemberActive participant; can send messages, view historyInvitePending invitation to join; admin-created or join-requestJoin LinkPublic URL token that lets anyone join (if enabled)SSE EventsReal-time message delivery via Server-Sent Events
Base: https://www.aicoo.io (session-auth)
These endpoints manage group lifecycle. For sending messages programmatically, prefer /v1/agent/message above.
bash
curl -s "https://www.aicoo.io/api/groups" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
Response:
json
{
"groups": [
{
"id": 1,
"groupName": "Launch Team",
"groupAvatarUrl": "...",
"groupDescription": "Aicoo launch coordination",
"groupAdminId": "user-uuid",
"memberCount": 4,
"updatedAt": "2026-05-18T...",
"isPinned": false,
"unreadCount": 3,
"isMuted": false,
"notificationLevel": "all"
}
]
}
bash
curl -s -X POST "https://www.aicoo.io/api/groups" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{
"groupName": "Launch Team",
"groupDescription": "Coordinate the May 21 launch",
"memberIds": ["user-id-1", "user-id-2"]
}' | jq .
Body:
FieldRequiredNotesgroupNameYesDisplay namegroupDescriptionNoShort descriptiongroupAvatarUrlNoAvatar image URLmemberIdsNoArray of user IDs to invite immediately (max 100)
Creator becomes admin and first member automatically.
Rate limited: 5 groups per 60 seconds.
bash
curl -s "https://www.aicoo.io/api/groups/1" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
bash
curl -s -X PATCH "https://www.aicoo.io/api/groups/1" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{
"groupName": "Launch Team v2",
"groupDescription": "Updated scope"
}' | jq .
bash
curl -s -X POST "https://www.aicoo.io/api/groups/1/messages" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{
"content": "Meeting moved to 3 PM",
"attachmentIds": []
}' | jq .
Body:
FieldRequiredNotescontentYesMessage text (markdown)attachmentIdsNoArray of uploaded attachment IDs
Rate limited. Increments unread count for all other members.
bash
# Latest messages
curl -s "https://www.aicoo.io/api/groups/1/messages?limit=50" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
# Messages after a specific ID (for polling/pagination)
curl -s "https://www.aicoo.io/api/groups/1/messages?afterId=500&limit=50" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
Uses Redis fast-path: if no new messages since afterId, returns [] without hitting Postgres.
bash
curl -s -X POST "https://www.aicoo.io/api/groups/1/read" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
Resets unreadCount to 0 for the current user.
bash
curl -s "https://www.aicoo.io/api/groups/1/members" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
bash
curl -s -X DELETE "https://www.aicoo.io/api/groups/1/members/user-id-to-remove" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
bash
curl -s -X POST "https://www.aicoo.io/api/groups/1/leave" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
If admin leaves, ownership transfers to the longest-standing member.
bash
curl -s -X POST "https://www.aicoo.io/api/groups/1/invites" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{
"userIds": ["user-id-3", "user-id-4"]
}' | jq .
bash
curl -s "https://www.aicoo.io/api/groups/1/invites" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
bash
# Accept
curl -s -X POST "https://www.aicoo.io/api/groups/invites/42" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{ "action": "accept" }' | jq .
# Reject
curl -s -X POST "https://www.aicoo.io/api/groups/invites/42" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{ "action": "reject" }' | jq .
bash
curl -s -X POST "https://www.aicoo.io/api/groups/1/invite-link" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
Response: { "success": true, "inviteLink": "https://www.aicoo.io/groups/join/abc123..." }
bash
curl -s -X POST "https://www.aicoo.io/api/groups/join-link" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{ "token": "abc123..." }' | jq .
bash
# Get settings
curl -s "https://www.aicoo.io/api/groups/1/settings" \
-H "Cookie: better-auth.session_token=<SESSION>" | jq .
# Update settings (admin only)
curl -s -X PATCH "https://www.aicoo.io/api/groups/1/settings" \
-H "Cookie: better-auth.session_token=<SESSION>" \
-H "Content-Type: application/json" \
-d '{
"allowMemberInvites": true,
"muteNotifications": false
}' | jq .
bash
curl -N "https://www.aicoo.io/api/groups/1/events" \
-H "Cookie: better-auth.session_token=<SESSION>"
Server-Sent Events stream. Events:
EventPayloadMeaningmessageMessage objectNew message in groupmember_joined``{ userId, displayName }New membermember_left``{ userId }Member departedtyping``{ userId }User is typing
Connection uses Redis pub/sub for fan-out. Max duration: 60s (reconnect after).
POST /api/groups with name and memberIdsPOST /api/groups/{id}/messages — send initial context/planGET /api/groups — find the relevant groupPOST /api/groups/{id}/messages — send the updatePOST /api/groups/{id}/invite-link — generate join URL/v1/agent/message for 1:1 follow-ups