---
url: https://talkjs.com/docs/REST_API/Conversations
---

# Conversations

Create, update, and manage conversations between users.

Ask a question Copy for LLM [View as Markdown](/docs/REST_API/Conversations.md)

## A single conversation

GET returns a single [Conversation](/docs/Concepts/Conversations/#conversation-data) or an HTTP 404 status if no conversation exists for the given [conversation ID](/docs/Concepts/Conversations/#the-conversation-id).

PUT creates or updates a conversation.

GET PUT /v1/{appId}/conversations/{conversationId}

Example url: `/v1/q3k1pa9d/conversations/order_fc_491731`

## Setting conversation data

You can use a PUT request method to create a conversation or to update (a subset of) conversation [attributes](/docs/Concepts/Conversations/#conversation-data).

To update conversation details, you only need to send the subset of fields you want to update. In that respect, even though you update a conversation with an HTTP `PUT` request method, the
conversation update acts similar to an HTTP `PATCH` request method.

PUT /v1/{appId}/conversations/{conversationId}

Payload Structure Example Payload

```typescript
type ConversationId = string;
type UnixMilliseconds = number;

type RequestBody = {
  participants?: Array<string>,
  subject?: string | null,
  welcomeMessages?: Array<string> | null,
  custom?: Record<string, string | null> | null,
  photoUrl?: string | null
}
```

PUT *merges* data with existing data, if any. For example, you cannot remove participants from a conversation by PUTing a list of participants that excludes some existing participants. If you want to remove participants from a conversation, use the [Participation](/docs/REST_API/Participation/) endpoint.

## Getting created conversations

After you successfully create or update a conversation, you can fetch it back with a GET REST call.

GET /v1/{appId}/conversations/{conversationId}

Response Structure Example Response

```typescript
type UserId = string;
type ConversationId = string;
type UnixMilliseconds = number;

type Conversation = {
  id: ConversationId;
  subject: string | null;
  photoUrl: string | null;
  welcomeMessages: string[] | null;
  custom: Record<string, string>;
  lastMessage: Message | null;
  participants: {
    [id: UserId]: {
      access: 'ReadWrite' | 'Read';
      notify: boolean | 'MentionsOnly';
      isUnread: boolean;
      joinedAt: UnixMilliseconds;
      readUntil: UnixMilliseconds;
    };
  };
  createdAt: UnixMilliseconds;
  everyoneReadUntil: UnixMilliseconds;
  topicId: string | null;
};
```

## Deleting a conversation

Use this endpoint to irrevocably delete data for a certain `conversationId`. All the data and metadata linked to the conversation will be deleted. Here is the list of things that will happen:

1. All messages in the conversation will be deleted.
2. Participants will not be a part of the conversation anymore.
3. All the [conversation metadata](/docs/Concepts/Conversations/#conversation-data) will be erased.
4. Active UIs will display a "Chat not found" screen (which is [localized](/docs/JavaScript_Data_API/Users/#UserSnapshot__locale)).
5. The conversation gets removed from all (former) participants' [Inbox](/docs/Features/Chat_UIs/#inbox) feeds.
NOTE: Users that take part in the conversation *WILL NOT* be deleted.

DELETE /v1/{appId}/conversations/{conversationId}

## Marking a conversation as read or unread

This endpoint is used to mark a conversation as read or unread for a specific user.

Setting the `isUnread` parameter to `true` marks the conversation as unread; setting the `isUnread` parameter
to `false` marks the conversation as read, and omitting the `isUnread` parameter, or setting it to `null` does
not change the read/unread status of the conversation.

Marking a conversation as read will also mark any messages within the conversation as read by that user,
but marking a conversation as unread will not change the read/unread status of any message within the conversation.

PATCH /v1/{appId}/users/{userId}/conversations/{conversationId}

Payload Structure

```typescript
{
  isUnread?: boolean | null,
}
```

## Listing all conversations in the application

This lists all conversations ever created in your TalkJS application. This request is paginated [as explained here](/docs/REST_API/#listing). The response has a `data` field with an array of `Conversation` objects as [described above](#getting-created-conversations).

GET /v1/{appId}/conversations

Response Structure Example Response

```typescript
{
  "data": Array<Conversation>
}
```

### Ordering

**Ordering is available since API version [`2021-02-09`](/docs/REST_API/Versions/#2021-02-09)**

Default order in versions before [`2021-02-09`](/docs/REST_API/Versions/#2021-02-09) is `createdAt DESC` and cannot be changed

By default, conversations are returned in the order of the last activity in them, latest first. You can change the order by using `orderBy` and `orderDirection` query parameters. Conversations can either be sorted on a creation date or on the last activity in that conversation. Ordering conversations by the creation date can be useful when you want stable sorting.

Following values are accepted in `orderBy` query parameter:

- `lastActivity` (default): sort by last activity timestamp
- `createdAt`: sort by date of creation
Following values are accepted in `orderDirection` query parameter:

- `DESC` (default): descending order
- `ASC`: ascending order

### Pagination

> `offsetTs` is available since API version [`2021-02-09`](/docs/REST_API/Versions/#2021-02-09)
Conversations [can be paginated](/docs/REST_API/#listing), as any other listing handle. You can request at most 30 conversations at once.

Using `startingAfter` requires passing in a conversation ID, whereby results will start with the conversation right after the selected one in the current sort order. It works with all currently supported sorting options.

Another option is to use `offsetTs` which accepts a timestamp and offsets the results according to the sort order. This might be more useful when used in conjunction with `lastActivity` sorting since conversations can move to the front of the list as new messages come, and using one of the conversations as a pointer can yield unexpected results.

### Filtering conversations

#### By the last message's timestamp

It is possible to filter conversations by when the last message was sent to the conversation using the `lastMessageBefore` and `lastMessageAfter` filters.

`lastMessageBefore` and `lastMessageAfter` should be Unix timestamps expressed in milliseconds.

For example, the following query string parameters get conversations where the last message was sent between the Unix timestamps `1701700000000` and `1702000000000`:

```text
?lastMessageAfter=1701700000000&lastMessageBefore=1702000000000
```

#### By custom filters

TalkJS also supports filtering by various fields.
The filter interface is precisely the same as the JavaScript SDK's [Conversation Filter](/docs/UI_Components/JavaScript/Classic/Other_Interfaces/#ConversationPredicate).
In order to filter conversations by a custom filter you need to URL-encode the JSON formatted filter.

You can use your favorite programming language to generate the conversation filter in the required JSON structure.

NodeJS example:

```typescript
const filter = { custom: { category: ['==', 'shoes'] } };
const encodedFilter = encodeURIComponent(JSON.stringify(filter));
const res = await fetch(
  `https://api.talkjs.com/v1/${appId}/conversations?filter=${encodedFilter}`
);
const conversations = await res.json();
```

Filters can be combined together with limits and cursors.

#### Examples

```typescript
GET https://api.talkjs.com/v1/{appId}/conversations
GET https://api.talkjs.com/v1/{appId}/conversations?lastMessageBefore=1521522849308&lastMessageAfter=1421522849732
GET https://api.talkjs.com/v1/{appId}/conversations?limit=30&lastMessageAfter=1421522849732
GET https://api.talkjs.com/v1/{appId}/conversations?startingAfter=c_21

// URL encoded version of the filter {"custom":{"category":["==","shoes"]}
GET https://api.talkjs.com/v1/{appId}/conversations?filter=%7B%22custom%22%3A%7B%22category%22%3A%5B%22%3D%3D%22%2C%22shoes%22%5D%7D%7D
```

### Filtering by user

The Users resource lets you list the [conversations a specific user is a part of](/docs/REST_API/Users/#listing-conversations-a-user-is-a-part-of).

## Deprecated Marking a conversation as read

**NOTE:** This endpoint is deprecated. Please use the endpoint described in the [previous section](#marking-a-conversation-as-read-or-unread) instead.

POST /v1/{appId}/conversations/{conversationId}/readBy/{userId}

Example payload

```typescript
{}
```