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.
@@ -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
+ ```