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

MethodEndpointDescription
POST/chat/v1/conversationsCreate a team chat or channel
GET/chat/v1/conversationsGet team chats and channels
POST/chat/v1/conversations/{conversationId}/messageSend 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 only

This endpoint requires an owner-level API key or the chat.write OAuth scope.

Request Body

FieldTypeRequiredDescription
titlestringYesConversation title shown in the chat clients. Must be non-empty.
typestringYesteam (members can send) or channel (only admins post)
assignedUserIdsinteger[]ConditionalIndividual user IDs assigned as members. At least one of assignedUserIds or assignedSmartGroupIds is required.
assignedSmartGroupIdsinteger[]ConditionalSmart group (dynamic cohort) IDs assigned to the conversation. At least one of assignedUserIds or assignedSmartGroupIds is required.
adminUserIdsinteger[]NoUser 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.
isLockedbooleanNoCreate the conversation locked (members can't send until an admin unlocks). Defaults to false.
isMembersHiddenbooleanNoHide the member list from members in the chat clients. Defaults to false.
descriptionobject[]NoOrdered 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

FieldTypeDescription
idstringUnique conversation identifier. Use it to send messages and follow-up calls.
titlestringConversation title
typestringteam or channel
assignedUserIdsinteger[]Individual user IDs assigned to the conversation
assignedSmartGroupIdsinteger[]Smart group IDs assigned to the conversation
adminUserIdsinteger[]User IDs with admin privileges (only members are returned)
isLockedbooleanWhether the conversation is locked
isMembersHiddenbooleanWhether the member list is hidden
descriptionobject[]Structured conversation description blocks

Errors

StatusWhen
400title is empty/missing, or neither assignedUserIds nor assignedSmartGroupIds is provided
404Conversation 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

ParameterTypeRequiredDefaultDescription
limitintegerNo10Results per page (1-100)
offsetintegerNo0Pagination 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

FieldTypeDescription
idstringUnique conversation identifier
titlestringConversation display name
typestringteam 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

ParameterTypeRequiredDescription
conversationIdstringYesConversation ID

Request Body

FieldTypeRequiredDescription
senderIdintegerYesCustom publisher ID
textstringYesMessage content (max 1000 chars)
attachmentsarrayNoList of file/image attachments

Attachment Object

FieldTypeRequiredDescription
typestringYesimage or file
fileIdstringYesFile 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.

📘

Use type: "team", not channel

In a channel, only admins can post — so the assigned user could not reply. For a two-way conversation always use type: "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"
}

API Reference