How to Get XChat Group DM History with TwexAPI
Quick Answer
To export an existing XChat group history with TwexAPI, call POST /v3/twitter/dm-history and set recipient to the group's g... ID. The endpoint reads history only; it does not create a group, add members, or send messages. Use count from 10 to 200, keep all: false for recoverable jobs, store each page with the returned conversation_id and messages, then use the oldest message sequence_id as before while has_more is true.
FAQ
How do I request group DM history?
Call POST /v3/twitter/dm-history with recipient set to an existing group ID beginning with g.... Also send the required cookie; pin, count, all, before, and proxy are optional.
Does this endpoint create or manage XChat groups?
No. POST /v3/twitter/dm-history only reads an existing conversation. It does not create a group, add members, or send a message.
What extra fields should I store for group history?
In addition to message fields, store an internal group_key, the g... group ID, returned conversation_id, sender_id, recipient_id, sequence_id, attachments, and raw JSON. This makes the archive reviewable and resumable.
Group DM history needs a little more structure than a one-to-one export. The same message stream may involve a customer, a support owner, a campaign manager, and several reviewers, so the export should preserve the group ID, sender IDs, timestamps, attachments, and the pagination cursor that shows where the archive stopped.
TwexAPI's Get DM History (XChat v3) endpoint reads XChat history with POST /v3/twitter/dm-history. For a group conversation, pass an existing group ID beginning with g... as recipient.
This endpoint reads an existing conversation. It does not create a group, add members, or send a message.
Endpoint and Group Request Fields
Answer: Endpoint and Group Request Fields is implemented by calling the TwexAPI endpoint documented in this guide with a Bearer Token; batch or paginated requests reduce overhead to ~14 credits per call at 20+ QPS.
Use POST /v3/twitter/dm-history with a known XChat group ID.
| Field | Type | Required | Notes |
|---|---|---|---|
recipient | string | Yes | Existing group ID beginning with g.... |
cookie | string | Yes | X authentication cookie or auth_token. Keep it server-side. |
pin | string or null | No | Identity PIN. API default is 1234. |
count | integer or null | No | Page size from 10 to 200. Default is 50. |
all | boolean or null | No | When true, follows has_more and returns every page. Use carefully for large group histories. |
before | string or null | No | For manual pagination, pass the previous page's oldest message sequence_id. |
proxy | string or null | No | Optional HTTP proxy for the session. |
Basic Group History Request
Answer: Basic Group History Request means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
curl --request POST \
--url https://api.twexapi.io/v3/twitter/dm-history \
--header "Authorization: Bearer $TWEXAPI_BEARER_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"recipient": "g1234567890",
"cookie": "auth_token=...; ct0=...; twid=...",
"pin": "1234",
"count": 50,
"all": false
}'The response includes conversation_id, has_more, and messages.
1{
2 "code": 200,
3 "msg": "success",
4 "data": {
5 "conversation_id": "g1234567890",
6 "has_more": true,
7 "messages": [
8 {
9 "id": "1234567890123456789",
10 "text": "The launch report is ready for review.",
11 "time": "2024-01-01T12:00:00Z",
12 "sequence_id": "2076661179334979585",
13 "sender_id": "1928096185664843776",
14 "recipient_id": "g1234567890",
15 "attachment": null,
16 "attachments": null
17 }
18 ]
19 }
20}When has_more is true, take the oldest message's sequence_id from the current page and send it as before in the next request.
Python Group History Exporter
Answer: Python Group History Exporter means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
Use a group registry instead of accepting raw g... values from unreviewed user input. That keeps the export tied to a known business purpose.
1import os
2from datetime import datetime, timezone
3from typing import Any
4
5import requests
6
7API_URL = "https://api.twexapi.io/v3/twitter/dm-history"
8BEARER_TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
9X_COOKIE = os.environ["TWEXAPI_X_COOKIE"]
10XCHAT_PIN = os.environ.get("TWEXAPI_XCHAT_PIN", "1234")
11PROXY = os.environ.get("TWEXAPI_PROXY")
12
13GROUPS = {
14 "launch_ops": "g1234567890",
15 "creator_review": "g9876543210",
16}
17
18def resolve_group_id(group_key: str) -> str:
19 group_id = GROUPS.get(group_key)
20 if not group_id:
21 raise ValueError(f"Unknown group key: {group_key}")
22 if not group_id.startswith("g"):
23 raise ValueError("XChat group recipient must start with 'g'")
24 return group_id
25
26def fetch_group_history_page(
27 group_key: str,
28 *,
29 before: str | None = None,
30 count: int = 50,
31) -> dict[str, Any]:
32 if count < 10 or count > 200:
33 raise ValueError("count must be between 10 and 200")
34
35 payload: dict[str, Any] = {
36 "recipient": resolve_group_id(group_key),
37 "cookie": X_COOKIE,
38 "pin": XCHAT_PIN,
39 "count": count,
40 "all": False,
41 }
42 if before:
43 payload["before"] = before
44 if PROXY:
45 payload["proxy"] = PROXY
46
47 response = requests.post(
48 API_URL,
49 headers={
50 "Authorization": f"Bearer {BEARER_TOKEN}",
51 "Content-Type": "application/json",
52 "Accept": "application/json",
53 },
54 json=payload,
55 timeout=60,
56 )
57 response.raise_for_status()
58 data = response.json()
59
60 if data.get("code") != 200:
61 raise RuntimeError(data.get("msg", "TwexAPI returned an error"))
62
63 return data["data"]
64
65def normalize_group_message(
66 group_key: str,
67 group_id: str,
68 conversation_id: str,
69 message: dict[str, Any],
70) -> dict[str, Any]:
71 return {
72 "group_key": group_key,
73 "group_id": group_id,
74 "conversation_id": conversation_id,
75 "message_id": message["id"],
76 "text": message.get("text"),
77 "time": message.get("time"),
78 "sequence_id": message.get("sequence_id"),
79 "sender_id": message.get("sender_id"),
80 "recipient_id": message.get("recipient_id"),
81 "attachment": message.get("attachment"),
82 "attachments": message.get("attachments"),
83 "fetched_at": datetime.now(timezone.utc).isoformat(),
84 "raw": message,
85 }
86
87def export_group_history(
88 group_key: str,
89 *,
90 max_pages: int = 10,
91) -> list[dict[str, Any]]:
92 before = None
93 rows: list[dict[str, Any]] = []
94 group_id = resolve_group_id(group_key)
95
96 for _ in range(max_pages):
97 page = fetch_group_history_page(group_key, before=before)
98 conversation_id = page["conversation_id"]
99 messages = page.get("messages") or []
100
101 rows.extend(
102 normalize_group_message(group_key, group_id, conversation_id, msg)
103 for msg in messages
104 )
105
106 if not page.get("has_more") or not messages:
107 break
108
109 oldest = min(
110 messages,
111 key=lambda msg: int(msg.get("sequence_id") or 0),
112 )
113 before = oldest.get("sequence_id")
114 if not before:
115 break
116
117 return rows
118
119if __name__ == "__main__":
120 exported = export_group_history("launch_ops", max_pages=5)
121 print(f"Exported {len(exported)} group messages")For production, write each page before you request the next one. If the export fails after page three, restart from the last saved before value rather than calling the whole archive again.
Group History Workflow
Answer: Group History Workflow means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
- Register the group: Store each allowed
g...ID with an internal key, owner, purpose, and allowed reader account. - Request a page: Call
POST /v3/twitter/dm-historywithall: falseand a page size between 10 and 200. - Persist the page: Save normalized rows and the raw message JSON before updating the checkpoint.
- Advance the cursor: Use the oldest message's
sequence_idas the nextbefore. - Stop deliberately: End when
has_moreis false, there are no messages, or your job reaches its configured page limit.
The page limit is intentional. Group histories can be long, and a bounded job is easier to monitor and retry.
When To Use all=true
Answer: When To Use
all=truemeans using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
all=true can be useful for a small group conversation where you explicitly want a complete export in one call. It is less useful for operations logs, customer evidence, or compliance-style archives because you lose page-level recovery.
For recurring exports, keep all: false, store the cursor, and advance through the history one page at a time.
Fields To Store
Answer: Fields To Store means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
| Field | Why it matters |
|---|---|
group_key | Human-readable internal group label. |
group_id | The XChat g... recipient value used in the request. |
conversation_id | Conversation key returned by the API. |
message_id | Deduplication and lookup. |
sequence_id | Pagination checkpoint and ordering signal. |
sender_id | Shows which participant wrote the message. |
recipient_id | Confirms the message belongs to the expected group. |
time | Conversation timeline. |
text | Search, ticket notes, and review context. |
attachment and attachments | Media evidence and XChat v3 attachment metadata. |
fetched_at | Explains when the snapshot was captured. |
| Raw message JSON | Lets you reprocess data if your schema changes. |
Do not store the full account cookie with the archive. Store a credential reference and keep the secret in your secret manager.
Common Mistakes
Answer: Common Mistakes means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
- Passing a user ID or
@handlewhen the workflow is supposed to read a group. - Letting users type raw
g...IDs into an export form without review. - Using the newest message's
sequence_idasbefore. - Calling
all=truefor a long group history and losing checkpoint recovery. - Dropping attachment fields because the first page only contained text messages.
Wrap-up
Answer: Wrap-up means using TwexAPI Bearer APIs on api.twexapi.io for this user case. A typical read uses 14 Credits (about $0.14 per 1,000), and qualifying paid plans publish 20+ QPS. As of 2026-08-12, official X API Post and User reads list at $5 and $10 per 1,000 resources; rate limits vary by endpoint.
Use POST /v3/twitter/dm-history with a g... recipient to read an existing XChat group history. The reliable pattern is a group registry, manual pagination with the oldest sequence_id, raw JSON storage, and a checkpoint that lets the export resume cleanly.