Conversations
Create team chats and channels, list them, and send messages — including a full two-way flow where a custom publisher and a user chat back and forth.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /chat/v1/conversations | Create a team chat or channel |
| GET | /chat/v1/conversations | Get team chats and channels |
| POST | /chat/v1/conversations/{conversationId}/message | Send a message to a conversation |
Create Conversation
Create a team chat or channel and assign members. At least one of assignedUserIds or assignedSmartGroupIds is required.
Use type: "team" for a collaborative chat where all members can send messages, or type: "channel" for a broadcast group where only admins post.
Owner-level onlyThis endpoint requires an owner-level API key or the
chat.writeOAuth scope.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Conversation title shown in the chat clients. Must be non-empty. |
| type | string | Yes | team (members can send) or channel (only admins post) |
| assignedUserIds | integer[] | Conditional | Individual user IDs assigned as members. At least one of assignedUserIds or assignedSmartGroupIds is required. |
| assignedSmartGroupIds | integer[] | Conditional | Smart group (dynamic cohort) IDs assigned to the conversation. At least one of assignedUserIds or assignedSmartGroupIds is required. |
| adminUserIds | integer[] | No | User IDs granted admin privileges (manage members/settings; for channels, the only users who can post). An admin must also be an assigned member — via assignedUserIds or an assigned smart group — to take effect. |
| isLocked | boolean | No | Create the conversation locked (members can't send until an admin unlocks). Defaults to false. |
| isMembersHidden | boolean | No | Hide the member list from members in the chat clients. Defaults to false. |
| description | object[] | No | Ordered list of rich-text blocks shown in the conversation details (not a chat message). |
Example Request
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"title": "Warehouse Team",
"type": "team",
"assignedUserIds": [12345, 67890],
"assignedSmartGroupIds": [99],
"adminUserIds": [12345]
}'Response
{
"requestId": "3f1c9a2e-6b0d-4e5a-9f21-9a1b2c3d4e5f",
"data": {
"conversation": {
"id": "b7e2c1a4-8f3d-4c9a-a1b2-3c4d5e6f7a8b",
"title": "Warehouse Team",
"type": "team",
"assignedUserIds": [12345, 67890],
"assignedSmartGroupIds": [99],
"adminUserIds": [12345],
"isLocked": false,
"isMembersHidden": false,
"description": []
}
}
}Response Fields
| Field | Type | Description |
|---|---|---|
| id | string | Unique conversation identifier. Use it to send messages and follow-up calls. |
| title | string | Conversation title |
| type | string | team or channel |
| assignedUserIds | integer[] | Individual user IDs assigned to the conversation |
| assignedSmartGroupIds | integer[] | Smart group IDs assigned to the conversation |
| adminUserIds | integer[] | User IDs with admin privileges (only members are returned) |
| isLocked | boolean | Whether the conversation is locked |
| isMembersHidden | boolean | Whether the member list is hidden |
| description | object[] | Structured conversation description blocks |
Errors
| Status | When |
|---|---|
| 400 | title is empty/missing, or neither assignedUserIds nor assignedSmartGroupIds is provided |
| 404 | Conversation could not be resolved after creation |
{
"details": null,
"error": "Conversation b7e2c1a4-8f3d-4c9a-a1b2-3c4d5e6f7a8b not found",
"path": "/chat/v1/conversations",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}Get Conversations
Retrieve a paginated list of team chats and channels. Private conversations are excluded.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| limit | integer | No | 10 | Results per page (1-100) |
| offset | integer | No | 0 | Pagination offset |
Example Request
curl --request GET \
--url 'https://api.connecteam.com/chat/v1/conversations?limit=50' \
--header 'X-API-KEY: YOUR_API_KEY'Response
{
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"conversations": [
{
"id": "conv-abc123",
"title": "Engineering Team",
"type": "team"
},
{
"id": "conv-def456",
"title": "Company Announcements",
"type": "channel"
}
]
},
"paging": {
"offset": 2
}
}Response Fields
| Field | Type | Description |
|---|---|---|
| id | string | Unique conversation identifier |
| title | string | Conversation display name |
| type | string | team or channel |
Send Message to Conversation
Send a message to a team chat or channel. The message is posted by a custom publisher.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| conversationId | string | Yes | Conversation ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| senderId | integer | Yes | Custom publisher ID |
| text | string | Yes | Message content (max 1000 chars) |
| attachments | array | No | List of file/image attachments |
Attachment Object
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | image or file |
| fileId | string | Yes | File ID from Attachments API |
Example: Send Text Message
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations/conv-abc123/message \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"senderId": 12345,
"text": "Daily standup reminder: Meeting starts in 15 minutes!"
}'Example: Send Message with Image
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations/conv-abc123/message \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"senderId": 12345,
"text": "Here is the updated floor plan",
"attachments": [
{
"type": "image",
"fileId": "file-abc123"
}
]
}'Example: Send Message with File
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations/conv-abc123/message \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"senderId": 12345,
"text": "Attached is the weekly report",
"attachments": [
{
"type": "file",
"fileId": "file-def456"
}
]
}'Response
{
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {}
}Two-Way Conversation with a Custom Publisher
A common integration pattern is a back-and-forth chat: your system creates a team chat with a single user, a custom publisher posts into it, and the user replies from the Connecteam app. Combined with chat webhooks, this lets your integration hold a two-way conversation — for example, an automated support or onboarding bot.
Usetype: "team", notchannelIn a
channel, only admins can post — so the assigned user could not reply. For a two-way conversation always usetype: "team".
Step 1 — Create a team chat with the user
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"title": "Support with Acme Bot",
"type": "team",
"assignedUserIds": [12345],
"adminUserIds": [12345]
}'Save data.conversation.id from the response — you will use it to post messages.
Step 2 — Post into the conversation as a custom publisher
curl --request POST \
--url https://api.connecteam.com/chat/v1/conversations/b7e2c1a4-8f3d-4c9a-a1b2-3c4d5e6f7a8b/message \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: YOUR_API_KEY' \
--data '{
"senderId": 555,
"text": "Hi! How can I help you today?"
}'senderId is the custom publisher ID (see Custom Publishers). The publisher is the message sender — it is not a member of the group.
Step 3 — Receive the user's reply and continue
The assigned user sees the conversation in their Connecteam chat inbox and replies directly; their replies are posted as themselves.
To receive those replies programmatically, subscribe to the message_created chat webhook and filter by conversationId. When a reply arrives, post the next custom-publisher message via Step 2 — closing the loop and keeping the conversation going.
Integration Example
class ChatIntegration {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.connecteam.com/chat/v1/conversations';
}
async createConversation({ title, type, assignedUserIds = [], assignedSmartGroupIds = [], adminUserIds }) {
const response = await fetch(this.baseUrl, {
method: 'POST',
headers: {
'X-API-KEY': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({ title, type, assignedUserIds, assignedSmartGroupIds, adminUserIds })
});
const data = await response.json();
return data.data.conversation;
}
async getConversations(limit = 100) {
const conversations = [];
let offset = 0;
while (true) {
const response = await fetch(
`${this.baseUrl}?limit=${limit}&offset=${offset}`,
{ headers: { 'X-API-KEY': this.apiKey } }
);
const data = await response.json();
conversations.push(...data.data.conversations);
if (data.data.conversations.length < limit) break;
offset = data.paging.offset;
}
return conversations;
}
async sendMessage(conversationId, senderId, text, attachments = []) {
const response = await fetch(
`${this.baseUrl}/${conversationId}/message`,
{
method: 'POST',
headers: {
'X-API-KEY': this.apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({ senderId, text, attachments })
}
);
return response.json();
}
}
// Two-way flow: create a team chat with one user, then post as a custom publisher.
const chat = new ChatIntegration('YOUR_API_KEY');
const conversation = await chat.createConversation({
title: 'Support with Acme Bot',
type: 'team',
assignedUserIds: [12345],
adminUserIds: [12345]
});
await chat.sendMessage(conversation.id, 555, 'Hi! How can I help you today?');Error Responses
Send Message — 404 Not Found
Conversation not found:
{
"detail": "Conversation not found"
}Sender not found:
{
"detail": "Sender id not found"
}Send Message — 400 Bad Request
Multiple non-image attachments:
{
"detail": "Multiple non-image attachments are not allowed"
}Attachment not uploaded:
{
"detail": "File upload not completed"
}