@socialapitech/sdk 1.0.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 +171 -0
- package/dist/index.d.ts +387 -0
- package/dist/index.js +494 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SocialAPI Tech
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# SocialAPI — TypeScript / JavaScript SDK
|
|
2
|
+
|
|
3
|
+
Real-time X (Twitter) data. **40 read endpoints** plus free account endpoints for checking your own balance and usage. Around 100× cheaper than the official X API.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm i @socialapitech/sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { SocialAPI } from "@socialapitech/sdk";
|
|
11
|
+
|
|
12
|
+
const api = new SocialAPI("sk_your_key"); // or set SOCIALAPI_KEY
|
|
13
|
+
|
|
14
|
+
const user = await api.user_info("elonmusk");
|
|
15
|
+
console.log(user.followers_count);
|
|
16
|
+
|
|
17
|
+
const tweets = await api.user_last_tweets("elonmusk", { limit: 10 });
|
|
18
|
+
for (const t of tweets) console.log(t.created_at, t.text.slice(0, 80));
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Get a key at **[socialapi.tech/signup](https://socialapi.tech/signup)** — no credit card.
|
|
22
|
+
|
|
23
|
+
Ships with full TypeScript declarations. Works in Node 18+, Deno, Bun, and
|
|
24
|
+
any runtime with `fetch`.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Why this exists
|
|
29
|
+
|
|
30
|
+
The official X API bills **per resource returned** — $0.005 a post, $0.010 a
|
|
31
|
+
profile. Pulling 30 posts costs $0.15 there; the same call here is $0.0008,
|
|
32
|
+
and a profile is $0.00015 instead of $0.010.
|
|
33
|
+
|
|
34
|
+
That gap is the whole reason this exists. Same pay-as-you-go model, roughly
|
|
35
|
+
100× less, one balance across every endpoint, and composite lookups plus
|
|
36
|
+
per-account streaming that the official API does not offer at all.
|
|
37
|
+
|
|
38
|
+
**Read-only by design.** There is no posting, liking, or following. That means
|
|
39
|
+
you never hand us an X account — a leaked key costs you some data queries, not
|
|
40
|
+
your voice.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Common tasks
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// Search — full X syntax, real-time (not cached)
|
|
48
|
+
await api.search_advanced("bitcoin min_faves:100", { limit: 30 });
|
|
49
|
+
|
|
50
|
+
// Is this account alive, suspended, or gone?
|
|
51
|
+
await api.user_status("someaccount"); // -> alive | suspended | not_found
|
|
52
|
+
|
|
53
|
+
// Followers / following with cursor pagination
|
|
54
|
+
await api.user_followers("jack", { limit: 200 });
|
|
55
|
+
|
|
56
|
+
// Trends — worldwide, or per-region with a WOEID
|
|
57
|
+
await api.trends();
|
|
58
|
+
await api.trends_place({ woeid: 1 });
|
|
59
|
+
|
|
60
|
+
// One call, full picture (several lookups run concurrently server-side)
|
|
61
|
+
await api.user_whois("elonmusk");
|
|
62
|
+
|
|
63
|
+
// Batch profiles in one request
|
|
64
|
+
await api.batch_user_info("elonmusk,jack,binance");
|
|
65
|
+
|
|
66
|
+
// Your own account — balance, spend, and what you're monitoring. These are free.
|
|
67
|
+
const me = await api.usage(); // balance + today/month spend
|
|
68
|
+
await api.analytics({ days: 14 }); // per-endpoint usage + days of runway left
|
|
69
|
+
await api.stream_subscriptions(); // which accounts you're watching, and the daily cost
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Every method maps 1:1 to an endpoint in the
|
|
73
|
+
[API reference](https://socialapi.tech/docs).
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Watching accounts, not just querying them
|
|
78
|
+
|
|
79
|
+
The methods above are request-and-response: you ask, you get an answer. If what
|
|
80
|
+
you need is *"tell me the moment they post"*, that runs over a WebSocket or a
|
|
81
|
+
webhook instead — we push to you, median **two seconds** from post to delivery.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// Your handler receives each new tweet as it lands
|
|
85
|
+
const ws = new WebSocket("wss://api.socialapi.tech/v1/stream/ws?api_key=sk_your_key");
|
|
86
|
+
ws.onmessage = (e) => console.log(JSON.parse(e.data));
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Monitoring is **$0.08 per account per day**, billed hourly — stop it and the
|
|
90
|
+
billing stops. One account minimum, no bundles. It draws from the same balance
|
|
91
|
+
as everything else, so there's nothing extra to sign up for.
|
|
92
|
+
|
|
93
|
+
Setup and payload format: [socialapi.tech/docs](https://socialapi.tech/docs)
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## What it costs
|
|
98
|
+
|
|
99
|
+
| | |
|
|
100
|
+
|---|---|
|
|
101
|
+
| A call returning up to 30 tweets | **$0.0008** |
|
|
102
|
+
| Per tweet, at 30 per call | **$0.000027** |
|
|
103
|
+
| Single profile lookup | **$0.00015** |
|
|
104
|
+
| Watching one account | **$0.08 / day** |
|
|
105
|
+
|
|
106
|
+
No monthly fee, no minimum, no card. Failed calls cost nothing, and credits
|
|
107
|
+
don't expire.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Errors worth handling
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { SocialAPI, RateLimited, InsufficientCredits, SocialAPIError }
|
|
115
|
+
from "@socialapitech/sdk";
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await api.user_info("elonmusk");
|
|
119
|
+
} catch (e) {
|
|
120
|
+
if (e instanceof InsufficientCredits) {
|
|
121
|
+
// 402 — top up. Do NOT retry; it will fail the same way.
|
|
122
|
+
} else if (e instanceof RateLimited) {
|
|
123
|
+
// 429 — not charged. Back off (the SDK already retries twice).
|
|
124
|
+
} else if (e instanceof SocialAPIError) {
|
|
125
|
+
console.error(e.status, e.message);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**402 and 429 mean different things.** 429 is "too fast, slow down" and costs
|
|
131
|
+
nothing. 402 is "out of balance" — retrying just burns time. The SDK retries
|
|
132
|
+
429 and 5xx automatically with exponential backoff, and never retries 402.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Billing, briefly
|
|
137
|
+
|
|
138
|
+
- Only **successful** requests are charged.
|
|
139
|
+
- A call returning up to 30 items is **one tier** — asking for 30 costs the
|
|
140
|
+
same as asking for 3, so request what you actually need.
|
|
141
|
+
- Every response carries an `x-credits-used` header.
|
|
142
|
+
|
|
143
|
+
Full rules: [socialapi.tech/#pricing](https://socialapi.tech/#pricing)
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Configuration
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const api = new SocialAPI({
|
|
151
|
+
apiKey: "sk_...", // or env SOCIALAPI_KEY
|
|
152
|
+
baseUrl: "https://api.socialapi.tech",
|
|
153
|
+
timeoutMs: 30_000,
|
|
154
|
+
maxRetries: 2, // for 429 / 5xx only
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Support
|
|
161
|
+
|
|
162
|
+
- Docs — <https://socialapi.tech/docs>
|
|
163
|
+
- Telegram — <https://t.me/socialapi_support>
|
|
164
|
+
- Email — <contact@socialapi.tech>
|
|
165
|
+
|
|
166
|
+
MIT licensed.
|
|
167
|
+
|
|
168
|
+
> *SocialAPI is an independent service and is not affiliated with, endorsed by,
|
|
169
|
+
> or authorized by X Corp. "X" and "Twitter" are trademarks of X Corp., used
|
|
170
|
+
> here only to describe the data this service reads. We access only publicly
|
|
171
|
+
> visible data.*
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SocialAPI TypeScript/JavaScript SDK — real-time X (Twitter) data.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED FILE - DO NOT EDIT BY HAND.
|
|
5
|
+
* Produced by sdk-generator/generate.mjs from openapi.json. Edit the spec and
|
|
6
|
+
* regenerate; hand edits are overwritten on the next run.
|
|
7
|
+
*
|
|
8
|
+
* Docs: https://socialapi.tech/docs
|
|
9
|
+
*/
|
|
10
|
+
export declare class SocialAPIError extends Error {
|
|
11
|
+
status: number;
|
|
12
|
+
code?: unknown | undefined;
|
|
13
|
+
constructor(message: string, status?: number, code?: unknown | undefined);
|
|
14
|
+
}
|
|
15
|
+
/** 429 - rate limited. **Not charged**; back off and retry. */
|
|
16
|
+
export declare class RateLimited extends SocialAPIError {
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
19
|
+
/** 402 - out of credits. **Do not retry**; top up first. */
|
|
20
|
+
export declare class InsufficientCredits extends SocialAPIError {
|
|
21
|
+
constructor(message: string);
|
|
22
|
+
}
|
|
23
|
+
export interface SocialAPIOptions {
|
|
24
|
+
/** API key; falls back to process.env.SOCIALAPI_KEY */
|
|
25
|
+
apiKey?: string;
|
|
26
|
+
/** Override the API host (self-hosted or staging) */
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
/** Per-request timeout in ms (default 30000) */
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
/** Retries for 429/5xx (default 2). **402 is never retried.** */
|
|
31
|
+
maxRetries?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class SocialAPI {
|
|
34
|
+
private apiKey;
|
|
35
|
+
private baseUrl;
|
|
36
|
+
private timeoutMs;
|
|
37
|
+
private maxRetries;
|
|
38
|
+
constructor(opts?: SocialAPIOptions | string);
|
|
39
|
+
private get;
|
|
40
|
+
/**
|
|
41
|
+
* Get user profile by username
|
|
42
|
+
*
|
|
43
|
+
* Look up a single X account's profile: followers, bio, verification, join date. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
44
|
+
*/
|
|
45
|
+
user_info(username: string): Promise<any>;
|
|
46
|
+
/**
|
|
47
|
+
* Get user profile by numeric ID
|
|
48
|
+
*
|
|
49
|
+
* Reverse lookup: numeric ID to profile. Useful after followers_ids returns raw IDs. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
50
|
+
*/
|
|
51
|
+
user_info_by_id(user_id: string): Promise<any>;
|
|
52
|
+
/**
|
|
53
|
+
* Account transparency details
|
|
54
|
+
*
|
|
55
|
+
* X's 'About this account' data: country, join date, username change count, verification history. Anti-bot signal. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
56
|
+
*/
|
|
57
|
+
user_about(username: string): Promise<any>;
|
|
58
|
+
/**
|
|
59
|
+
* Recent tweets
|
|
60
|
+
*
|
|
61
|
+
* Most recent tweets from an account, newest first. Includes original posts, replies, retweets and quote tweets — the same set X shows on a profile timeline. Use `exclude` to narrow it down. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Deep history**: for accounts under continuous monitoring this endpoint serves up to 1,000 tweets from our own store — well beyond what a live timeline scrape returns. Coverage begins when an account entered monitoring, so the earliest available date differs per account; accounts outside the monitored set return whatever the live timeline yields.
|
|
62
|
+
*/
|
|
63
|
+
user_last_tweets(username: string, opts?: {
|
|
64
|
+
limit?: number;
|
|
65
|
+
cursor?: string;
|
|
66
|
+
exclude?: string;
|
|
67
|
+
}): Promise<any>;
|
|
68
|
+
/**
|
|
69
|
+
* Replies only
|
|
70
|
+
*
|
|
71
|
+
* Only this account's replies, using X's own replies timeline. Equivalent to filtering last_tweets down to replies, but sourced directly from X. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
72
|
+
*/
|
|
73
|
+
user_replies(username: string, opts?: {
|
|
74
|
+
limit?: number;
|
|
75
|
+
cursor?: string;
|
|
76
|
+
}): Promise<any>;
|
|
77
|
+
/**
|
|
78
|
+
* Tweets with photos
|
|
79
|
+
*
|
|
80
|
+
* Only image posts. Measured 88% carry photos, zero overlap with last_tweets. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
81
|
+
*/
|
|
82
|
+
user_photos(username: string, opts?: {
|
|
83
|
+
limit?: number;
|
|
84
|
+
cursor?: string;
|
|
85
|
+
}): Promise<any>;
|
|
86
|
+
/**
|
|
87
|
+
* Tweets with video
|
|
88
|
+
*
|
|
89
|
+
* Only video posts, with direct mp4 URLs, duration and thumbnail. Measured 100% carry video. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
90
|
+
*/
|
|
91
|
+
user_videos(username: string, opts?: {
|
|
92
|
+
limit?: number;
|
|
93
|
+
cursor?: string;
|
|
94
|
+
}): Promise<any>;
|
|
95
|
+
/**
|
|
96
|
+
* Tweets with any media
|
|
97
|
+
*
|
|
98
|
+
* Photos and video combined. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
99
|
+
*/
|
|
100
|
+
user_media(username: string, opts?: {
|
|
101
|
+
limit?: number;
|
|
102
|
+
}): Promise<any>;
|
|
103
|
+
/**
|
|
104
|
+
* Highlighted tweets
|
|
105
|
+
*
|
|
106
|
+
* Tweets the account pinned to its Highlights tab. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
107
|
+
*/
|
|
108
|
+
user_highlights(username: string, opts?: {
|
|
109
|
+
limit?: number;
|
|
110
|
+
}): Promise<any>;
|
|
111
|
+
/**
|
|
112
|
+
* Long-form articles
|
|
113
|
+
*
|
|
114
|
+
* X Articles (long-form posts) with full plain text. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
115
|
+
*/
|
|
116
|
+
user_articles(username: string, opts?: {
|
|
117
|
+
limit?: number;
|
|
118
|
+
}): Promise<any>;
|
|
119
|
+
/**
|
|
120
|
+
* Mentions of an account
|
|
121
|
+
*
|
|
122
|
+
* Who is talking to this account. Core endpoint for brand and ticker sentiment monitoring. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
123
|
+
*/
|
|
124
|
+
user_mentions(username: string, opts?: {
|
|
125
|
+
limit?: number;
|
|
126
|
+
}): Promise<any>;
|
|
127
|
+
/**
|
|
128
|
+
* Followers with full profiles
|
|
129
|
+
*
|
|
130
|
+
* Follower list with complete profile objects. 200 per page, no depth cap. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
131
|
+
*/
|
|
132
|
+
user_followers(username: string, opts?: {
|
|
133
|
+
limit?: number;
|
|
134
|
+
cursor?: string;
|
|
135
|
+
}): Promise<any>;
|
|
136
|
+
/**
|
|
137
|
+
* Accounts this user follows
|
|
138
|
+
*
|
|
139
|
+
* Following list with full profiles. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
140
|
+
*/
|
|
141
|
+
user_followings(username: string, opts?: {
|
|
142
|
+
limit?: number;
|
|
143
|
+
cursor?: string;
|
|
144
|
+
}): Promise<any>;
|
|
145
|
+
/**
|
|
146
|
+
* Verified followers
|
|
147
|
+
*
|
|
148
|
+
* Only blue-check followers - audience quality signal. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
149
|
+
*/
|
|
150
|
+
user_verified_followers(username: string, opts?: {
|
|
151
|
+
limit?: number;
|
|
152
|
+
cursor?: string;
|
|
153
|
+
}): Promise<any>;
|
|
154
|
+
/**
|
|
155
|
+
* Follower IDs (lightweight)
|
|
156
|
+
*
|
|
157
|
+
* IDs and handles only - 8.3 bytes per follower vs 151 for full profiles. Built for follower-graph crawling at scale. **Pricing**: 60 credits per 100-item tier (1 USD = 100,000 credits).
|
|
158
|
+
*/
|
|
159
|
+
user_followers_ids(username: string, opts?: {
|
|
160
|
+
limit?: number;
|
|
161
|
+
cursor?: string;
|
|
162
|
+
}): Promise<any>;
|
|
163
|
+
/**
|
|
164
|
+
* Follow relationship between two accounts
|
|
165
|
+
*
|
|
166
|
+
* Does A follow B? Works on any two third-party accounts, not just your own. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
167
|
+
*/
|
|
168
|
+
user_relationship(source: string, target: string): Promise<any>;
|
|
169
|
+
/**
|
|
170
|
+
* Aggregate account intelligence
|
|
171
|
+
*
|
|
172
|
+
* One call returns profile plus recent activity plus transparency data. Concurrent internally. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
173
|
+
*/
|
|
174
|
+
user_whois(username: string): Promise<any>;
|
|
175
|
+
/**
|
|
176
|
+
* Single tweet
|
|
177
|
+
*
|
|
178
|
+
* Full tweet object with all metrics and media. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
179
|
+
*/
|
|
180
|
+
tweet_info(id: string): Promise<any>;
|
|
181
|
+
/**
|
|
182
|
+
* Batch fetch tweets by IDs
|
|
183
|
+
*
|
|
184
|
+
* Fetch up to 100 tweets by ID in one request — the IDs can come from anywhere, including different accounts. Use this to refresh engagement counts on tweets you already stored, or to fill gaps a timeline cannot reach. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits) — the same rate as any tweet list. Billed on what is actually returned, so IDs that no longer exist cost nothing extra.
|
|
185
|
+
*/
|
|
186
|
+
tweets_batch(ids: string): Promise<any>;
|
|
187
|
+
/**
|
|
188
|
+
* Replies to a tweet
|
|
189
|
+
*
|
|
190
|
+
* The reply tree under a tweet. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
191
|
+
*/
|
|
192
|
+
tweet_replies(id: string, opts?: {
|
|
193
|
+
limit?: number;
|
|
194
|
+
}): Promise<any>;
|
|
195
|
+
/**
|
|
196
|
+
* Full thread
|
|
197
|
+
*
|
|
198
|
+
* Reconstructs a multi-tweet thread in order. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
199
|
+
*/
|
|
200
|
+
tweet_thread(id: string, opts?: {
|
|
201
|
+
limit?: number;
|
|
202
|
+
}): Promise<any>;
|
|
203
|
+
/**
|
|
204
|
+
* Quote tweets
|
|
205
|
+
*
|
|
206
|
+
* Who quoted this tweet and what they said. Note: X's search index favours recent content. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
207
|
+
*/
|
|
208
|
+
tweet_quotes(id: string, opts?: {
|
|
209
|
+
limit?: number;
|
|
210
|
+
}): Promise<any>;
|
|
211
|
+
/**
|
|
212
|
+
* Users who retweeted
|
|
213
|
+
*
|
|
214
|
+
* Retweeter profiles. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
215
|
+
*/
|
|
216
|
+
tweet_retweeters(id: string, opts?: {
|
|
217
|
+
limit?: number;
|
|
218
|
+
}): Promise<any>;
|
|
219
|
+
/**
|
|
220
|
+
* Engagement panorama
|
|
221
|
+
*
|
|
222
|
+
* Everything about how one tweet performed, in a single call: the tweet's own counts (likes, retweets, replies, quotes, views, bookmarks) plus the people behind them — who replied and who retweeted, with full profiles. **Pricing**: 120 credits for the first 60 items, then 12 credits per extra item — replies and retweeters counted together. Cheaper than calling `/v1/tweet/replies` and `/v1/tweet/retweeters` separately, which is the point — it saves you the round trip.
|
|
223
|
+
*/
|
|
224
|
+
tweet_engagement(id: string): Promise<any>;
|
|
225
|
+
/**
|
|
226
|
+
* Advanced tweet search
|
|
227
|
+
*
|
|
228
|
+
* Full X search syntax. Real-time, not cached. The workhorse for sentiment and event detection. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
229
|
+
*/
|
|
230
|
+
search_advanced(query: string, opts?: {
|
|
231
|
+
limit?: number;
|
|
232
|
+
product?: string;
|
|
233
|
+
}): Promise<any>;
|
|
234
|
+
/**
|
|
235
|
+
* Search users
|
|
236
|
+
*
|
|
237
|
+
* Find accounts by keyword. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
238
|
+
*/
|
|
239
|
+
search_user(query: string, opts?: {
|
|
240
|
+
limit?: number;
|
|
241
|
+
}): Promise<any>;
|
|
242
|
+
/**
|
|
243
|
+
* Community details
|
|
244
|
+
*
|
|
245
|
+
* Name, description, member count, join policy, rules. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
246
|
+
*/
|
|
247
|
+
community_info(community_id: string): Promise<any>;
|
|
248
|
+
/**
|
|
249
|
+
* Community tweet stream
|
|
250
|
+
*
|
|
251
|
+
* Posts inside an X Community. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
252
|
+
*/
|
|
253
|
+
community_tweets(community_id: string, opts?: {
|
|
254
|
+
limit?: number;
|
|
255
|
+
cursor?: string;
|
|
256
|
+
ranking?: string;
|
|
257
|
+
}): Promise<any>;
|
|
258
|
+
/**
|
|
259
|
+
* Community members
|
|
260
|
+
*
|
|
261
|
+
* Member list with cursor pagination - measured zero duplicates across 39 pages. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
262
|
+
*/
|
|
263
|
+
community_members(community_id: string, opts?: {
|
|
264
|
+
limit?: number;
|
|
265
|
+
cursor?: string;
|
|
266
|
+
}): Promise<any>;
|
|
267
|
+
/**
|
|
268
|
+
* Community moderators
|
|
269
|
+
*
|
|
270
|
+
* Moderator list. Single digits typically, returned in one call. **Pricing**: 25 credits per call (1 USD = 100,000 credits).
|
|
271
|
+
*/
|
|
272
|
+
community_moderators(community_id: string): Promise<any>;
|
|
273
|
+
/**
|
|
274
|
+
* List timeline
|
|
275
|
+
*
|
|
276
|
+
* Tweets from every account on an X List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
277
|
+
*/
|
|
278
|
+
list_timeline(list_id: string, opts?: {
|
|
279
|
+
limit?: number;
|
|
280
|
+
}): Promise<any>;
|
|
281
|
+
/**
|
|
282
|
+
* List members
|
|
283
|
+
*
|
|
284
|
+
* Accounts on a List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
285
|
+
*/
|
|
286
|
+
list_members(list_id: string, opts?: {
|
|
287
|
+
limit?: number;
|
|
288
|
+
cursor?: string;
|
|
289
|
+
}): Promise<any>;
|
|
290
|
+
/**
|
|
291
|
+
* List subscribers
|
|
292
|
+
*
|
|
293
|
+
* Accounts subscribed to a List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
294
|
+
*/
|
|
295
|
+
list_subscribers(list_id: string, opts?: {
|
|
296
|
+
limit?: number;
|
|
297
|
+
cursor?: string;
|
|
298
|
+
}): Promise<any>;
|
|
299
|
+
/**
|
|
300
|
+
* Global trending topics
|
|
301
|
+
*
|
|
302
|
+
* What is trending right now worldwide. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
303
|
+
*/
|
|
304
|
+
trends(): Promise<any>;
|
|
305
|
+
/**
|
|
306
|
+
* Trends for a region
|
|
307
|
+
*
|
|
308
|
+
* Region-specific trends across 467 locations - neither competitor offers this. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
309
|
+
*/
|
|
310
|
+
trends_place(opts?: {
|
|
311
|
+
woeid?: number;
|
|
312
|
+
}): Promise<any>;
|
|
313
|
+
/**
|
|
314
|
+
* Available trend regions
|
|
315
|
+
*
|
|
316
|
+
* The 467 WOEIDs accepted by /v1/trends/place. Static data, cache it. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
317
|
+
*/
|
|
318
|
+
trends_locations(): Promise<any>;
|
|
319
|
+
/**
|
|
320
|
+
* Explore feed
|
|
321
|
+
*
|
|
322
|
+
* X's multi-section explore page. **Pricing**: 20 credits per call (1 USD = 100,000 credits).
|
|
323
|
+
*/
|
|
324
|
+
explore(): Promise<any>;
|
|
325
|
+
/**
|
|
326
|
+
* Batch user profiles
|
|
327
|
+
*
|
|
328
|
+
* Multiple profiles in one call, fetched concurrently. **Pricing**: 40 credits per call (1 USD = 100,000 credits).
|
|
329
|
+
*/
|
|
330
|
+
batch_user_info(usernames: string): Promise<any>;
|
|
331
|
+
/**
|
|
332
|
+
* Account status (alive / suspended / not found)
|
|
333
|
+
*
|
|
334
|
+
* Check whether an X account is alive, suspended, deleted or otherwise unavailable — without guessing from a 404. Returns one of: `alive` (with user_id), `suspended`, `not_found`, `unavailable`. Always HTTP 200 — "the account does not exist"… **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
335
|
+
*/
|
|
336
|
+
user_status(username: string): Promise<any>;
|
|
337
|
+
/**
|
|
338
|
+
* Verified organization affiliates
|
|
339
|
+
*
|
|
340
|
+
* Official accounts affiliated with a verified organization (staff, sub-brands). Get a company's entire X footprint in one call. Note: pass the ORGANIZATION handle (e.g. `X`), not a member account. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
341
|
+
*/
|
|
342
|
+
user_affiliates(username: string, opts?: {
|
|
343
|
+
cursor?: string;
|
|
344
|
+
limit?: number;
|
|
345
|
+
}): Promise<any>;
|
|
346
|
+
/**
|
|
347
|
+
* Account usage & balance
|
|
348
|
+
*
|
|
349
|
+
* Your current credit balance, plus call counts and spend for today and the last 30 days, your account email and join date, and your total deposits with the volume-bonus tier they earn. **Free** — this endpoint is not billed. Use it to check
|
|
350
|
+
*/
|
|
351
|
+
usage(): Promise<any>;
|
|
352
|
+
/**
|
|
353
|
+
* Usage analytics & runway
|
|
354
|
+
*
|
|
355
|
+
* Per-day and per-endpoint usage over a window, plus success rate, p50/p95 latency, and a **runway estimate** — how many days your balance lasts at the current burn rate (API spend plus any live-stream subscriptions). **Free** — this endpoint
|
|
356
|
+
*/
|
|
357
|
+
analytics(opts?: {
|
|
358
|
+
days?: number;
|
|
359
|
+
}): Promise<any>;
|
|
360
|
+
/**
|
|
361
|
+
* Recent request log
|
|
362
|
+
*
|
|
363
|
+
* Your most recent API calls with endpoint, status, latency and credits charged. Useful for debugging a client without leaving your terminal. **Free** — this endpoint is not billed.
|
|
364
|
+
*/
|
|
365
|
+
logs(opts?: {
|
|
366
|
+
limit?: number;
|
|
367
|
+
}): Promise<any>;
|
|
368
|
+
/**
|
|
369
|
+
* List API keys
|
|
370
|
+
*
|
|
371
|
+
* Your API keys with labels, creation time and last-used time. Key values themselves are stored hashed and are never returned — only their metadata. **Free** — this endpoint is not billed.
|
|
372
|
+
*/
|
|
373
|
+
keys(): Promise<any>;
|
|
374
|
+
/**
|
|
375
|
+
* Live-stream subscriptions
|
|
376
|
+
*
|
|
377
|
+
* Which accounts you are monitoring over the live stream, how many are active versus paused, what they cost per hour and per day, and how many days your balance covers at that rate. **Free** — this endpoint is not billed. (The subscriptions t
|
|
378
|
+
*/
|
|
379
|
+
stream_subscriptions(): Promise<any>;
|
|
380
|
+
/**
|
|
381
|
+
* Credit balance
|
|
382
|
+
*
|
|
383
|
+
* Your credit balance on its own — the smallest call for a balance check. **Free** — this endpoint is not billed.
|
|
384
|
+
*/
|
|
385
|
+
deposit_balance(): Promise<any>;
|
|
386
|
+
}
|
|
387
|
+
export default SocialAPI;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SocialAPI TypeScript/JavaScript SDK — real-time X (Twitter) data.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED FILE - DO NOT EDIT BY HAND.
|
|
5
|
+
* Produced by sdk-generator/generate.mjs from openapi.json. Edit the spec and
|
|
6
|
+
* regenerate; hand edits are overwritten on the next run.
|
|
7
|
+
*
|
|
8
|
+
* Docs: https://socialapi.tech/docs
|
|
9
|
+
*/
|
|
10
|
+
export class SocialAPIError extends Error {
|
|
11
|
+
status;
|
|
12
|
+
code;
|
|
13
|
+
constructor(message, status = 0, code) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.name = "SocialAPIError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** 429 - rate limited. **Not charged**; back off and retry. */
|
|
21
|
+
export class RateLimited extends SocialAPIError {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message, 429);
|
|
24
|
+
this.name = "RateLimited";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** 402 - out of credits. **Do not retry**; top up first. */
|
|
28
|
+
export class InsufficientCredits extends SocialAPIError {
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message, 402);
|
|
31
|
+
this.name = "InsufficientCredits";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const VERSION = "1.0.0";
|
|
35
|
+
export class SocialAPI {
|
|
36
|
+
apiKey;
|
|
37
|
+
baseUrl;
|
|
38
|
+
timeoutMs;
|
|
39
|
+
maxRetries;
|
|
40
|
+
constructor(opts = {}) {
|
|
41
|
+
const o = typeof opts === "string" ? { apiKey: opts } : opts;
|
|
42
|
+
const key = o.apiKey ??
|
|
43
|
+
(typeof process !== "undefined" ? process.env?.SOCIALAPI_KEY : undefined) ??
|
|
44
|
+
"";
|
|
45
|
+
if (!key) {
|
|
46
|
+
throw new Error("API key missing. Pass apiKey or set SOCIALAPI_KEY. " +
|
|
47
|
+
"Get one free at https://socialapi.tech/signup");
|
|
48
|
+
}
|
|
49
|
+
this.apiKey = key;
|
|
50
|
+
this.baseUrl = (o.baseUrl ?? "https://api.socialapi.tech").replace(/\/$/, "");
|
|
51
|
+
this.timeoutMs = o.timeoutMs ?? 30_000;
|
|
52
|
+
this.maxRetries = o.maxRetries ?? 2;
|
|
53
|
+
}
|
|
54
|
+
async get(path, params) {
|
|
55
|
+
// Drop undefined/null so the server applies its own default.
|
|
56
|
+
const url = new URL(this.baseUrl + path);
|
|
57
|
+
for (const [k, v] of Object.entries(params)) {
|
|
58
|
+
if (v !== undefined && v !== null)
|
|
59
|
+
url.searchParams.set(k, String(v));
|
|
60
|
+
}
|
|
61
|
+
let lastErr;
|
|
62
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
63
|
+
const ac = new AbortController();
|
|
64
|
+
const timer = setTimeout(() => ac.abort(), this.timeoutMs);
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(url, {
|
|
67
|
+
headers: {
|
|
68
|
+
"X-API-Key": this.apiKey,
|
|
69
|
+
"User-Agent": `socialapi-js/${VERSION}`,
|
|
70
|
+
},
|
|
71
|
+
signal: ac.signal,
|
|
72
|
+
});
|
|
73
|
+
clearTimeout(timer);
|
|
74
|
+
if (res.status === 200) {
|
|
75
|
+
const body = await res.json();
|
|
76
|
+
if (body && body.status === "error") {
|
|
77
|
+
throw new SocialAPIError(body.error?.message ?? "unknown error", 200, body.error?.code);
|
|
78
|
+
}
|
|
79
|
+
return body?.data ?? body;
|
|
80
|
+
}
|
|
81
|
+
// Never retry 402: deterministic failure.
|
|
82
|
+
if (res.status === 402) {
|
|
83
|
+
throw new InsufficientCredits("insufficient credits — top up at https://socialapi.tech/dashboard/deposit");
|
|
84
|
+
}
|
|
85
|
+
if (res.status === 429) {
|
|
86
|
+
lastErr = new RateLimited("rate limited (not charged) — back off and retry");
|
|
87
|
+
if (attempt < this.maxRetries) {
|
|
88
|
+
await sleep(2 ** attempt * 1000);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
throw lastErr;
|
|
92
|
+
}
|
|
93
|
+
if (res.status >= 500 && attempt < this.maxRetries) {
|
|
94
|
+
lastErr = new SocialAPIError(`server error ${res.status}`, res.status);
|
|
95
|
+
await sleep(2 ** attempt * 1000);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
let msg = `HTTP ${res.status}`;
|
|
99
|
+
try {
|
|
100
|
+
msg = (await res.json())?.error?.message ?? msg;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* body was not JSON - fall back to the status code */
|
|
104
|
+
}
|
|
105
|
+
throw new SocialAPIError(msg, res.status);
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
if (e instanceof SocialAPIError)
|
|
110
|
+
throw e;
|
|
111
|
+
lastErr = e;
|
|
112
|
+
if (attempt < this.maxRetries) {
|
|
113
|
+
await sleep(2 ** attempt * 1000);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
throw new SocialAPIError(`network error: ${e?.message ?? e}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
throw lastErr ?? new SocialAPIError("request failed");
|
|
120
|
+
}
|
|
121
|
+
// ── generated endpoint methods (46) ──────────────────
|
|
122
|
+
/**
|
|
123
|
+
* Get user profile by username
|
|
124
|
+
*
|
|
125
|
+
* Look up a single X account's profile: followers, bio, verification, join date. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
126
|
+
*/
|
|
127
|
+
user_info(username) {
|
|
128
|
+
return this.get("/v1/user/info", { username });
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get user profile by numeric ID
|
|
132
|
+
*
|
|
133
|
+
* Reverse lookup: numeric ID to profile. Useful after followers_ids returns raw IDs. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
134
|
+
*/
|
|
135
|
+
user_info_by_id(user_id) {
|
|
136
|
+
return this.get("/v1/user/info_by_id", { user_id });
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Account transparency details
|
|
140
|
+
*
|
|
141
|
+
* X's 'About this account' data: country, join date, username change count, verification history. Anti-bot signal. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
142
|
+
*/
|
|
143
|
+
user_about(username) {
|
|
144
|
+
return this.get("/v1/user/about", { username });
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Recent tweets
|
|
148
|
+
*
|
|
149
|
+
* Most recent tweets from an account, newest first. Includes original posts, replies, retweets and quote tweets — the same set X shows on a profile timeline. Use `exclude` to narrow it down. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Deep history**: for accounts under continuous monitoring this endpoint serves up to 1,000 tweets from our own store — well beyond what a live timeline scrape returns. Coverage begins when an account entered monitoring, so the earliest available date differs per account; accounts outside the monitored set return whatever the live timeline yields.
|
|
150
|
+
*/
|
|
151
|
+
user_last_tweets(username, opts = {}) {
|
|
152
|
+
return this.get("/v1/user/last_tweets", { username, limit: opts.limit, cursor: opts.cursor, exclude: opts.exclude });
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Replies only
|
|
156
|
+
*
|
|
157
|
+
* Only this account's replies, using X's own replies timeline. Equivalent to filtering last_tweets down to replies, but sourced directly from X. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
158
|
+
*/
|
|
159
|
+
user_replies(username, opts = {}) {
|
|
160
|
+
return this.get("/v1/user/replies", { username, limit: opts.limit, cursor: opts.cursor });
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Tweets with photos
|
|
164
|
+
*
|
|
165
|
+
* Only image posts. Measured 88% carry photos, zero overlap with last_tweets. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
166
|
+
*/
|
|
167
|
+
user_photos(username, opts = {}) {
|
|
168
|
+
return this.get("/v1/user/photos", { username, limit: opts.limit, cursor: opts.cursor });
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Tweets with video
|
|
172
|
+
*
|
|
173
|
+
* Only video posts, with direct mp4 URLs, duration and thumbnail. Measured 100% carry video. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits). **Note**: served from a live timeline read, so depth is bounded by what X returns.
|
|
174
|
+
*/
|
|
175
|
+
user_videos(username, opts = {}) {
|
|
176
|
+
return this.get("/v1/user/videos", { username, limit: opts.limit, cursor: opts.cursor });
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Tweets with any media
|
|
180
|
+
*
|
|
181
|
+
* Photos and video combined. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
182
|
+
*/
|
|
183
|
+
user_media(username, opts = {}) {
|
|
184
|
+
return this.get("/v1/user/media", { username, limit: opts.limit });
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Highlighted tweets
|
|
188
|
+
*
|
|
189
|
+
* Tweets the account pinned to its Highlights tab. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
190
|
+
*/
|
|
191
|
+
user_highlights(username, opts = {}) {
|
|
192
|
+
return this.get("/v1/user/highlights", { username, limit: opts.limit });
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Long-form articles
|
|
196
|
+
*
|
|
197
|
+
* X Articles (long-form posts) with full plain text. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
198
|
+
*/
|
|
199
|
+
user_articles(username, opts = {}) {
|
|
200
|
+
return this.get("/v1/user/articles", { username, limit: opts.limit });
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Mentions of an account
|
|
204
|
+
*
|
|
205
|
+
* Who is talking to this account. Core endpoint for brand and ticker sentiment monitoring. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
206
|
+
*/
|
|
207
|
+
user_mentions(username, opts = {}) {
|
|
208
|
+
return this.get("/v1/user/mentions", { username, limit: opts.limit });
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Followers with full profiles
|
|
212
|
+
*
|
|
213
|
+
* Follower list with complete profile objects. 200 per page, no depth cap. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
214
|
+
*/
|
|
215
|
+
user_followers(username, opts = {}) {
|
|
216
|
+
return this.get("/v1/user/followers", { username, limit: opts.limit, cursor: opts.cursor });
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Accounts this user follows
|
|
220
|
+
*
|
|
221
|
+
* Following list with full profiles. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
222
|
+
*/
|
|
223
|
+
user_followings(username, opts = {}) {
|
|
224
|
+
return this.get("/v1/user/followings", { username, limit: opts.limit, cursor: opts.cursor });
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Verified followers
|
|
228
|
+
*
|
|
229
|
+
* Only blue-check followers - audience quality signal. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
230
|
+
*/
|
|
231
|
+
user_verified_followers(username, opts = {}) {
|
|
232
|
+
return this.get("/v1/user/verified_followers", { username, limit: opts.limit, cursor: opts.cursor });
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Follower IDs (lightweight)
|
|
236
|
+
*
|
|
237
|
+
* IDs and handles only - 8.3 bytes per follower vs 151 for full profiles. Built for follower-graph crawling at scale. **Pricing**: 60 credits per 100-item tier (1 USD = 100,000 credits).
|
|
238
|
+
*/
|
|
239
|
+
user_followers_ids(username, opts = {}) {
|
|
240
|
+
return this.get("/v1/user/followers_ids", { username, limit: opts.limit, cursor: opts.cursor });
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Follow relationship between two accounts
|
|
244
|
+
*
|
|
245
|
+
* Does A follow B? Works on any two third-party accounts, not just your own. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
246
|
+
*/
|
|
247
|
+
user_relationship(source, target) {
|
|
248
|
+
return this.get("/v1/user/relationship", { source, target });
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Aggregate account intelligence
|
|
252
|
+
*
|
|
253
|
+
* One call returns profile plus recent activity plus transparency data. Concurrent internally. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
254
|
+
*/
|
|
255
|
+
user_whois(username) {
|
|
256
|
+
return this.get("/v1/user/whois", { username });
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Single tweet
|
|
260
|
+
*
|
|
261
|
+
* Full tweet object with all metrics and media. **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
262
|
+
*/
|
|
263
|
+
tweet_info(id) {
|
|
264
|
+
return this.get("/v1/tweet/info", { id });
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Batch fetch tweets by IDs
|
|
268
|
+
*
|
|
269
|
+
* Fetch up to 100 tweets by ID in one request — the IDs can come from anywhere, including different accounts. Use this to refresh engagement counts on tweets you already stored, or to fill gaps a timeline cannot reach. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits) — the same rate as any tweet list. Billed on what is actually returned, so IDs that no longer exist cost nothing extra.
|
|
270
|
+
*/
|
|
271
|
+
tweets_batch(ids) {
|
|
272
|
+
return this.get("/v1/tweets/batch", { ids });
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Replies to a tweet
|
|
276
|
+
*
|
|
277
|
+
* The reply tree under a tweet. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
278
|
+
*/
|
|
279
|
+
tweet_replies(id, opts = {}) {
|
|
280
|
+
return this.get("/v1/tweet/replies", { id, limit: opts.limit });
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Full thread
|
|
284
|
+
*
|
|
285
|
+
* Reconstructs a multi-tweet thread in order. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
286
|
+
*/
|
|
287
|
+
tweet_thread(id, opts = {}) {
|
|
288
|
+
return this.get("/v1/tweet/thread", { id, limit: opts.limit });
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Quote tweets
|
|
292
|
+
*
|
|
293
|
+
* Who quoted this tweet and what they said. Note: X's search index favours recent content. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
294
|
+
*/
|
|
295
|
+
tweet_quotes(id, opts = {}) {
|
|
296
|
+
return this.get("/v1/tweet/quotes", { id, limit: opts.limit });
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Users who retweeted
|
|
300
|
+
*
|
|
301
|
+
* Retweeter profiles. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
302
|
+
*/
|
|
303
|
+
tweet_retweeters(id, opts = {}) {
|
|
304
|
+
return this.get("/v1/tweet/retweeters", { id, limit: opts.limit });
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Engagement panorama
|
|
308
|
+
*
|
|
309
|
+
* Everything about how one tweet performed, in a single call: the tweet's own counts (likes, retweets, replies, quotes, views, bookmarks) plus the people behind them — who replied and who retweeted, with full profiles. **Pricing**: 120 credits for the first 60 items, then 12 credits per extra item — replies and retweeters counted together. Cheaper than calling `/v1/tweet/replies` and `/v1/tweet/retweeters` separately, which is the point — it saves you the round trip.
|
|
310
|
+
*/
|
|
311
|
+
tweet_engagement(id) {
|
|
312
|
+
return this.get("/v1/tweet/engagement", { id });
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Advanced tweet search
|
|
316
|
+
*
|
|
317
|
+
* Full X search syntax. Real-time, not cached. The workhorse for sentiment and event detection. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
318
|
+
*/
|
|
319
|
+
search_advanced(query, opts = {}) {
|
|
320
|
+
return this.get("/v1/search/advanced", { query, limit: opts.limit, product: opts.product });
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Search users
|
|
324
|
+
*
|
|
325
|
+
* Find accounts by keyword. **Pricing**: 100 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
326
|
+
*/
|
|
327
|
+
search_user(query, opts = {}) {
|
|
328
|
+
return this.get("/v1/search/user", { query, limit: opts.limit });
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Community details
|
|
332
|
+
*
|
|
333
|
+
* Name, description, member count, join policy, rules. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
334
|
+
*/
|
|
335
|
+
community_info(community_id) {
|
|
336
|
+
return this.get("/v1/community/info", { community_id });
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Community tweet stream
|
|
340
|
+
*
|
|
341
|
+
* Posts inside an X Community. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
342
|
+
*/
|
|
343
|
+
community_tweets(community_id, opts = {}) {
|
|
344
|
+
return this.get("/v1/community/tweets", { community_id, limit: opts.limit, cursor: opts.cursor, ranking: opts.ranking });
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Community members
|
|
348
|
+
*
|
|
349
|
+
* Member list with cursor pagination - measured zero duplicates across 39 pages. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
350
|
+
*/
|
|
351
|
+
community_members(community_id, opts = {}) {
|
|
352
|
+
return this.get("/v1/community/members", { community_id, limit: opts.limit, cursor: opts.cursor });
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Community moderators
|
|
356
|
+
*
|
|
357
|
+
* Moderator list. Single digits typically, returned in one call. **Pricing**: 25 credits per call (1 USD = 100,000 credits).
|
|
358
|
+
*/
|
|
359
|
+
community_moderators(community_id) {
|
|
360
|
+
return this.get("/v1/community/moderators", { community_id });
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* List timeline
|
|
364
|
+
*
|
|
365
|
+
* Tweets from every account on an X List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
366
|
+
*/
|
|
367
|
+
list_timeline(list_id, opts = {}) {
|
|
368
|
+
return this.get("/v1/list/timeline", { list_id, limit: opts.limit });
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* List members
|
|
372
|
+
*
|
|
373
|
+
* Accounts on a List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
374
|
+
*/
|
|
375
|
+
list_members(list_id, opts = {}) {
|
|
376
|
+
return this.get("/v1/list/members", { list_id, limit: opts.limit, cursor: opts.cursor });
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* List subscribers
|
|
380
|
+
*
|
|
381
|
+
* Accounts subscribed to a List. **Pricing**: 80 credits for the first 30 items, then 12 credits per extra item (1 USD = 100,000 credits).
|
|
382
|
+
*/
|
|
383
|
+
list_subscribers(list_id, opts = {}) {
|
|
384
|
+
return this.get("/v1/list/subscribers", { list_id, limit: opts.limit, cursor: opts.cursor });
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Global trending topics
|
|
388
|
+
*
|
|
389
|
+
* What is trending right now worldwide. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
390
|
+
*/
|
|
391
|
+
trends() {
|
|
392
|
+
return this.get("/v1/trends", {});
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Trends for a region
|
|
396
|
+
*
|
|
397
|
+
* Region-specific trends across 467 locations - neither competitor offers this. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
398
|
+
*/
|
|
399
|
+
trends_place(opts = {}) {
|
|
400
|
+
return this.get("/v1/trends/place", { woeid: opts.woeid });
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Available trend regions
|
|
404
|
+
*
|
|
405
|
+
* The 467 WOEIDs accepted by /v1/trends/place. Static data, cache it. **Pricing**: 12 credits per call (1 USD = 100,000 credits).
|
|
406
|
+
*/
|
|
407
|
+
trends_locations() {
|
|
408
|
+
return this.get("/v1/trends/locations", {});
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Explore feed
|
|
412
|
+
*
|
|
413
|
+
* X's multi-section explore page. **Pricing**: 20 credits per call (1 USD = 100,000 credits).
|
|
414
|
+
*/
|
|
415
|
+
explore() {
|
|
416
|
+
return this.get("/v1/explore", {});
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Batch user profiles
|
|
420
|
+
*
|
|
421
|
+
* Multiple profiles in one call, fetched concurrently. **Pricing**: 40 credits per call (1 USD = 100,000 credits).
|
|
422
|
+
*/
|
|
423
|
+
batch_user_info(usernames) {
|
|
424
|
+
return this.get("/v1/batch/user_info", { usernames });
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Account status (alive / suspended / not found)
|
|
428
|
+
*
|
|
429
|
+
* Check whether an X account is alive, suspended, deleted or otherwise unavailable — without guessing from a 404. Returns one of: `alive` (with user_id), `suspended`, `not_found`, `unavailable`. Always HTTP 200 — "the account does not exist"… **Pricing**: 15 credits per call (1 USD = 100,000 credits).
|
|
430
|
+
*/
|
|
431
|
+
user_status(username) {
|
|
432
|
+
return this.get("/v1/user/status", { username });
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Verified organization affiliates
|
|
436
|
+
*
|
|
437
|
+
* Official accounts affiliated with a verified organization (staff, sub-brands). Get a company's entire X footprint in one call. Note: pass the ORGANIZATION handle (e.g. `X`), not a member account. **Pricing**: 80 credits per call (1 USD = 100,000 credits).
|
|
438
|
+
*/
|
|
439
|
+
user_affiliates(username, opts = {}) {
|
|
440
|
+
return this.get("/v1/user/affiliates", { username, cursor: opts.cursor, limit: opts.limit });
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Account usage & balance
|
|
444
|
+
*
|
|
445
|
+
* Your current credit balance, plus call counts and spend for today and the last 30 days, your account email and join date, and your total deposits with the volume-bonus tier they earn. **Free** — this endpoint is not billed. Use it to check
|
|
446
|
+
*/
|
|
447
|
+
usage() {
|
|
448
|
+
return this.get("/v1/usage", {});
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Usage analytics & runway
|
|
452
|
+
*
|
|
453
|
+
* Per-day and per-endpoint usage over a window, plus success rate, p50/p95 latency, and a **runway estimate** — how many days your balance lasts at the current burn rate (API spend plus any live-stream subscriptions). **Free** — this endpoint
|
|
454
|
+
*/
|
|
455
|
+
analytics(opts = {}) {
|
|
456
|
+
return this.get("/v1/analytics", { days: opts.days });
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Recent request log
|
|
460
|
+
*
|
|
461
|
+
* Your most recent API calls with endpoint, status, latency and credits charged. Useful for debugging a client without leaving your terminal. **Free** — this endpoint is not billed.
|
|
462
|
+
*/
|
|
463
|
+
logs(opts = {}) {
|
|
464
|
+
return this.get("/v1/logs", { limit: opts.limit });
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* List API keys
|
|
468
|
+
*
|
|
469
|
+
* Your API keys with labels, creation time and last-used time. Key values themselves are stored hashed and are never returned — only their metadata. **Free** — this endpoint is not billed.
|
|
470
|
+
*/
|
|
471
|
+
keys() {
|
|
472
|
+
return this.get("/v1/keys", {});
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Live-stream subscriptions
|
|
476
|
+
*
|
|
477
|
+
* Which accounts you are monitoring over the live stream, how many are active versus paused, what they cost per hour and per day, and how many days your balance covers at that rate. **Free** — this endpoint is not billed. (The subscriptions t
|
|
478
|
+
*/
|
|
479
|
+
stream_subscriptions() {
|
|
480
|
+
return this.get("/v1/stream/subscriptions", {});
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Credit balance
|
|
484
|
+
*
|
|
485
|
+
* Your credit balance on its own — the smallest call for a balance check. **Free** — this endpoint is not billed.
|
|
486
|
+
*/
|
|
487
|
+
deposit_balance() {
|
|
488
|
+
return this.get("/v1/deposit/balance", {});
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function sleep(ms) {
|
|
492
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
493
|
+
}
|
|
494
|
+
export default SocialAPI;
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@socialapitech/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Real-time X (Twitter) data — 40 endpoints plus live streaming. $0.0008 per call, up to 30 tweets, from $0.000027 each. Around 100x cheaper than the official X API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"prepublishOnly": "npm run build",
|
|
27
|
+
"test": "node --test test/smoke.test.js"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"twitter",
|
|
31
|
+
"x",
|
|
32
|
+
"twitter-api",
|
|
33
|
+
"x-api",
|
|
34
|
+
"twitter-scraper",
|
|
35
|
+
"social-media",
|
|
36
|
+
"sentiment-analysis",
|
|
37
|
+
"twitter-data",
|
|
38
|
+
"api-client",
|
|
39
|
+
"typescript",
|
|
40
|
+
"socialapi",
|
|
41
|
+
"twitter-stream",
|
|
42
|
+
"realtime",
|
|
43
|
+
"websocket",
|
|
44
|
+
"twitter-monitoring"
|
|
45
|
+
],
|
|
46
|
+
"author": "SocialAPI Tech <contact@socialapi.tech>",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"homepage": "https://socialapi.tech",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/socialapitech/socialapi-node.git"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/socialapitech/socialapi-node/issues"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"typescript": "^5.5.0",
|
|
61
|
+
"@types/node": "^20.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|