How to Get XChat Conversations with TwexAPI
Before you export DM history, you need to know which conversations exist. A support system, CRM sync, or compliance archive usually starts with the inbox list: conversation IDs, direct-versus-group type, muted state, and participant user IDs.
TwexAPI's Get Conversations (XChat v3) endpoint returns that XChat conversation list with POST /v3/twitter/conversations.
This endpoint lists conversations. It does not return message history, media files, or message text. Use it to build the conversation inventory, then call POST /v3/twitter/dm-history for the conversations that need full message export.
Endpoint and Request Fields
Use POST /v3/twitter/conversations to list XChat conversations for the authenticated account.
| Field | Type | Required | Notes |
|---|---|---|---|
cookie | string | Yes | X authentication cookie or auth_token. Keep it server-side. |
count | integer or null | No | Page size from 10 to 200. Set it explicitly so jobs behave predictably. |
all | boolean or null | No | When true, follows the inbox cursor and returns every conversation. This can be slow for large inboxes. |
proxy | string or null | No | Optional HTTP proxy for the session. |
Basic Request
curl --request POST \
--url https://api.twexapi.io/v3/twitter/conversations \
--header "Authorization: Bearer $TWEXAPI_BEARER_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"cookie": "auth_token=...; ct0=...; twid=...",
"count": 100,
"all": false
}'The response returns an array of conversation objects in data.
1{
2 "code": 200,
3 "msg": "success",
4 "data": [
5 {
6 "conversation_id": "1928096185664843776:1989842918455291904",
7 "type": "direct",
8 "is_muted": false,
9 "participants": [
10 "1928096185664843776",
11 "1989842918455291904"
12 ]
13 },
14 {
15 "conversation_id": "g1234567890",
16 "type": "group",
17 "is_muted": false,
18 "participants": [
19 "1928096185664843776",
20 "1989842918455291904",
21 "1234567890123456789"
22 ]
23 }
24 ]
25}Store conversation_id as the stable key. For direct conversations, it is commonly shaped like a:b. For group conversations, it can begin with g....
Python Conversation Sync
This script reads the conversation list and stores normalized rows you can use to drive later history exports.
1import os
2from datetime import datetime, timezone
3from typing import Any
4
5import requests
6
7API_URL = "https://api.twexapi.io/v3/twitter/conversations"
8BEARER_TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
9X_COOKIE = os.environ["TWEXAPI_X_COOKIE"]
10PROXY = os.environ.get("TWEXAPI_PROXY")
11
12def fetch_conversations(
13 *,
14 count: int = 100,
15 all_conversations: bool = False,
16) -> list[dict[str, Any]]:
17 if count < 10 or count > 200:
18 raise ValueError("count must be between 10 and 200")
19
20 payload: dict[str, Any] = {
21 "cookie": X_COOKIE,
22 "count": count,
23 "all": all_conversations,
24 }
25 if PROXY:
26 payload["proxy"] = PROXY
27
28 response = requests.post(
29 API_URL,
30 headers={
31 "Authorization": f"Bearer {BEARER_TOKEN}",
32 "Content-Type": "application/json",
33 "Accept": "application/json",
34 },
35 json=payload,
36 timeout=90,
37 )
38 response.raise_for_status()
39 data = response.json()
40
41 if data.get("code") != 200:
42 raise RuntimeError(data.get("msg", "TwexAPI returned an error"))
43
44 return data["data"]
45
46def normalize_conversation(
47 account_key: str,
48 conversation: dict[str, Any],
49) -> dict[str, Any]:
50 participants = conversation.get("participants") or []
51 return {
52 "account_key": account_key,
53 "conversation_id": conversation["conversation_id"],
54 "conversation_type": conversation["type"],
55 "is_muted": conversation["is_muted"],
56 "participants": participants,
57 "participant_count": len(participants),
58 "synced_at": datetime.now(timezone.utc).isoformat(),
59 "raw": conversation,
60 }
61
62def conversations_for_history_export(
63 rows: list[dict[str, Any]],
64) -> list[dict[str, Any]]:
65 return [
66 row
67 for row in rows
68 if not row["is_muted"] and row["conversation_type"] in {"direct", "group"}
69 ]
70
71if __name__ == "__main__":
72 account_key = "support_account"
73 conversations = fetch_conversations(count=100, all_conversations=True)
74 rows = [normalize_conversation(account_key, item) for item in conversations]
75 export_queue = conversations_for_history_export(rows)
76
77 print(f"Synced {len(rows)} conversations")
78 print(f"Queued {len(export_queue)} conversations for history checks")Set TWEXAPI_BEARER_TOKEN and TWEXAPI_X_COOKIE in your server environment before running the script. Do not call this endpoint from browser code, because the request needs the X cookie.
When To Use all=true
Use all=true when you need a full inbox inventory, such as a first-time CRM sync or a scheduled audit. The API follows the inbox cursor internally and returns every conversation it can reach.
For lightweight health checks or UI previews, keep all: false and set a bounded count. Since the response does not expose a manual cursor field, do not invent your own pagination cursor from conversation_id.
Conversation-to-History Workflow
- List conversations: Call
POST /v3/twitter/conversationsand store eachconversation_id. - Classify: Separate
directandgroupconversations, and keep the participant IDs. - Select: Decide which conversations need message export based on account, type, muted state, or internal policy.
- Export history: For selected rows, call
POST /v3/twitter/dm-historyusingconversation_idasrecipient. - Resolve media: When history messages contain attachments, call
POST /v3/twitter/dm-mediafor the exact media item.
This keeps each endpoint in its lane: conversations discover the inbox, history reads messages, and media resolves files.
Fields To Store
| Field | Why it matters |
|---|---|
account_key | Identifies which X account the inbox belongs to. |
conversation_id | Stable key for later history export. |
conversation_type | Distinguishes direct and group workflows. |
is_muted | Useful for prioritization or exclusion rules. |
participants | Participant user IDs for matching CRM or support records. |
participant_count | Simple group/direct sanity check. |
synced_at | Shows when this inbox snapshot was taken. |
| Raw conversation JSON | Lets you reprocess if your schema changes. |
Do not store the full account cookie with conversation rows. Store a credential reference instead.
Common Mistakes
- Expecting this endpoint to return message text. It only returns conversation objects.
- Using
all=truein a latency-sensitive request path for a large inbox. - Treating
participantsas display names; they are user IDs. - Dropping group conversations because they do not look like
a:bdirect conversation IDs. - Creating a fake cursor from
conversation_ideven though the response does not expose a manual cursor.
Wrap-up
Use POST /v3/twitter/conversations to build the XChat inbox inventory: conversation_id, type, is_muted, and participants. Then use those conversation IDs to decide which threads should go through dm-history and, when needed, dm-media.