x-developer 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/package.json +33 -0
- package/skills/x-twitter-scraper/SKILL.md +421 -0
- package/skills/x-twitter-scraper/metadata.json +14 -0
- package/skills/x-twitter-scraper/references/api-endpoints.md +1607 -0
- package/skills/x-twitter-scraper/references/draws.md +57 -0
- package/skills/x-twitter-scraper/references/extractions.md +229 -0
- package/skills/x-twitter-scraper/references/mcp-setup.md +207 -0
- package/skills/x-twitter-scraper/references/mcp-tools.md +151 -0
- package/skills/x-twitter-scraper/references/pricing.md +132 -0
- package/skills/x-twitter-scraper/references/python-examples.md +152 -0
- package/skills/x-twitter-scraper/references/types.md +1163 -0
- package/skills/x-twitter-scraper/references/webhooks.md +198 -0
- package/skills/x-twitter-scraper/references/workflows.md +194 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Xquik Pricing
|
|
2
|
+
|
|
3
|
+
Xquik is the most affordable X data API available. All metered operations deduct credits from a single shared pool.
|
|
4
|
+
|
|
5
|
+
## Subscription
|
|
6
|
+
|
|
7
|
+
| | |
|
|
8
|
+
|---|---|
|
|
9
|
+
| **Base plan** | $20/month |
|
|
10
|
+
| **Included monitors** | 1 |
|
|
11
|
+
| **Additional monitors** | $5/month each |
|
|
12
|
+
| **Credit value** | 1 credit = $0.00015 |
|
|
13
|
+
|
|
14
|
+
## Per-Operation Costs
|
|
15
|
+
|
|
16
|
+
### Read operations — 1 credit ($0.00015)
|
|
17
|
+
|
|
18
|
+
| Operation | Unit |
|
|
19
|
+
|-----------|------|
|
|
20
|
+
| Get tweet | per call |
|
|
21
|
+
| Search tweets | per tweet returned |
|
|
22
|
+
| User tweets | per tweet returned |
|
|
23
|
+
| User likes | per result |
|
|
24
|
+
| User media | per result |
|
|
25
|
+
| Tweet favoriters | per result |
|
|
26
|
+
| Followers you know | per result |
|
|
27
|
+
| Bookmarks | per result |
|
|
28
|
+
| Bookmark folders | per call |
|
|
29
|
+
| Notifications | per result |
|
|
30
|
+
| Timeline | per result |
|
|
31
|
+
| DM history | per result |
|
|
32
|
+
| Download media | per media item |
|
|
33
|
+
| Get user | per call |
|
|
34
|
+
| Verified followers | per result |
|
|
35
|
+
|
|
36
|
+
### Read operations — 3 credits ($0.00045)
|
|
37
|
+
|
|
38
|
+
| Operation | Unit |
|
|
39
|
+
|-----------|------|
|
|
40
|
+
| Trends | per call |
|
|
41
|
+
|
|
42
|
+
### Read operations — 7 credits ($0.00105)
|
|
43
|
+
|
|
44
|
+
| Operation | Unit |
|
|
45
|
+
|-----------|------|
|
|
46
|
+
| Follow check | per call |
|
|
47
|
+
| Get article | per call |
|
|
48
|
+
|
|
49
|
+
### Write operations — 10 credits ($0.0015)
|
|
50
|
+
|
|
51
|
+
All write actions: create/delete tweet, like, unlike, retweet, follow, unfollow, send DM, update profile/avatar/banner, upload media, community actions.
|
|
52
|
+
|
|
53
|
+
### Extractions & draws
|
|
54
|
+
|
|
55
|
+
Draws: 1 credit per participant. Extraction cost depends on the tool type:
|
|
56
|
+
|
|
57
|
+
| Credits/result | Extraction types |
|
|
58
|
+
|----------------|-----------------|
|
|
59
|
+
| 1 | Tweets, replies, quotes, mentions, posts, likes, media, tweet search, favoriters, retweeters, community members, people search, list members, list followers |
|
|
60
|
+
| 1 | Followers, following, verified followers |
|
|
61
|
+
| 5 | Articles |
|
|
62
|
+
|
|
63
|
+
### Free operations ($0)
|
|
64
|
+
|
|
65
|
+
Monitors, webhooks, integrations, account status, radar (7 sources), extraction/draw history, cost estimates, tweet composition (compose, refine, score), style cache management, drafts, support tickets, API key management, X account management.
|
|
66
|
+
|
|
67
|
+
## Price Comparison vs Official X API
|
|
68
|
+
|
|
69
|
+
| | Xquik | X API Basic | X API Pro |
|
|
70
|
+
|---|---|---|---|
|
|
71
|
+
| **Monthly cost** | **$20** | $100 | $5,000 |
|
|
72
|
+
| **Cost per tweet read** | **$0.00015** | ~$0.01 | ~$0.005 |
|
|
73
|
+
| **Cost per user lookup** | **$0.00015** | ~$0.01 | ~$0.005 |
|
|
74
|
+
| **Write actions** | **$0.0015** | Limited | Limited |
|
|
75
|
+
| **Bulk extraction** | **$0.00015/result** | Not available | Not available |
|
|
76
|
+
| **Monitoring + webhooks** | **Free** | Not available | Not available |
|
|
77
|
+
| **Giveaway draws** | **$0.00015/entry** | Not available | Not available |
|
|
78
|
+
|
|
79
|
+
## Pay-Per-Use
|
|
80
|
+
|
|
81
|
+
Two options without a monthly subscription:
|
|
82
|
+
|
|
83
|
+
**Credits**: Top up credits via `POST /credits/topup` ($10 minimum). 1 credit = $0.00015. Works with all 122 endpoints.
|
|
84
|
+
|
|
85
|
+
**MPP**: 32 X-API endpoints accept anonymous on-chain payments. No account needed.
|
|
86
|
+
|
|
87
|
+
| Endpoint | Price | Unit |
|
|
88
|
+
|----------|-------|------|
|
|
89
|
+
| `GET /x/tweets/{id}` | $0.00015 | per call |
|
|
90
|
+
| `GET /x/tweets/search` | $0.00015 | per tweet |
|
|
91
|
+
| `GET /x/tweets/{id}/quotes` | $0.00015 | per tweet |
|
|
92
|
+
| `GET /x/tweets/{id}/replies` | $0.00015 | per tweet |
|
|
93
|
+
| `GET /x/tweets/{id}/retweeters` | $0.00015 | per user |
|
|
94
|
+
| `GET /x/tweets/{id}/favoriters` | $0.00015 | per user |
|
|
95
|
+
| `GET /x/tweets/{id}/thread` | $0.00015 | per tweet |
|
|
96
|
+
| `GET /x/users/{id}` | $0.00015 | per call |
|
|
97
|
+
| `GET /x/users/{id}/tweets` | $0.00015 | per tweet |
|
|
98
|
+
| `GET /x/users/{id}/likes` | $0.00015 | per tweet |
|
|
99
|
+
| `GET /x/users/{id}/media` | $0.00015 | per tweet |
|
|
100
|
+
| `GET /x/followers/check` | $0.00105 | per call |
|
|
101
|
+
| `GET /x/articles/{tweetId}` | $0.00105 | per call |
|
|
102
|
+
| `POST /x/media/download` | $0.00015 | per media item |
|
|
103
|
+
| `GET /x/trends` | $0.00045 | per call |
|
|
104
|
+
| `GET /trends` | $0.00045 | per call |
|
|
105
|
+
| `GET /x/communities/{id}/info` | $0.00015 | per call |
|
|
106
|
+
| `GET /x/communities/{id}/members` | $0.00015 | per user |
|
|
107
|
+
| `GET /x/communities/{id}/moderators` | $0.00015 | per user |
|
|
108
|
+
| `GET /x/communities/{id}/tweets` | $0.00015 | per tweet |
|
|
109
|
+
| `GET /x/communities/search` | $0.00015 | per community |
|
|
110
|
+
| `GET /x/communities/tweets` | $0.00015 | per tweet |
|
|
111
|
+
| `GET /x/lists/{id}/followers` | $0.00015 | per user |
|
|
112
|
+
| `GET /x/lists/{id}/members` | $0.00015 | per user |
|
|
113
|
+
| `GET /x/lists/{id}/tweets` | $0.00015 | per tweet |
|
|
114
|
+
| `GET /x/users/batch` | $0.00015 | per user |
|
|
115
|
+
| `GET /x/users/search` | $0.00015 | per user |
|
|
116
|
+
| `GET /x/users/{id}/followers` | $0.00015 | per user |
|
|
117
|
+
| `GET /x/users/{id}/followers-you-know` | $0.00015 | per user |
|
|
118
|
+
| `GET /x/users/{id}/following` | $0.00015 | per user |
|
|
119
|
+
| `GET /x/users/{id}/mentions` | $0.00015 | per tweet |
|
|
120
|
+
| `GET /x/users/{id}/verified-followers` | $0.00015 | per user |
|
|
121
|
+
|
|
122
|
+
SDK: `npm i mppx viem` (TypeScript). Handles the 402 challenge/credential flow automatically.
|
|
123
|
+
|
|
124
|
+
## Credits
|
|
125
|
+
|
|
126
|
+
Prepaid credits for metered operations. 1 credit = $0.00015. Top up via `POST /credits/topup` ($10 minimum).
|
|
127
|
+
|
|
128
|
+
Check balance: `GET /credits` — returns `balance`, `lifetimePurchased`, `lifetimeUsed`.
|
|
129
|
+
|
|
130
|
+
## Extra Usage
|
|
131
|
+
|
|
132
|
+
Enable from dashboard to continue metered calls beyond included allowance. Tiered spending limits: $5 -> $7 -> $10 -> $15 -> $25 (increases with each paid overage invoice).
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Xquik Python Examples
|
|
2
|
+
|
|
3
|
+
Python equivalents of the JavaScript examples in SKILL.md.
|
|
4
|
+
|
|
5
|
+
## Authentication
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
API_KEY = "xq_YOUR_KEY_HERE"
|
|
11
|
+
BASE = "https://xquik.com/api/v1"
|
|
12
|
+
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Retry with Exponential Backoff
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import time, random
|
|
19
|
+
|
|
20
|
+
def xquik_fetch(path, method="GET", json_body=None, max_retries=3):
|
|
21
|
+
base_delay = 1.0
|
|
22
|
+
|
|
23
|
+
for attempt in range(max_retries + 1):
|
|
24
|
+
response = requests.request(
|
|
25
|
+
method,
|
|
26
|
+
f"{BASE}{path}",
|
|
27
|
+
headers=HEADERS,
|
|
28
|
+
json=json_body,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
if response.ok:
|
|
32
|
+
return response.json()
|
|
33
|
+
|
|
34
|
+
retryable = response.status_code == 429 or response.status_code >= 500
|
|
35
|
+
if not retryable or attempt == max_retries:
|
|
36
|
+
error = response.json()
|
|
37
|
+
raise Exception(f"Xquik API {response.status_code}: {error['error']}")
|
|
38
|
+
|
|
39
|
+
retry_after = response.headers.get("Retry-After")
|
|
40
|
+
delay = int(retry_after) if retry_after else base_delay * (2 ** attempt) + random.uniform(0, 1)
|
|
41
|
+
time.sleep(delay)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Extraction Workflow
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
# Step 1: Estimate
|
|
48
|
+
estimate = xquik_fetch("/extractions/estimate", method="POST", json_body={
|
|
49
|
+
"toolType": "reply_extractor",
|
|
50
|
+
"targetTweetId": "1893704267862470862",
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
if not estimate["allowed"]:
|
|
54
|
+
print(f"Would exceed quota: {estimate['projectedPercent']}%")
|
|
55
|
+
exit()
|
|
56
|
+
|
|
57
|
+
# Step 2: Create job
|
|
58
|
+
job = xquik_fetch("/extractions", method="POST", json_body={
|
|
59
|
+
"toolType": "reply_extractor",
|
|
60
|
+
"targetTweetId": "1893704267862470862",
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
# Step 3: Poll until complete (large jobs may return "running")
|
|
64
|
+
while job["status"] in ("pending", "running"):
|
|
65
|
+
time.sleep(2)
|
|
66
|
+
job = xquik_fetch(f"/extractions/{job['id']}")
|
|
67
|
+
|
|
68
|
+
# Step 4: Get results
|
|
69
|
+
cursor = None
|
|
70
|
+
results = []
|
|
71
|
+
|
|
72
|
+
while True:
|
|
73
|
+
path = f"/extractions/{job['id']}"
|
|
74
|
+
if cursor:
|
|
75
|
+
path += f"?after={cursor}"
|
|
76
|
+
page = xquik_fetch(path)
|
|
77
|
+
results.extend(page["results"])
|
|
78
|
+
|
|
79
|
+
if not page["hasMore"]:
|
|
80
|
+
break
|
|
81
|
+
cursor = page["nextCursor"]
|
|
82
|
+
|
|
83
|
+
print(f"Extracted {len(results)} results")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Giveaway Draw
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Create draw with all filters
|
|
90
|
+
draw = xquik_fetch("/draws", method="POST", json_body={
|
|
91
|
+
"tweetUrl": "https://x.com/burakbayir/status/1893456789012345678",
|
|
92
|
+
"winnerCount": 3,
|
|
93
|
+
"backupCount": 2,
|
|
94
|
+
"uniqueAuthorsOnly": True,
|
|
95
|
+
"mustRetweet": True,
|
|
96
|
+
"mustFollowUsername": "burakbayir",
|
|
97
|
+
"filterMinFollowers": 50,
|
|
98
|
+
"filterAccountAgeDays": 30,
|
|
99
|
+
"requiredKeywords": ["giveaway"],
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
# Get winners
|
|
103
|
+
details = xquik_fetch(f"/draws/{draw['id']}")
|
|
104
|
+
for winner in details["winners"]:
|
|
105
|
+
role = "BACKUP" if winner["isBackup"] else "WINNER"
|
|
106
|
+
print(f"{role} #{winner['position']}: @{winner['authorUsername']}")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Webhook Handler (Flask)
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
import hmac, hashlib, json, os
|
|
113
|
+
from flask import Flask, request
|
|
114
|
+
|
|
115
|
+
app = Flask(__name__)
|
|
116
|
+
# Per-webhook secret from POST /webhooks response, not a Xquik account credential
|
|
117
|
+
WEBHOOK_SECRET = os.environ["XQUIK_WEBHOOK_SECRET"]
|
|
118
|
+
processed_hashes = set() # Use Redis/DB in production
|
|
119
|
+
|
|
120
|
+
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
|
|
121
|
+
expected = "sha256=" + hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
|
|
122
|
+
return hmac.compare_digest(expected, signature)
|
|
123
|
+
|
|
124
|
+
EVENT_HANDLERS = {
|
|
125
|
+
"tweet.new": lambda u, d: print(f"New tweet from @{u}: {d['text']}"),
|
|
126
|
+
"tweet.reply": lambda u, d: print(f"Reply from @{u}: {d['text']}"),
|
|
127
|
+
"tweet.quote": lambda u, d: print(f"Quote from @{u}: {d['text']}"),
|
|
128
|
+
"tweet.retweet": lambda u, d: print(f"Retweet by @{u}"),
|
|
129
|
+
"follower.gained": lambda u, d: print(f"@{u} gained follower: @{d['followerUsername']}"),
|
|
130
|
+
"follower.lost": lambda u, d: print(f"@{u} lost follower: @{d['followerUsername']}"),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@app.route("/webhook", methods=["POST"])
|
|
134
|
+
def webhook():
|
|
135
|
+
signature = request.headers.get("X-Xquik-Signature", "")
|
|
136
|
+
payload = request.get_data()
|
|
137
|
+
|
|
138
|
+
if not verify_signature(payload, signature, WEBHOOK_SECRET):
|
|
139
|
+
return "Invalid signature", 401
|
|
140
|
+
|
|
141
|
+
payload_hash = hashlib.sha256(payload).hexdigest()
|
|
142
|
+
if payload_hash in processed_hashes:
|
|
143
|
+
return "Already processed", 200
|
|
144
|
+
processed_hashes.add(payload_hash)
|
|
145
|
+
|
|
146
|
+
event = json.loads(payload)
|
|
147
|
+
handler = EVENT_HANDLERS.get(event["eventType"])
|
|
148
|
+
if handler:
|
|
149
|
+
handler(event["username"], event["data"])
|
|
150
|
+
|
|
151
|
+
return "OK", 200
|
|
152
|
+
```
|