How to Collect Cerfia X Data with TwexAPI
When you need data from a public X account, keep the workflow concrete: collect the profile snapshot, page through recent posts, and run topic-specific searches only when you need a filtered subset.
This guide uses CerfiaFR as the example screen name. If the account handle changes, replace the screen name before running the requests.
Collection Plan
Use three TwexAPI endpoints depending on the data you need:
| Task | Endpoint | When to use it |
|---|---|---|
| Get public account metadata | GET /twitter/{screen_name}/about | Capture profile fields before collecting posts. |
| Page through the account timeline | POST /twitter/{screen_name}/timeline/page | Collect recent posts with cursor pagination. |
| Search within public X results | POST /twitter/advanced_search/page | Filter by query, such as from:CerfiaFR climate, and paginate search results. |
Store both the raw response and the normalized rows. The raw response gives you an audit trail if your parser changes later.
Get Account Metadata
curl --request GET \
--url https://api.twexapi.io/twitter/CerfiaFR/about \
--header 'Authorization: Bearer <token>'Keep this profile snapshot separate from the post table. It can include account identifiers, display fields, description text, and public counters returned by the API.
Page Through Timeline Posts
POST /twitter/{screen_name}/timeline/page accepts count and next_cursor. Use the first response's next_cursor for the next page while has_next_page is true.
curl --request POST \
--url https://api.twexapi.io/twitter/CerfiaFR/timeline/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"count": 20
}'The response includes the current data page plus pagination fields.
{
"code": 200,
"msg": "success",
"data": [],
"has_next_page": true,
"next_cursor": "DAAHCgAB...",
"requested_count": 20,
"effective_count": 20,
"parsed_count": 20
}Python Collector
This collector retrieves a bounded number of timeline pages and produces review-friendly rows.
1import os
2from typing import Any
3
4import requests
5
6TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
7SCREEN_NAME = "CerfiaFR"
8BASE_URL = "https://api.twexapi.io"
9
10def headers() -> dict[str, str]:
11 return {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
12
13def get_profile(screen_name: str) -> dict[str, Any] | None:
14 response = requests.get(
15 f"{BASE_URL}/twitter/{screen_name}/about",
16 headers=headers(),
17 timeout=30,
18 )
19 response.raise_for_status()
20 return response.json().get("data")
21
22def get_timeline_page(
23 screen_name: str,
24 *,
25 count: int = 20,
26 next_cursor: str | None = None,
27) -> dict[str, Any]:
28 payload: dict[str, Any] = {"count": count}
29 if next_cursor:
30 payload["next_cursor"] = next_cursor
31
32 response = requests.post(
33 f"{BASE_URL}/twitter/{screen_name}/timeline/page",
34 headers=headers(),
35 json=payload,
36 timeout=30,
37 )
38 response.raise_for_status()
39 return response.json()
40
41def normalize_post(post: dict[str, Any]) -> dict[str, Any]:
42 tweet_id = post.get("tweet_id") or post.get("id")
43 return {
44 "tweet_id": tweet_id,
45 "created_at": post.get("created_at_datetime") or post.get("created_at"),
46 "text": post.get("full_text") or post.get("text") or "",
47 "favorite_count": post.get("favorite_count") or 0,
48 "retweet_count": post.get("retweet_count") or 0,
49 "reply_count": post.get("reply_count") or 0,
50 "quote_count": post.get("quote_count") or 0,
51 "url": f"https://x.com/i/status/{tweet_id}",
52 }
53
54def collect_timeline(screen_name: str, max_pages: int = 3) -> list[dict[str, Any]]:
55 rows: list[dict[str, Any]] = []
56 cursor = None
57
58 for _ in range(max_pages):
59 page = get_timeline_page(screen_name, count=20, next_cursor=cursor)
60 rows.extend(normalize_post(post) for post in page.get("data", []))
61
62 if not page.get("has_next_page"):
63 break
64 cursor = page.get("next_cursor")
65 if not cursor:
66 break
67
68 return rows
69
70if __name__ == "__main__":
71 profile = get_profile(SCREEN_NAME)
72 posts = collect_timeline(SCREEN_NAME, max_pages=2)
73 print(profile.get("screen_name") if profile else SCREEN_NAME, len(posts))Optional Topic Search
Use timeline collection when you want account posts. Use advanced search by page when you need a topic-filtered subset.
curl --request POST \
--url https://api.twexapi.io/twitter/advanced_search/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"searchTerms": ["from:CerfiaFR climate"],
"sortBy": "Latest"
}'Save the query with each collected row. Without that, it is hard to explain later why a post appeared in a dataset.
Data Hygiene
- Record
screen_name, collection time, endpoint, query, and cursor for every run. - Deduplicate by
tweet_id. - Store raw JSON before normalizing fields.
- Do not treat engagement counts as proof of accuracy or importance.
- Review media, quoted posts, and replies before using the data in reports.
Wrap-up
For a public account such as CerfiaFR, the practical flow is: capture the profile, page through the timeline, optionally run topic-specific searches, and normalize the results into reviewable rows.
That gives you useful account data without adding unsupported claims or noisy analysis.