Audit X Account Status with TwexAPI
Account lists do not stay clean on their own. A creator can be suspended, a partner account can become unavailable, and a whitelist handle can change or lose verification signals. Finding that out after a payout, launch, or partnership goes live is usually too late.
TwexAPI works well as a repeatable audit layer: first call POST /twitter/users/status to batch-check whether accounts exist or are suspended, then call POST /x/account/verify when you also need Blue Verified and official-organization affiliation metadata. The result is not a vague trust score. It is evidence you can send to an approval or review queue.
Audit Goal
Run this audit before a workflow creates money, permission, or brand exposure. The goal is to check whether each X account is still usable, whether it appears suspended or missing, and whether verification metadata matches your business rules. A blue checkmark is useful context, but it is not a replacement for account-status evidence.
Common goals include:
- Suspended or unavailable accounts: Identify suspended or missing accounts before payouts, partnerships, or whitelist approvals.
- Verification changes: Confirm whether an account is still Blue Verified or affiliated with an official organization.
- Review evidence: Store raw responses, audit time, audit reason, and prior status so reviewers can tell whether a risk is new.
Endpoint Choice
Keep two questions separate: "is this account usable?" and "does this account have verification metadata?" The first question uses the status endpoint. The second uses the verification endpoint. Keeping them separate prevents verification badges from being misread as account-risk conclusions.
| Purpose | Endpoint | Body | Good for |
|---|---|---|---|
| Batch account status | POST /twitter/users/status | Username array | Suspended or missing accounts |
| Verification metadata | POST /x/account/verify | User ID or username array | is_blue_verified, is_verified_organization_affiliate, is_verified |
Both endpoints use Bearer Token authentication:
Authorization: Bearer <your_token>
Content-Type: application/jsonAccount status request:
POST https://api.twexapi.io/twitter/users/status
Authorization: Bearer <your_token>
Content-Type: application/json
["elonmusk", "sundarpichai", "unknown_handle"]Verification metadata request:
POST https://api.twexapi.io/x/account/verify
Authorization: Bearer <your_token>
Content-Type: application/json
["elonmusk", "sundarpichai"]Python Example: Batch Audit Loop
The example below is a conservative server-side audit loop. It checks account status, enriches the rows with verification metadata, then returns records that can be written to a database or human review queue. The status response is normalized defensively because it may be returned as an array or mapping.
1import os
2from datetime import datetime, timezone
3
4import requests
5
6API_BASE = "https://api.twexapi.io"
7TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
8
9def post_json(path, body):
10 response = requests.post(
11 API_BASE + path,
12 headers={
13 "Authorization": f"Bearer {TOKEN}",
14 "Content-Type": "application/json",
15 "Accept": "application/json",
16 },
17 json=body,
18 timeout=30,
19 )
20 response.raise_for_status()
21 payload = response.json()
22
23 if isinstance(payload, dict) and payload.get("code", 200) >= 400:
24 raise RuntimeError(payload.get("msg", "TwexAPI returned an error"))
25
26 return payload
27
28def normalize_status_payload(payload, usernames):
29 data = payload.get("data", payload) if isinstance(payload, dict) else payload
30
31 if isinstance(data, dict):
32 return {name.lower(): data.get(name) for name in usernames}
33
34 if isinstance(data, list):
35 return {
36 name.lower(): data[index] if index < len(data) else None
37 for index, name in enumerate(usernames)
38 }
39
40 return {name.lower(): None for name in usernames}
41
42def verification_by_username(payload):
43 rows = payload.get("data", []) if isinstance(payload, dict) else []
44 result = {}
45
46 for row in rows:
47 screen_name = (row.get("screen_name") or "").lower()
48 if screen_name:
49 result[screen_name] = row
50
51 return result
52
53def classify_account(status_value, verify_row):
54 status_text = "" if status_value is None else str(status_value).lower()
55
56 if status_value is None:
57 return "REVIEW_NOT_FOUND"
58
59 if "suspended" in status_text:
60 return "BLOCK_SUSPENDED"
61
62 if any(flag in status_text for flag in ("not_found", "not found", "missing", "unavailable")):
63 return "REVIEW_NOT_FOUND"
64
65 if verify_row.get("is_verified"):
66 return "PASS_STATUS_VERIFIED"
67
68 return "PASS_STANDARD"
69
70def audit_accounts(usernames, audit_reason):
71 status_payload = post_json("/twitter/users/status", usernames)
72 verify_payload = post_json("/x/account/verify", usernames)
73
74 statuses = normalize_status_payload(status_payload, usernames)
75 verifications = verification_by_username(verify_payload)
76 audited_at = datetime.now(timezone.utc).isoformat()
77
78 results = []
79 for username in usernames:
80 key = username.lower()
81 verify_row = verifications.get(key, {})
82 status_value = statuses.get(key)
83
84 results.append({
85 "username": username,
86 "status": status_value,
87 "is_blue_verified": verify_row.get("is_blue_verified"),
88 "is_org_affiliate": verify_row.get("is_verified_organization_affiliate"),
89 "is_verified": verify_row.get("is_verified"),
90 "decision": classify_account(status_value, verify_row),
91 "audit_reason": audit_reason,
92 "audited_at": audited_at,
93 })
94
95 return results
96
97accounts = ["elonmusk", "sundarpichai", "unknown_handle"]
98for row in audit_accounts(accounts, "partner_payout_precheck"):
99 print(row)In production, store TWEXAPI_BEARER_TOKEN in a server-side environment variable, not in source code. Save both the normalized rows and the raw responses; reviewers need raw evidence, while dashboards and rule engines can read normalized fields.
Response Fields
Save fields that let a reviewer reconstruct the decision later. /twitter/users/status is for account availability; /x/account/verify returns verification metadata.
Common fields in the verification response data array include:
| Field | Meaning |
|---|---|
user_id | X user ID |
screen_name | Username |
is_blue_verified | Whether the account is Blue Verified |
is_verified_organization_affiliate | Whether the account is affiliated with an official organization |
is_verified | Whether either Blue Verified or official-organization affiliation applies |
The status endpoint is simpler: if an account is suspended, route it to block or review. If the response is null or cannot be matched to the target, treat it as "missing or needs review" rather than auto-approving it.
Where To Use It
Place the check before actions that create money, permission, or brand risk.
- Pre-payout checks: Confirm creator, KOL, or partner accounts are not suspended or unavailable before payment.
- Whitelist approval: Record account status and verification evidence before granting community, event, or product permissions.
- Partner intake: Snapshot account status before adding agencies, creators, or affiliates to a database.
- Brand monitoring: Recheck executive, brand, and support accounts on a schedule, then alert security or PR on changes.
- Sybil filtering: Feed suspended, missing, and verification-change signals into a broader risk model instead of relying on one field.
Risk Tiers
Translate API responses into business actions, but keep the script out of irreversible decisions. Generate a clear recommendation, then let the workflow apply it.
| Signal | Suggested action |
|---|---|
suspended | Block payout or approval and create a review task |
null or missing | Pause auto-approval and confirm whether the username changed |
| Unverified but status normal | Continue the flow, but do not grant high-trust permissions |
| Verification status changed | Trigger a second check, especially for brand, organization, and executive accounts |
| Repeated API errors | Mark as a system issue and retry or delay the audit; do not treat it as account risk |
Implementation Notes
Make the audit reproducible, explainable, and recoverable. Save the raw status response, raw verification response, username, account ID, audit time, audit reason, list version, and rule version.
For scheduled audits, separate temporary API errors from account risk. Network timeouts should be retried. Suspended, missing, or verification-change results should create human review tasks with evidence. For payouts and partnerships, keep "pass", "block", and "review" as separate outcomes so every anomaly does not become the same generic error.
Summary
Treat account status auditing as an evidence chain rather than a badge check: read the account list, call /twitter/users/status for availability, enrich with /x/account/verify, save raw and normalized data, then route suspicious changes to human review. That keeps payouts, partnerships, community whitelists, and brand monitoring lists from quietly going stale.