superx-cli 0.2.0 → 0.4.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/CHANGELOG.md +45 -2
- package/PLAYBOOK.md +2 -2
- package/PLAYBOOKS.md +523 -0
- package/README.md +32 -11
- package/SKILL.md +489 -22
- package/dist/index.js +1798 -22
- package/package.json +2 -1
package/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: superx
|
|
3
|
-
description: SuperX is a Twitter/X growth tool. Use it to read an account's published posts with engagement metrics, pull account analytics (impressions, likes, replies, follower change), find the people who engage with the account most, review reply history in both directions (sent and received), manage contact lists, create and manage signal agents (automated lead finders) and review the leads they discover, search a library of 50M+ high-performing posts for inspiration, create, edit, tag, or schedule draft posts and threads (with image attachments), write, schedule, publish, and generate AI covers for long-form X Articles, and read or update the account's Context settings (profile description, interests, SuperX rules, reply settings, favorite creators, style guide, products) that steer SuperX's AI writing, all through the SuperX API.
|
|
3
|
+
description: SuperX is a Twitter/X growth tool. Use it to read an account's published posts with engagement metrics, pull account analytics (impressions, likes, replies, follower change), find the people who engage with the account most, review reply history in both directions (sent and received), manage contact lists, create and manage signal agents (automated lead finders), add or remove the signals they watch, and review the leads they discover, marking each one fit or not fit, search a library of 50M+ high-performing posts for inspiration, create, edit, and delete saved Engage feeds and read the posts they surface for review, create, edit, tag, or schedule draft posts and threads (with image attachments), write, schedule, publish, and generate AI covers for long-form X Articles (in one of the account's saved cover styles), and read or update the account's Context settings (profile description, interests, SuperX rules, reply settings, favorite creators, style guide, products) that steer SuperX's AI writing, all through the SuperX API.
|
|
4
4
|
homepage: https://docs.superx.so
|
|
5
5
|
metadata: {"openclaw":{"emoji":"🚀","requires":{"bins":["superx"],"env":[]}}}
|
|
6
6
|
---
|
|
@@ -30,9 +30,9 @@ official website: https://superx.so
|
|
|
30
30
|
|
|
31
31
|
**Rule 1: Run `superx status` before anything else.** Every other command fails without valid credentials. If the `superx` binary is missing, install it with `npm install -g superx-cli`. If not authenticated, either run `superx login` (interactive) or set `export SUPERX_API_KEY=sxk_...` (CI and non-interactive sessions). Keys are created at https://app.superx.so/account?tab=api.
|
|
32
32
|
|
|
33
|
-
**Rule 2: Read PLAYBOOK.md before creating any content.** This repo ships a growth strategy guide (`PLAYBOOK.md`, also inside the installed npm package). It tells you WHAT to post, WHEN, and WHY: the action hierarchy, out-of-network discovery, the engagement loop, and the failure modes that kill reach. The CLI gives you data and actions; the playbook gives you judgment. Do not schedule content without it.
|
|
33
|
+
**Rule 2: Read PLAYBOOK.md before creating any content.** This repo ships a growth strategy guide (`PLAYBOOK.md`, also inside the installed npm package). It tells you WHAT to post, WHEN, and WHY: the action hierarchy, out-of-network discovery, the engagement loop, and the failure modes that kill reach. The CLI gives you data and actions; the playbook gives you judgment. Do not schedule content without it. For a goal-shaped task ("give me my weekly recap", "DM the people who replied to this post"), read `PLAYBOOKS.md` too: it holds the 28 named recipes with their exact command chains, MCP tool names and stopping points.
|
|
34
34
|
|
|
35
|
-
**Rule 3: Know the write constraints.** `scheduled:create` without `--at` creates a DRAFT (nothing publishes). With `--at` it schedules for that time. `scheduled:update` changes only the flags you pass, and a new `--at` alone never schedules a draft; add `--status scheduled` to promote. Writes work on
|
|
35
|
+
**Rule 3: Know the write constraints.** `scheduled:create` without `--at` creates a DRAFT (nothing publishes). With `--at` it schedules for that time. `scheduled:update` changes only the flags you pass, and a new `--at` alone never schedules a draft; add `--status scheduled` to promote. Writes work on your main account or any linked account (pass the same `--account` you used to read it); accounts shared with you by other people are read-only, and tags are workspace-wide. Images attach via `media:upload` then `--media` (JPG/PNG/WEBP up to 5MB, GIF up to 15MB; max 4 images or 1 GIF per post); video is not supported. Timestamps MUST be UTC ISO-8601 with an explicit `Z` or offset; naive timestamps are rejected with 400. `posts:publish` and `articles:publish` post to X IMMEDIATELY and irreversibly; treat them like hitting Publish in public and get human confirmation of the exact text unless the user already gave it. `posts:publish` also requires `--idempotency-key`, which you reuse verbatim on any retry. `posts:draft` writes post text in the user's voice and saves NOTHING: show the drafts, let the user pick and edit one, then pass the final text to `scheduled:create` yourself; it costs AI credits per draft, so ask for the count the user actually wants.
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
@@ -51,7 +51,7 @@ echo "$POSTS" | jq '.data[].text'
|
|
|
51
51
|
|
|
52
52
|
## Core Workflow
|
|
53
53
|
|
|
54
|
-
1. **Check auth**: `superx status` (verifies the key and shows plan
|
|
54
|
+
1. **Check auth**: `superx status` (verifies the key and shows plan, AI credit pool, and rate-limit state)
|
|
55
55
|
2. **Discover accounts**: `superx accounts` (main account first; note ids for `--account`)
|
|
56
56
|
3. **Read the data**: top posts, analytics, most engaged contacts
|
|
57
57
|
4. **Read PLAYBOOK.md**, then draft content informed by what already works for this account
|
|
@@ -89,7 +89,7 @@ superx scheduled:list --status draft,scheduled
|
|
|
89
89
|
```bash
|
|
90
90
|
superx login # Guided: prints the key page URL, prompts for a paste
|
|
91
91
|
superx login --key "sxk_..." # Non-interactive
|
|
92
|
-
superx status # Verify credentials; shows plan, key scopes, rate limits
|
|
92
|
+
superx status # Verify credentials; shows plan, credits, key scopes, rate limits
|
|
93
93
|
superx logout # Delete ~/.superx/credentials.json
|
|
94
94
|
export SUPERX_API_KEY=sxk_... # Env alternative (credentials file wins when both exist)
|
|
95
95
|
```
|
|
@@ -133,7 +133,41 @@ superx inspiration:search "AI tools" --min-likes 500 --min-followers 1000 --max-
|
|
|
133
133
|
- Searches a library of 50M+ real high-performing posts. Use results for structures, hooks, and angles to remix. Never copy them.
|
|
134
134
|
- Flags: `--sort relevant|recent|likes|reposts|impressions|outlier`, `--min-likes/--min-reposts/--min-replies/--min-bookmarks/--min-impressions`, `--min-followers/--max-followers` (author size), `--since/--until`, `--lang` (default en), `--exclude-topics "crypto,politics"`, `--limit` (max 50), `--page` (1-7).
|
|
135
135
|
- `outlier_score` on each result = how far the post outperformed the norm for its author's follower tier. Sorting by `outlier` surfaces content that won on substance, not audience size.
|
|
136
|
-
- Results are
|
|
136
|
+
- Results are relevance-ranked, strongest matches first. Weak and promotional matches are filtered out, so a page may return fewer than `--limit` posts.
|
|
137
|
+
|
|
138
|
+
### Live X lookups
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
superx x:post https://x.com/levelsio/status/1938765432109876543 # one public post, live
|
|
142
|
+
superx x:post 1938765432109876543 --quotes # + a page of quote posts
|
|
143
|
+
superx x:replies 1938765432109876543 --limit 20 # best-liked direct replies
|
|
144
|
+
superx x:user @levelsio # one public profile, live
|
|
145
|
+
superx x:user-posts levelsio --limit 20 --no-reposts # their latest posts
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- These read X **right now**, not SuperX's stored data. Use them for a post or account the user names; use `posts:list` / `contacts:*` for the user's own SuperX data.
|
|
149
|
+
- Cost: the tighter **enrichment** allowance, 1 unit each, **3** for `x:replies` (it walks up to 3 pages), 2 for `x:post --quotes` and 2 for an `x:user-posts` handle SuperX has never seen (`profile_resolved_locally: false` reports that). A multi-unit call is all-or-nothing, never half-charged.
|
|
150
|
+
- On top of that they share an allowance of **300 live lookups per day** with Ask SuperX inside the app. Over it: `429 lookup_quota_exceeded` with `retry_after`, `limit` and `reset_at`, resetting at midnight UTC. That gate fails CLOSED, so the same code appears when SuperX cannot verify the count. Do not retry in a loop; tell the user.
|
|
151
|
+
- Results are cached server-side for about **15 minutes**. A repeat still costs its enrichment units but does not touch the 300/day allowance.
|
|
152
|
+
- `x:replies` is a **sample**: the best-liked replies from up to 3 relevance-ranked pages (about 60 candidates), never every reply and never chronological. For everyone who replied to a post, use the audience collections (`datasets:list`) built in the app. It also does NOT hide the account owner's own replies, unlike the same feature in the app.
|
|
153
|
+
- `x:post` 404s `post_not_found` for a deleted, protected or wrong id. The upstream read reports a missing post and a failed read identically, so retry once before telling the user a post is gone. `x:user` / `x:user-posts` 404 `user_not_found` for a suspended, renamed or misspelled handle.
|
|
154
|
+
- Owner-scoped: none of these take `--account`. Nothing about a public lookup is per-X-account.
|
|
155
|
+
|
|
156
|
+
### Inspiration media (cross-platform)
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
superx inspiration:media "founder morning routine" --limit 10
|
|
160
|
+
superx inspiration:media --platforms youtube,instagram --media-type video
|
|
161
|
+
superx inspiration:media # browse the newest
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- Searches the media index behind the app's Inspiration > Media tab: short-form video and image posts from x, instagram, youtube, threads, reddit and linkedin, with captions, a summary and engagement counts.
|
|
165
|
+
- **No media file URLs.** There is no thumbnail or video link in the response; `source_url` opens the original post on its own platform, so link the user there rather than trying to embed the media.
|
|
166
|
+
- With **no query** it browses the newest media instead of searching. `meta.mode` says which ran, and only `search` results carry a `score`. Unlike the app there is **no personalisation** here.
|
|
167
|
+
- Costs no enrichment. Its own caps are a burst of 20 (refilling one every 3 seconds) and 500 FRESH searches a day; repeats of a recent identical search come from a cache and do not count.
|
|
168
|
+
- **No pagination.** One query returns at most 120 items and `--limit` only trims that, so ask for `--limit 120` and filter locally rather than calling it again for "the next page".
|
|
169
|
+
- `--content-type` is a **free-text label as stored in the index**, with no list to choose from. A label the index does not use returns zero items and still burns one of the 500 daily searches, so leave it off unless the user named one.
|
|
170
|
+
- Use it for visual format and hook research, never to copy.
|
|
137
171
|
|
|
138
172
|
### Contacts (who engages with you)
|
|
139
173
|
|
|
@@ -145,6 +179,21 @@ superx contacts:replies <contact-id> --sort recent # One person's reply history
|
|
|
145
179
|
|
|
146
180
|
Sort options: `contacts:list` takes `engagement|replies|reposts`; `contacts:replies` takes `recent|most_liked`.
|
|
147
181
|
|
|
182
|
+
```bash
|
|
183
|
+
superx contacts:get <x-user-id> # Profile, follower counts, verified state, lists they are in (known contacts only)
|
|
184
|
+
superx contacts:get <x-user-id> --refresh # Refresh a stale profile from X (costs an enrichment unit)
|
|
185
|
+
superx contacts:notes <x-user-id> # Your private notes about them, newest first
|
|
186
|
+
superx contacts:notes:add <x-user-id> --body "Wants a demo in September"
|
|
187
|
+
superx contacts:notes:update <x-user-id> <note-id> --body "Demo booked for 12 Sept"
|
|
188
|
+
superx contacts:notes:delete <x-user-id> <note-id>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- The id everywhere here is a NUMERIC X user id, from `contacts:list`, `lists:members` or `signals:leads`. `contacts:get` returns the stored profile plus each list the person is in, with the `member_id` that `lists:remove-member` takes.
|
|
192
|
+
- KNOWN CONTACTS ONLY: `contacts:get` and `contacts:notes:add` resolve people the account actually knows, meaning anyone who has replied to or reposted its posts, a member of one of its contact lists (manual or system), or a scored signal lead. Any other id returns 404 `contact_not_found`, even one SuperX holds a profile for. This is NOT a general X profile lookup: take ids from `contacts:list`, `lists:members` or `signals:leads` rather than typing one in.
|
|
193
|
+
- `--refresh` is the only path that calls X. Leave it off unless the follower counts have to be current: it counts against the tighter enrichment limit, and the default read is free of it.
|
|
194
|
+
- Notes live inside SuperX and are NEVER posted anywhere. Use them for context you want on the next conversation. A note written through the CLI is attributed to the account you wrote as.
|
|
195
|
+
- Note writes need a key with the write scope; shared accounts are read-only.
|
|
196
|
+
|
|
148
197
|
### Contact lists
|
|
149
198
|
|
|
150
199
|
```bash
|
|
@@ -155,9 +204,116 @@ superx lists:remove-member <list-id> <member-id> # member-id from lists:memb
|
|
|
155
204
|
```
|
|
156
205
|
|
|
157
206
|
- Lists are the saved people-collections from the SuperX app. Use them to track prospects, customers, or people worth engaging.
|
|
158
|
-
- System lists (Followers, Following, Repliers, Reposters) appear in `lists:list` with `is_system: true` but are read-only and
|
|
207
|
+
- System lists (Followers, Following, Repliers, Reposters) appear in `lists:list` with `is_system: true` and a real `member_count`, but they are read-only and `lists:members` will not serve them: read their people with `audience:list <kind>` instead.
|
|
159
208
|
- Adding someone already in a list is harmless: the existing member returns with `"duplicate": true` and nothing changes.
|
|
160
|
-
- Member writes
|
|
209
|
+
- Member writes work on your main or linked accounts (`--account`) and need a key with the write scope; shared accounts are read-only.
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
superx lists:create --name "Founder prospects" # Names are NOT unique; check lists:list first
|
|
213
|
+
superx lists:rename <list-id> --name "Q4 prospects"
|
|
214
|
+
superx lists:delete <list-id> # Deletes the list and its membership; the people stay
|
|
215
|
+
superx lists:add-members <list-id> --x-user-ids 44196397,944883311 # up to 500 per call
|
|
216
|
+
superx lists:remove-members <list-id> --member-ids m1abc,m2def # up to 500 per call
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
- `lists:add-members` does NO live lookup: it uses profiles SuperX already stores, which is why it costs one write and no enrichment. Ids SuperX has never seen come back in `not_found` and are NOT added. Add those one at a time with `lists:add-member --handle`, which does resolve live.
|
|
220
|
+
- Re-adding someone already in the list is counted in `duplicates`, never an error. `lists:remove-members` skips ids that are not in the list, so `deleted` can be lower than what you sent.
|
|
221
|
+
- `lists:delete` also stops any signal agent depositing into that list until the agent is repointed in the SuperX app. Confirm with the user first.
|
|
222
|
+
|
|
223
|
+
### Audience (followers, following, repliers, reposters)
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
superx audience:list followers --limit 100 # newest followers first
|
|
227
|
+
superx audience:list following
|
|
228
|
+
superx audience:list repliers # people who replied in the last 90 days
|
|
229
|
+
superx audience:list reposters
|
|
230
|
+
superx audience:list followers --cursor "<next_cursor>" # the next page
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- These are the four SYSTEM people-lists in the app's Contacts tab. `lists:members` does not serve them; this is where they are read.
|
|
234
|
+
- Paging is by **cursor**, not page number. Take `pagination.next_cursor` from one call and pass it as `--cursor` to the next; `has_more: false` means you are at the end. Do not try `--page`.
|
|
235
|
+
- There is no `total`. `meta.synced_count` is the size of the whole list, so quote that rather than counting rows. It may exceed the rows a full walk returns, because edges that were later removed are still counted.
|
|
236
|
+
- `meta.status` is the sync state (`missing`, `pending`, `running`, `complete`, `paused`): anything but `complete` means SuperX is still filling the list in, so say so rather than presenting a partial list as the whole audience.
|
|
237
|
+
- On `followers` / `following`, `meta.is_capped: true` means the account is deeper than the plan's `backfill_cap` and the list is the most recent slice, not everyone.
|
|
238
|
+
- `repliers` and `reposters` are a rolling 90-day window (`meta.window_days`): someone whose last reply ages past 90 days drops out and comes back on their next one.
|
|
239
|
+
- `engaged_count` is replies + reposts in the last 90 days on the follow lists, and this list's own action count on the other two. `icp_score` and `icp_rationale` are always null here (scoring belongs to signal-agent leads).
|
|
240
|
+
- Costs no enrichment units, and reads like any other GET.
|
|
241
|
+
|
|
242
|
+
### Mentions (who is talking to you right now)
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
superx engage:mentions # newest mentions, with the post each replies to
|
|
246
|
+
superx engage:mentions --sort top # most engaged first
|
|
247
|
+
superx engage:mentions --include-replied true # keep ones you already answered, flagged replied
|
|
248
|
+
superx engage:mentions --cursor "<next_cursor>" # the next page
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
- Reads X **live**, so it is the up-to-the-minute view of what people are saying to the user, unlike `replies:received` which reads what SuperX has stored.
|
|
252
|
+
- One call costs **3 of the daily feed fetches** (the same allowance `engage:posts` draws on): read a page and work from it rather than polling.
|
|
253
|
+
- `mention_type` is `reply` for a direct reply to one of the user's posts and `mention` for anything else (standalone @-mention, chain, or being tagged in someone else's reply). `parent_post` carries the post being replied to, with one further level of ancestry.
|
|
254
|
+
- By default, mentions the user already replied to on X are left out. `--include-replied true` keeps them with `replied: true`.
|
|
255
|
+
- The app's Mentions tab also hides posts the user skipped or blocked there. That is an app preference and is NOT applied here, so the API list can be longer than what they see in the app.
|
|
256
|
+
- READ-ONLY, like Engage: there is no reply command. Draft suggestions for the user and let them send.
|
|
257
|
+
|
|
258
|
+
### Datasets (Ask SuperX collections)
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
superx datasets:list # collections built in the app, newest first
|
|
262
|
+
superx datasets:get <dataset-id> # status, counts, coverage sentence
|
|
263
|
+
superx datasets:rows <dataset-id> --limit 50 # a page of rows, exactly as collected
|
|
264
|
+
superx datasets:export <dataset-id> # writes superx-dataset-<title>-<date>.csv here
|
|
265
|
+
superx datasets:export <dataset-id> --out - # stream the CSV to stdout instead
|
|
266
|
+
superx datasets:add-to-list <dataset-id> --list-id <list-id> # copy its people into a list
|
|
267
|
+
|
|
268
|
+
# Build a new one (write scope)
|
|
269
|
+
superx datasets:collect --source repliers --target https://x.com/user/status/123 --wait
|
|
270
|
+
superx datasets:collect --source list_members --target https://x.com/i/lists/1234567890
|
|
271
|
+
superx datasets:collect --source my_posts --since-days 90 --sort likes
|
|
272
|
+
superx datasets:collect --source reposters --target 1234567890 --min-followers 500 --require-can-dm
|
|
273
|
+
|
|
274
|
+
# Narrow a dataset by what each person wrote (creates a NEW dataset)
|
|
275
|
+
superx datasets:refine <dataset-id> --criterion "supportive or neutral, not hostile" --sort followers --wait
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
- Datasets are audience collections: the repliers, quoters or reposters of a post, the members of an X list, the user's own posts or replies, or a set of research briefs. `datasets:collect` builds one from here, `datasets:research` builds the briefs kind (see Lead search and outreach below), and the ones Ask SuperX builds in the app show up in the same list.
|
|
279
|
+
- `datasets:collect` may not be done when it returns. A big collection, or one whose size cannot be established up front, answers `status: "collecting"` with zero rows and keeps running in the background: pass `--wait` to poll until it is ready, or poll `datasets:get` yourself. NEVER quote a row count from a `collecting` result.
|
|
280
|
+
- Each collection costs one of **10 a day** for the account, shared with the collections Ask SuperX runs in the app (429 `collection_quota_exceeded`), plus enrichment for the pages it walks. `--source my_posts` / `my_replies` read the local post library: no enrichment, always synchronous, and the profile filters do not apply to them (the `note` says so).
|
|
281
|
+
- Only ONE background collection runs per account at a time: a second one returns 409 `collection_in_progress`. If nothing matched the filters no dataset is created: the answer is `data: null` with a `note`.
|
|
282
|
+
- They are kept for **30 days**. After that the id 404s.
|
|
283
|
+
- `status` is `collecting`, `ready` or `failed`. Only a `ready` dataset can be paged, exported or added to a list; the others return `409 dataset_not_ready`.
|
|
284
|
+
- Export is **CSV only**. XLSX downloads stay in the SuperX app.
|
|
285
|
+
- `has_people: false` marks an own-content dataset (the user's posts or replies): there is nobody in it to add to a contact list.
|
|
286
|
+
- Dataset ids come from `datasets:list`; the tool that created one also reports its id in the app.
|
|
287
|
+
- `datasets:refine` filters a dataset by WHAT EACH PERSON WROTE and writes the kept rows to a NEW dataset; the source is untouched. It only works on datasets whose rows carry text (repliers, quoters) - anything else is a 400. Rows the classifier cannot judge are KEPT and counted as `unclear`, so report those honestly rather than claiming clean curation. It creates a dataset, so it counts against the SAME 10 collections a day, and it costs AI credits. Over 100 rows with text it answers `202 collecting`: pass `--wait` or poll `datasets:get`.
|
|
288
|
+
|
|
289
|
+
### Engage (feed posts to reply to)
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
superx engage:feeds # feeds saved in the app, with type and fetch cost
|
|
293
|
+
superx engage:posts <feed-id> --limit 50 # one big page of candidate posts
|
|
294
|
+
superx engage:posts <feed-id> --mode latest --fresh true # newest, skipping the cache
|
|
295
|
+
superx engage:posts <feed-id> --exclude 1234567890,1234567891 # next batch, minus what you have
|
|
296
|
+
superx engage:posts <feed-id> --include-replied true # keep posts already replied to
|
|
297
|
+
|
|
298
|
+
# Feed writes (write scope; main or linked account via --account)
|
|
299
|
+
superx engage:feeds:create --name "AI builders" --keyword "shipping with LLMs" --keyword "eval harness"
|
|
300
|
+
superx engage:feeds:create --name "Founders" --x-list https://x.com/i/lists/1234567890
|
|
301
|
+
superx engage:feeds:create --name "Prospects" --list-id <contact-list-id>
|
|
302
|
+
superx engage:feeds:update <feed-id> --name "AI builders v2"
|
|
303
|
+
superx engage:feeds:delete <feed-id>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
- Engage feeds are the keyword and list feeds the user set up in the app's Engage tab. `engage:feeds` gives each feed's `id`, `name`, `type` (`keywords`, `list`, `x_list`), `active`, and `fetch_units`.
|
|
307
|
+
- Feeds can be created, renamed, repointed and deleted here. Give `engage:feeds:create` a `--name` (1-40 chars) and exactly ONE source: repeatable `--keyword` (1-5), `--x-list` (a public X list id or `x.com/i/lists/...` link), or `--list-id` (one of the user's contact lists from `lists:list`).
|
|
308
|
+
- A feed you create does NOT become the feed the app has open: the person keeps their place. Tell them where to find the new feed rather than assuming they will see it.
|
|
309
|
+
- Up to 8 feeds per account (409 `feed_limit_reached` beyond that). `engage:feeds:update` changes one source at a time and keeps the feed's id, so a feed may switch type. Deleting the feed the app has open hands the slot to the first remaining feed.
|
|
310
|
+
- An X list source is looked up live: those calls also draw on the tighter enrichment allowance, and a private list is a 404 `x_list_not_found`. Keyword and contact-list feeds cost no enrichment.
|
|
311
|
+
- `engage:posts` returns candidate posts (text, author handle/bio/follower counts, engagement metrics, post time) plus `has_more` and the `feed`. Score and shortlist them for the user.
|
|
312
|
+
- READ-ONLY BY DESIGN: there is no reply command. Replies are written and sent by a person in SuperX. Sending replies that read as inauthentic can get an X account suspended and a SuperX account terminated; AI output must be reviewed and meaningfully edited by a person before it is posted. Surface candidates and draft suggestions for the user; never claim a reply was sent.
|
|
313
|
+
- `--limit` (1-50, default 20) applies to KEYWORD feeds. List feeds return one page per fetch (about 10 posts for a member list, 20 to 25 for an imported X list) and `--limit` only trims it. Page a list feed with `--exclude` (at most 100 ids per call; window the list to the most recent ids), not a bigger `--limit`.
|
|
314
|
+
- A 50-post page on a keyword feed costs the same as a 20-post page: ask for `--limit 50` a few times a day and filter locally. Feeds refresh over hours, so polling more often than hourly returns the same posts.
|
|
315
|
+
- Each plan has a daily feed-fetch allowance (Trial 20, Pro 60, Advanced 120, Ultra 300), separate from the read budget; per minute: trial 2, pro 5, advanced 10, ultra 15. A list feed that rotates its members counts as 3 fetches. `engage:feeds` never spends it. Over the cap you get 429 `rate_limited`: the API returns `remaining_day`; the CLI prints the message and the retry delay.
|
|
316
|
+
- Posts a fetch returns count as seen and get demoted in later fetches, in the app as well as here. An unknown feed id returns 404 `feed_not_found`.
|
|
161
317
|
|
|
162
318
|
### Signals (automated lead finding)
|
|
163
319
|
|
|
@@ -167,26 +323,107 @@ superx signals:leads --limit 20 # newest leads across all a
|
|
|
167
323
|
superx signals:leads --agent 3 --deposited false # one agent's leads not yet in its list
|
|
168
324
|
superx signals:leads --since "2026-07-01T00:00:00Z" # leads discovered since July
|
|
169
325
|
|
|
170
|
-
# Create an agent (main account
|
|
326
|
+
# Create an agent (write scope; main or linked account via --account)
|
|
171
327
|
superx signals:create-agent \
|
|
172
328
|
--name "Build in public founders" \
|
|
173
329
|
--icp "Indie founders building SaaS in public, sharing MRR and launches" \
|
|
174
330
|
--keyword "building in public" --keyword "just shipped my MVP"
|
|
175
331
|
|
|
332
|
+
# Watch an account and its followers as well as keywords
|
|
333
|
+
superx signals:create-agent --name "Naval orbit" --icp "..." \
|
|
334
|
+
--signal "profile:@naval" --signal "follower:@naval"
|
|
335
|
+
|
|
176
336
|
# Lifecycle (agent id from signals:agents)
|
|
337
|
+
superx signals:update-agent 3 --icp "Series A founders hiring their first RevOps lead"
|
|
338
|
+
superx signals:update-agent 3 --list-id <contact-list-id>
|
|
177
339
|
superx signals:pause-agent 3
|
|
178
340
|
superx signals:resume-agent 3
|
|
179
341
|
superx signals:delete-agent 3
|
|
342
|
+
|
|
343
|
+
# Signals on an existing agent (signal id from the agent's signals in signals:agents)
|
|
344
|
+
superx signals:add-signal 3 --type keyword_watch --query "just raised a seed round"
|
|
345
|
+
superx signals:add-signal 3 --type follower_watch --handle naval
|
|
346
|
+
superx signals:add-signal 3 --type list_watch --list https://x.com/i/lists/1234567890
|
|
347
|
+
superx signals:remove-signal 3 118
|
|
348
|
+
|
|
349
|
+
# Teach the scorer (lead id from signals:leads, NOT an X user id)
|
|
350
|
+
superx signals:feedback 4821 --fit
|
|
351
|
+
superx signals:feedback 4821 --not-fit
|
|
352
|
+
superx signals:feedback 4821 --clear
|
|
180
353
|
```
|
|
181
354
|
|
|
182
|
-
- Signal agents are automated lead finders: they watch profiles, followers, keywords, or lists and score people against an ideal customer profile.
|
|
183
|
-
- `signals:create-agent` requires `--name` (max 80) and `--icp` (max 500). Repeat `--keyword` for
|
|
355
|
+
- Signal agents are automated lead finders: they watch profiles, followers, keywords, or lists and score people against an ideal customer profile. All four watch types, agent edits, signal add/remove and lead feedback work from here.
|
|
356
|
+
- `signals:create-agent` requires `--name` (max 80) and `--icp` (max 500). Repeat `--keyword` for plain-language searches ("what does the target customer post about"), and repeat `--signal "type:target"` for the other kinds (`profile:@handle`, `follower:@handle`, `list:<id or x.com/i/lists link>`, `keyword:<search>`). Keywords and signals combined are 1-5 entries; omit both and 1-3 keywords are auto-suggested from the ICP. Omit `--list-id` and a contact list named `Leads: <agent name>` is created for the leads (`destination_list_created: true` in the response). `--precision high|discovery` defaults to high. Supports `--idempotency-key`.
|
|
357
|
+
- A create is PARTIAL SUCCESS: entries the add path rejects come back in `warnings` (each with its `type`, `target` and a `code` such as `user_not_found`, `x_list_not_found`, `duplicate_signal`, `cap_reached`) and the agent is still created with the entries that landed. Check `warnings` and re-add the fixed ones with `signals:add-signal`; never report a mistyped handle as watched.
|
|
358
|
+
- `signals:update-agent <id>` changes `--name`, `--icp`, `--precision`, `--list-id` or `--status`. Editing the ICP changes how NEW leads are scored; leads already found keep their scores. An unusable `--list-id` is a 404 `list_not_found`.
|
|
359
|
+
- `signals:add-signal` takes one target per call. Each plan caps how many signals one agent may hold (403 `cap_reached`), an agent may watch each target once (409 `duplicate_signal`), and handle/list adds are resolved live so they also draw on the enrichment allowance. `signals:remove-signal` keeps the leads that signal already found; removing the last signal is allowed and leaves the agent finding nothing.
|
|
360
|
+
- `signals:feedback` records the user's verdict and teaches the scorer, so ASK before deciding for them: a wrong verdict skews which leads the agent brings next. The verdict is also mirrored onto the person's row in the agent's destination list, and shows up as `feedback`/`feedback_at` on `signals:leads`.
|
|
184
361
|
- Creation returns immediately, but leads arrive ASYNCHRONOUSLY: the agent finds people over the following minutes and days. Never promise instant results; check `signals:leads` later.
|
|
185
362
|
- Deleting an agent keeps its saved leads and its contact list.
|
|
186
363
|
- Each lead carries the person's profile, `icp_score` and `icp_rationale` (why they matched), `deposited`/`deposited_at` (whether it has been saved to the agent's contact list yet), `discovered_at`, and `provenance` (how it was found: the action, the watched handle, the triggering post text).
|
|
187
364
|
- `signals:leads` flags: `--agent <id>` (from `signals:agents`; unknown id returns 404 `agent_not_found`), `--deposited true|false`, `--since/--until` (UTC ISO-8601, on discovery time), `--limit` (max 100, default 50), `--page`.
|
|
188
365
|
- An agent's `destination_list_id` joins to `lists:list` for the target list's name; deposited leads appear there as members.
|
|
189
366
|
|
|
367
|
+
### Lead search and outreach (live search, briefs, drafts)
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
# Find people on X right now (saves NOTHING: no agent, no stored leads)
|
|
371
|
+
superx signals:search \
|
|
372
|
+
--keywords "losing customers to churn, cancellations killing my MRR" \
|
|
373
|
+
--icp "B2B SaaS founders worried about retention" \
|
|
374
|
+
--precision discovery --max 10
|
|
375
|
+
|
|
376
|
+
# Turn people into outreach briefs saved as a dataset (exactly one source)
|
|
377
|
+
superx datasets:research --handles levelsio,naval --focus "audience-growth tooling" --wait
|
|
378
|
+
superx datasets:research --list <contact-list-id> --max 20 --wait
|
|
379
|
+
superx datasets:research --agent 3 --max 10 --wait
|
|
380
|
+
superx datasets:research --dataset <dataset-id> --max 25 --wait
|
|
381
|
+
|
|
382
|
+
# Draft one message per person onto that dataset (TEXT ONLY - nothing is sent)
|
|
383
|
+
superx datasets:outreach-drafts <dataset-id> \
|
|
384
|
+
--format "hey [first]! been following what you're building. <personalization>. would love to trade notes"
|
|
385
|
+
superx datasets:rows <dataset-id> --limit 50 # read every drafted message
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
- **Nothing in this chain sends a DM.** `datasets:outreach-drafts` writes message TEXT onto the dataset's `message` column and stops there. A person reviews and sends them from the SuperX app. Never tell the user their messages have gone out, and never imply the CLI can send them.
|
|
389
|
+
- `signals:suggest-keywords --icp "..."` and `signals:expand-icp (--text | --url)` stage what a new agent needs before you create one: keyword ideas, and the rubric the scorer reads the ICP as. Both are FREE and create nothing. Pass a suggestion to `signals:create-agent --keyword`; the rubric has nowhere to be saved (agents are created with `--icp`), so use it to sharpen that text. `--url` reads a website and also returns an `icp_description` to pass straight to `--icp`; it costs one of the account's 20 page reads a day, shared with the app, and takes up to a minute.
|
|
390
|
+
- `signals:search` needs a key with the **write** scope (every non-GET API route does), even though it CREATES NOTHING. The leads exist only in that response, so save what you need. For an audience that keeps filling up on its own, use `signals:create-agent` instead. It takes up to a minute, and each lead comes from ONE matched post: `posts_count` is lifetime volume, not proof of current activity.
|
|
391
|
+
- `datasets:research` needs exactly one of `--handles` (max 25), `--list`, `--agent` or `--dataset`, and `--max` is 1-25 (default 10). Every hook in a brief QUOTES one of the person's real posts; proposed quotes that failed the verbatim check are dropped server-side, so a brief with no hooks is honest, not broken. More than 5 profiles run in the background (`202 collecting`) - pass `--wait` or poll `datasets:get`.
|
|
392
|
+
- `datasets:outreach-drafts` needs a `--format` from the USER: their template or an example message. Never invent one. `[name]`, `[first]` and `[handle]` are kept intact for per-recipient fill-in at send time. A brief with no usable hook gets an honest generic message counted in `generic`, and a draft that names a DIFFERENT recipient is discarded and counted in `contaminated` (run it again to retry those rows). Re-running overwrites every draft.
|
|
393
|
+
- Costs: `signals:search` is measured, at least 1 credit for a search that reaches X; `datasets:research` is a flat **1 credit per profile actually researched** (the rest are returned); `datasets:outreach-drafts` is measured and usually 1-3 credits. Research settles when the run finishes, so after a `--wait` read `superx status` for the pool rather than the response.
|
|
394
|
+
- The two that read X live also carry per-plan day caps (`429 ai_action_limited`) and draw on a platform-wide fair-use ceiling shared by every account. On a 429 read `error.scope`: `"account"` means the user's own daily cap, `"platform"` means the shared ceiling and their own allowance is untouched - wait for `reset_at` and retry rather than telling them they are out.
|
|
395
|
+
|
|
396
|
+
### Writing helpers (drafts, remix, edits, checks)
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# One reply draft, in the user's voice (nothing is posted)
|
|
400
|
+
superx engage:reply-draft --post 1234567890 --thoughts "agree, and we saw the same thing" --tone concise
|
|
401
|
+
superx engage:reply-draft --text "hot take about pricing" --handle levelsio --author "Pieter Levels"
|
|
402
|
+
|
|
403
|
+
# Rewrite a post, near or far from the original
|
|
404
|
+
superx posts:remix --text "$(cat post.txt)" --closeness 70
|
|
405
|
+
superx posts:remix --text "..." --closeness 20 --instructions "make it a question"
|
|
406
|
+
|
|
407
|
+
# Change one selected piece, keeping the surrounding style
|
|
408
|
+
superx tools:inline-edit --text "the hook line" --full "$(cat post.txt)" --type hook
|
|
409
|
+
superx tools:inline-edit --text "..." --instruction "make this one line, lowercase"
|
|
410
|
+
|
|
411
|
+
# One preset rewrite of a whole post
|
|
412
|
+
superx tools:rephrase --type concise --text "$(cat post.txt)"
|
|
413
|
+
|
|
414
|
+
# Check a claim, and compare two drafts
|
|
415
|
+
superx tools:factcheck --text "X has 600M daily active users"
|
|
416
|
+
superx tools:predict --a "$(cat v1.txt)" --b "$(cat v2.txt)"
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
- **Every one of these returns TEXT and posts NOTHING.** `engage:reply-draft` writes a reply for a person to review and post; there is still no reply-sending command anywhere in the CLI. Show the draft, let the user edit it, and never say a reply went out.
|
|
420
|
+
- `engage:reply-draft` takes exactly one of `--post <id>` (the API reads the post live, so the draft sees the real text, author and any quoted post) or `--text` with optional `--author` and `--handle`. Add `--thoughts` with what the USER wants to say - ask them, never invent an opinion for them - and `--tone engaging|humorous|creative|sarcastic|inspirational|concise`. `--post` also spends one live X lookup on top of the credit.
|
|
421
|
+
- `posts:remix` needs `--closeness` 0-100: 0 keeps only the idea, 100 stays very close to the original wording. Use it on a proven post the user wants to say again in their own words, then save the result with `posts:draft` or `scheduled:create`.
|
|
422
|
+
- `tools:inline-edit` needs `--instruction`, `--type`, or both, and works best with `--full` so the edit blends into the post around it. `--type` presets: grammar, translate, hook, details, concise, engaging, humorous, creative, sarcastic, inspirational.
|
|
423
|
+
- `tools:rephrase` presets: improve, grammar, translate, hook, details, clarity, engaging, humorous, positive, creative, sarcastic, inspirational, concise. The style ones write in the user's voice; grammar, translate, clarity, details and concise stay mechanical.
|
|
424
|
+
- `tools:factcheck` reports `result` (true, false or unknown), a one-sentence `comment` and the `sources` it read. It is a model's reading of a couple of search results, NOT a guarantee: show the sources and never present the verdict as settled. `tools:predict` scores are an opinion for comparing two drafts against each other, not a prediction of reach.
|
|
425
|
+
- Costs are measured AI credits: typically 1 each, and 2 for a remix or a reply draft. None of them spends a live X request except `engage:reply-draft --post`.
|
|
426
|
+
|
|
190
427
|
### Scheduling
|
|
191
428
|
|
|
192
429
|
```bash
|
|
@@ -229,6 +466,48 @@ superx scheduled:delete <post-id>
|
|
|
229
466
|
- `scheduled:list` filters: `--status draft,scheduled,sent,error` (comma list), `--tags id,id` (any-of), `--from/--to` bounds on the scheduled time.
|
|
230
467
|
- `media:upload` accepts JPG/PNG/WEBP (5MB) and GIF (15MB); a post part carries up to 4 images OR exactly 1 GIF. Uploads are capped at 100/day and expire after 24h if never attached.
|
|
231
468
|
|
|
469
|
+
### Publishing now (irreversible)
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
# Publishes to X the moment this returns. --idempotency-key is REQUIRED.
|
|
473
|
+
superx posts:publish --text "Post text" --idempotency-key "launch-2026-09-07"
|
|
474
|
+
|
|
475
|
+
# Thread, same shape as scheduled:create
|
|
476
|
+
superx posts:publish --part "1/ The hook" --part "2/ The close" --idempotency-key "thread-42"
|
|
477
|
+
|
|
478
|
+
# With an image and an auto retweet
|
|
479
|
+
KEY=$(superx media:upload ./chart.png | jq -r '.object_key')
|
|
480
|
+
superx posts:publish --text "Chart of the week" --media "$KEY" --alt-text "Weekly revenue line chart" \
|
|
481
|
+
--auto-retweet 6 --idempotency-key "chart-2026-09-07"
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
- **Get explicit human confirmation of the exact text before running this.** It cannot be undone: the post is live on X. Use `scheduled:create --at` for anything that can wait, and `posts:draft` when the user still wants to review wording.
|
|
485
|
+
- `--idempotency-key` is required and is yours to choose. Reuse the SAME key on a retry: it returns the original result instead of posting again. Only use a new key for genuinely new content.
|
|
486
|
+
- On a timeout, retry with the SAME key. A retry inside the publish window returns 409 `idempotency_in_flight` with a `Retry-After` delay; after that the API checks whether the first attempt landed and replays its result rather than posting twice.
|
|
487
|
+
- No `--at`, `--title` or `--scratchpad`: a published post has no draft to organize (passing them returns 400).
|
|
488
|
+
- The result carries `status: "sent"`, `posted_at`, `x_post_id` and `url`.
|
|
489
|
+
- Advanced settings and Auto DM inherit the account's Default Post Settings exactly like `scheduled:create`; the `--no-*` forms turn one off for this post.
|
|
490
|
+
|
|
491
|
+
### Bulk queue operations
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
# Move queued posts to new times (up to 500, one transaction: all or none)
|
|
495
|
+
superx scheduled:bulk-retime --moves-json '[{"id":"abc","scheduled_for":"2026-09-08T15:00:00Z"}]'
|
|
496
|
+
|
|
497
|
+
# Turn Auto Retweet on for posts that do not have it (up to 100)
|
|
498
|
+
superx scheduled:bulk-auto-retweet --ids abc,def --auto-retweet 6 --auto-retweet-remove 4
|
|
499
|
+
|
|
500
|
+
# Delete queued posts and refund their post quota (up to 100)
|
|
501
|
+
superx scheduled:bulk-delete --ids abc,def
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
- All three touch **queued posts only**. Drafts, sent posts and error rows are counted in `skipped` and are never retimed or deleted, so `updated` / `deleted` can be lower than the number of ids you sent. Delete a draft with `scheduled:delete <id>`.
|
|
505
|
+
- `bulk-auto-retweet` never overwrites a post's existing auto retweet; those posts land in `skipped`.
|
|
506
|
+
- GOTCHA: posts you create through the CLI inherit the account's Default Post Settings, so if Auto Retweet is on there they ALREADY have one and `bulk-auto-retweet` reports every id as `skipped`. Create them with `--no-auto-retweet`, or clear it per post with `scheduled:update <id> --no-auto-retweet`, before bulk-applying a different one.
|
|
507
|
+
- Each `scheduled_for` follows the normal window: at least 60 seconds ahead, within 18 months.
|
|
508
|
+
- The responses are COUNTS, not per-post results. Re-read with `scheduled:list` to see the new state.
|
|
509
|
+
- No idempotency key: re-running the same call converges (a retime to the same time is a no-op, an already-deleted id is skipped).
|
|
510
|
+
|
|
232
511
|
### Editing drafts and scheduled posts
|
|
233
512
|
|
|
234
513
|
```bash
|
|
@@ -244,7 +523,7 @@ superx scheduled:update <post-id> --clear-tags --clear-title --clear-scratchpad
|
|
|
244
523
|
- A new `--at` alone never schedules a draft. Promotion is always explicit via `--status scheduled` (which needs a future time, provided or already set).
|
|
245
524
|
- CAUTION: replacement text is a FULL replace, media included. `--text` without `--media` REMOVES any images the post carried; re-list the current `object_key`s (visible in `scheduled:list`) to keep them. Title, scratchpad, tag, and time edits never touch media.
|
|
246
525
|
|
|
247
|
-
### Advanced settings (auto retweet, auto delete, auto plug, super followers)
|
|
526
|
+
### Advanced settings (auto retweet, auto delete, auto plug, auto DM, super followers)
|
|
248
527
|
|
|
249
528
|
```bash
|
|
250
529
|
# Explicit values on create
|
|
@@ -264,17 +543,41 @@ superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
|
264
543
|
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
265
544
|
--no-auto-retweet --no-auto-plug
|
|
266
545
|
|
|
546
|
+
# Auto DM the people who engage with the post once it is live
|
|
547
|
+
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
548
|
+
--auto-dm-message "Hey [first], here is the template I mentioned" \
|
|
549
|
+
--auto-dm-triggers reply,repost --auto-dm-max 50
|
|
550
|
+
|
|
267
551
|
# Edit or remove on an existing post (no inheritance on update)
|
|
268
552
|
superx scheduled:update <post-id> --auto-retweet 2
|
|
269
553
|
superx scheduled:update <post-id> --no-auto-delete
|
|
554
|
+
superx scheduled:update <post-id> --no-auto-dm # also gives back the month's slot
|
|
270
555
|
```
|
|
271
556
|
|
|
272
557
|
- On `scheduled:create`, flags you OMIT inherit the user's Default Post Settings from the SuperX app; that is the expected behavior, not a bug. Exactly five settings inherit (auto retweet, auto delete, auto plug, auto DM, Super Followers only); other composer defaults like Bluesky cross-posting never apply to API posts. Use the `--no-*` forms to turn a default off for one post.
|
|
273
558
|
- On `scheduled:update` there is no inheritance: passed flags override, omitted flags keep the post's current settings, `--no-*` removes them.
|
|
274
559
|
- Hours are 1-12. `--auto-plug` needs `--auto-plug-threshold` (likes); template ids come from `plug-templates:list`, unknown ids fail with `unknown_plug_template`. `--super-followers` / `--no-super-followers` toggle Super Followers only.
|
|
275
|
-
- Auto DM
|
|
560
|
+
- Auto DM: `--auto-dm-message` (1-1000, `[name]` / `[first]` / `[handle]` are filled per recipient) arms it, with optional `--auto-dm-triggers reply,repost` (default reply only), `--auto-dm-max` 1-100 and `--auto-dm-batch`. `--no-auto-dm` turns it off for the post. Omitted, it follows the user's app defaults. The plan caps how many posts a month may carry one (`dm:limits` -> `posts_with_auto_dm`): when that cap strips it the post is still created and the response carries `"auto_dm_skipped": true`, so relay that instead of ignoring it. Reading a post back never shows the DM text, only that one is attached.
|
|
276
561
|
- `scheduled:list` shows the applied settings per post (`auto_retweet`, `auto_delete`, `auto_plug`, `auto_dm`, `super_followers_only`), so you can verify what a post will actually do.
|
|
277
562
|
|
|
563
|
+
### DM campaigns (queue only; the app sends)
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
superx dm:limits # allowances before you queue anything
|
|
567
|
+
superx dm:campaign --recipients people.json --message "Hey [first], loved your thread"
|
|
568
|
+
superx dm:campaign --recipients=- --message "..." --spread # recipients from stdin
|
|
569
|
+
superx dm:campaign-status <campaign-id> # counts per status + the messages
|
|
570
|
+
superx dm:queue --status pending # everything still waiting to go out
|
|
571
|
+
superx dm:cancel <campaign-id> # remove the unsent ones
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
- **Nothing is sent by these commands.** `dm:campaign` puts messages into the account's own DM queue and the SuperX app's scheduler sends them within the account's daily and monthly limits. The reply is COUNTS (`queued`, `queued_now`, `scheduled`, `skipped`, `duplicates`), never deliveries, so never tell the user their messages went out: point them at `dm:campaign-status`.
|
|
575
|
+
- The user is responsible for these messages under X's automation rules. Confirm the recipient list and the exact text with them before queueing, and do not queue a campaign they did not ask for.
|
|
576
|
+
- `--recipients` takes a JSON file (or `--recipients=-` for stdin; the `=` is required) of `[{ "x_user_id", "handle"?, "name"?, "message"?, "source_post_id"? }]`, up to 100 people. Ids come from `signals:leads`, `datasets:rows` or `lists:members`. A recipient's own `message` overrides the shared one. `[name]`, `[first]` and `[handle]` are filled per person.
|
|
577
|
+
- People this account messaged in the last 24 hours are skipped and counted in `duplicates`, and the account never messages itself. `--spread` places whatever today's daily allowance cannot hold over the coming days instead of skipping it.
|
|
578
|
+
- `dm:cancel` deletes the campaign's UNSENT rows, queued-for-now and scheduled-for-later alike, and gives the monthly commitment back. Sent messages cannot be recalled and one already going out cannot be stopped.
|
|
579
|
+
- Costs no AI credits. Refusals come back as `dm_limit_reached` with `scope` `month` or `day`, `dm_not_in_plan` when the plan has no DM allowance, and `reauth_required` when the X account needs reconnecting in the app.
|
|
580
|
+
|
|
278
581
|
### Tags
|
|
279
582
|
|
|
280
583
|
```bash
|
|
@@ -308,12 +611,20 @@ superx context:products
|
|
|
308
611
|
superx context:products:set --url "https://superx.so" --name "SuperX" --description "X growth platform"
|
|
309
612
|
superx context:products:set --id 3 --updates "Shipped the public API"
|
|
310
613
|
superx context:products:delete <product-id>
|
|
614
|
+
superx context:products:replace --json '[{"url":"https://superx.so","name":"SuperX"}]' # FULL REPLACE
|
|
615
|
+
|
|
616
|
+
# Free helpers (no AI credits)
|
|
617
|
+
superx context:regenerate-style-guide # rebuild the generated guide; once an hour
|
|
618
|
+
superx context:scrape-product <product-id> # re-read that product's page and refresh it
|
|
311
619
|
```
|
|
312
620
|
|
|
313
621
|
- What each setting affects: `--profile-description` grounds the AI's voice and personalizes the daily content mix and search; `--rules` are mandatory instructions on EVERY AI surface; `--reply-rules` and `--reply-author-name` steer generated replies; `--favorite-creators` (X usernames, max 3) inspire the writing style; `--interests` are the highest-priority topics for content suggestions; `--style-audience`/`--style-vocabulary` outrank the app's generated style guide until cleared.
|
|
314
622
|
- `context:get` also returns the read-only generated style guide (`style_guide.generated`) so you can see what a cleared override falls back to.
|
|
623
|
+
- `context:regenerate-style-guide` rewrites that generated guide from the account's recent posts. Free, once an hour per account (429 `ai_action_limited`, `scope: "account"`, `reset_at` an hour after the last run), and it takes up to a minute. It does NOT touch `--style-audience` / `--style-vocabulary`, which keep outranking it, so a user who set overrides sees no change in output until they clear them. An account with fewer than 5 recent posts stored has them read live: that leg allows 3 attempts a day and also draws on the shared platform ceiling (both 429 `ai_action_limited`, `scope` `account` and `platform` respectively), and still too few posts returns 400 `not_enough_posts`. Shared accounts refuse it.
|
|
624
|
+
- `context:scrape-product <id>` re-reads a product's page and refreshes its stored name, description and details. The url comes from the SAVED product, so fix a moved url with `context:products:set --id` first. Free, on the account's 20 page reads a day shared with the app; a page that cannot be read returns 422 `scrape_failed`.
|
|
315
625
|
- Caps: profile description 500, rules 500, reply rules 500, style audience 600, style vocabulary 1000 characters; 30 interests of 50 characters each; 3 favorite creators; 5 products.
|
|
316
626
|
- `context:products:set --url` creates the product when it does not exist. Removing a product is reversible: re-adding the same url restores its scraped details.
|
|
627
|
+
- `context:products:replace` REPLACES the whole product list: any product whose url is missing from the array is removed. Read `context:products` first and send every product the user should keep, or use `context:products:set` to change one in place. `'[]'` removes every product.
|
|
317
628
|
- Writes need a key with the write scope. Unlike scheduling, context writes work on ANY linked or shared account via `--account` (they are per-account settings). On a share with Editor permission they return 403 `editor_restricted`: only the account owner can change these. These settings shape ALL future AI output for the account; confirm with the user before changing rules or the profile description.
|
|
318
629
|
|
|
319
630
|
### Queue settings (posting schedule)
|
|
@@ -359,14 +670,18 @@ superx articles:unschedule <article-id> # back to draft, quota refunds
|
|
|
359
670
|
superx articles:publish <article-id> # LIVE NOW, irreversible, needs X Premium
|
|
360
671
|
superx articles:delete <article-id>
|
|
361
672
|
|
|
362
|
-
# AI cover (60-100s,
|
|
673
|
+
# AI cover (60-100s, a flat 25 AI credits, plus the daily/monthly cover caps)
|
|
674
|
+
superx articles:cover-styles # styles saved in the app, with their ids
|
|
363
675
|
superx articles:cover <article-id>
|
|
676
|
+
superx articles:cover <article-id> --style-id <style-id> # render in a saved style
|
|
364
677
|
superx articles:cover <article-id> --style "dark, minimal, geometric" --no-attach
|
|
365
678
|
```
|
|
366
679
|
|
|
367
680
|
- Publishing and scheduling spend post quota; the article needs a title and some content first.
|
|
368
681
|
- X enforces its own article limits (10 drafts/day, 5 publishes/day) and requires X Premium; those surface as publish failures.
|
|
369
682
|
- `articles:cover` generates from the article's TITLE. Attach is the default; `--no-attach` keeps the current cover and you can attach later with `articles:update --cover-url`.
|
|
683
|
+
- Steer the look with `--style-id` (one of the styles the user saved in the app, listed by `articles:cover-styles`) or `--style` (a one-off description), never both: passing both is a 400. An unknown style id is a 404 `cover_style_not_found`. Styles are saved and deleted in the app.
|
|
684
|
+
- A cover generation costs a FLAT 25 AI credits on the API, whatever the render actually costs, and the response reports `meta.credits_charged`. A generation that fails outright is refunded in full; one that TIMES OUT keeps the charge because the cover may still have landed, so run `articles:get` and look at the cover before retrying.
|
|
370
685
|
- A publish timeout is AMBIGUOUS: run `articles:get` and check `status` before retrying.
|
|
371
686
|
|
|
372
687
|
### Docs
|
|
@@ -425,7 +740,7 @@ for attempt in 1 2 3; do
|
|
|
425
740
|
done
|
|
426
741
|
```
|
|
427
742
|
|
|
428
|
-
Rate limits per
|
|
743
|
+
Rate limits are per account owner and scale with the plan: reads, writes, enrichment and feed fetches each have their own per-minute and per-day windows, and media uploads are capped at 100 per key per day. Every authenticated response carries `X-RateLimit-*` headers; `superx status` shows the current window and the AI credit pool. On 429 the stderr message includes the retry delay. Current numbers: https://docs.superx.so/rate-limits
|
|
429
744
|
|
|
430
745
|
### Pattern 5: Batch a week of content
|
|
431
746
|
|
|
@@ -441,12 +756,60 @@ superx scheduled:list --status scheduled
|
|
|
441
756
|
|
|
442
757
|
---
|
|
443
758
|
|
|
759
|
+
## Playbooks
|
|
760
|
+
|
|
761
|
+
Full recipes with flags and MCP tool chains: [PLAYBOOKS.md](./PLAYBOOKS.md). Pick by goal, then open that entry.
|
|
762
|
+
|
|
763
|
+
### Recaps and analytics
|
|
764
|
+
- **Weekly Growth Recap**: the week in review, one focus for next week. `posts:analytics` -> `posts:list` -> `signals:leads` -> `replies:received`
|
|
765
|
+
- **Growth Plan Builder**: multi-week plan tied to real numbers. `posts:analytics` -> `posts:list` -> `replies:list` -> `queue:get`
|
|
766
|
+
- **Post Post-Mortem**: why one post over- or underperformed. `posts:list` -> `posts:analytics` -> `x:user-posts`
|
|
767
|
+
- **Top Performers Breakdown**: the shape the best posts share. `posts:list` -> `posts:analytics`
|
|
768
|
+
- **My Replies Report**: which replies earned attention. `replies:list`
|
|
769
|
+
|
|
770
|
+
### Content
|
|
771
|
+
- **Daily Post Ideas**: two or three drafts for today. `scheduled:list` -> `posts:list` -> `posts:draft` -> `scheduled:create`
|
|
772
|
+
- **Week of Posts**: a week of drafts on the real slots. `posts:list` -> `queue:get` -> `posts:draft` -> `scheduled:create`
|
|
773
|
+
- **Thread Builder**: notes turned into a thread draft. `posts:draft` -> `scheduled:create`
|
|
774
|
+
- **Repurpose a Winner**: the best post, reworked. `posts:list` -> `posts:remix` -> `scheduled:create`
|
|
775
|
+
- **Viral Format Remix**: proven shapes in this account's voice. `inspiration:search` -> `posts:draft` -> `scheduled:create`
|
|
776
|
+
- **Trending Now Scan**: what is working in the niche now. `inspiration:search`
|
|
777
|
+
|
|
778
|
+
### Queue
|
|
779
|
+
- **Cadence & Queue Audit**: gaps, pile-ups, a cadence verdict. `queue:get` -> `scheduled:list` -> `posts:list` -> `scheduled:update`
|
|
780
|
+
- **Queue Reshuffle**: move and rewrite queued posts. `scheduled:list` -> `scheduled:bulk-retime` -> `scheduled:update`
|
|
781
|
+
|
|
782
|
+
### Replies (stop at a draft, by design)
|
|
783
|
+
- **Reply Sprint**: five audience replies, each with a draft. `replies:received` -> `engage:reply-draft`
|
|
784
|
+
- **Reply to Any Post**: context plus one strong reply draft. `x:post` -> `x:replies` -> `engage:reply-draft`
|
|
785
|
+
|
|
786
|
+
### Leads
|
|
787
|
+
- **Who Is This Person?**: a fast read plus your history. `x:user` -> `x:user-posts` -> `contacts:get` -> `contacts:replies`
|
|
788
|
+
- **Your Warmest Leads**: the people engaging most, ranked. `contacts:list` -> `contacts:replies`
|
|
789
|
+
- **Instant Lead Hunt**: live search for matching people now. `signals:suggest-keywords` -> `signals:search`
|
|
790
|
+
- **Standing Lead Agent**: an agent that keeps finding leads. `signals:expand-icp` -> `signals:create-agent` -> `signals:leads`
|
|
791
|
+
- **Lead Review**: found leads, prioritized and checked. `signals:agents` -> `signals:leads` -> `x:user-posts` -> `signals:feedback`
|
|
792
|
+
|
|
793
|
+
### Audiences, research and DMs
|
|
794
|
+
- **Profile Research Briefs**: structured briefs plus a CSV. `datasets:research` -> `datasets:rows` -> `datasets:export`
|
|
795
|
+
- **DM-Ready Audience Builder**: a clean DM-able audience. `datasets:collect` -> `datasets:get` -> `datasets:add-to-list`
|
|
796
|
+
- **Sentiment Slice**: keep only the people who said it. `datasets:list` -> `datasets:refine` -> `datasets:rows`
|
|
797
|
+
- **Audience Export**: everyone who engaged a post, as CSV. `datasets:collect` -> `datasets:export`
|
|
798
|
+
- **My Content Export**: your own posts or replies, as CSV. `datasets:collect` -> `datasets:export`
|
|
799
|
+
- **Warm Outreach Pipeline**: briefs, a message each, queued. `datasets:research` -> `datasets:outreach-drafts` -> `dm:campaign`
|
|
800
|
+
- **Reply-to-DM Campaign**: DM the people who replied. `datasets:collect` -> `datasets:refine` -> `dm:campaign`
|
|
801
|
+
|
|
802
|
+
### Settings
|
|
803
|
+
- **Teach SuperX Your Rules**: standing rules for AI drafts. `context:get` -> `context:set`
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
444
807
|
## Common Gotchas
|
|
445
808
|
|
|
446
809
|
1. **Naive timestamps are rejected (400)**. Always include `Z` or an offset: `2026-08-01T15:00:00Z`, not `2026-08-01T15:00:00`.
|
|
447
810
|
2. **Schedule window**: `--at` must be at least 60 seconds in the future and within 18 months.
|
|
448
811
|
3. **Read-only keys cannot write**: `scheduled:create`/`scheduled:delete` with a read-only key returns 403 `insufficient_scope`. Check `superx me` for the key's scopes.
|
|
449
|
-
4. **
|
|
812
|
+
4. **Shared accounts are read-only for writes**: writes work on your main account or any linked account (pass the same `--account` you used to read it). Accounts shared with you by other people return 403 `writes_main_account_only` for post, article, signal and contact-list member writes. `context:*` and `queue:set` are per-account settings that do accept a shared account.
|
|
450
813
|
5. **Images need an upload first**: `--media` takes `object_key`s from `media:upload`, never file paths or URLs. Unknown keys return 400 `invalid_media`; a presign whose bytes were never PUT returns 400 `media_not_uploaded`. Video is not supported.
|
|
451
814
|
6. **Size caps**: max 25 thread parts, 25,000 characters total.
|
|
452
815
|
7. **Rate limited (429)**: `rate_limited` on stderr with a retry delay. Back off; do not hammer.
|
|
@@ -471,6 +834,33 @@ superx scheduled:list --status scheduled
|
|
|
471
834
|
26. **`context:set` list flags REPLACE the stored list**: `--interests` and `--favorite-creators` overwrite what is there; include every value the user should keep. `""` on a string flag clears it (style-guide overrides then revert to the generated guide). These settings steer all future AI output; confirm with the user before changing them.
|
|
472
835
|
27. **`queue:set --slots-json` REPLACES the whole schedule** and re-flows queued posts onto the new slots. Read the current slots with `queue:get` first and send the full set. `'[]'` clears every slot and leaves the queue all-custom. `reflow.bailed: true` means the settings saved but no post moved.
|
|
473
836
|
28. **`editor_restricted` (403)**: the account is shared with the key owner with Editor permission. Editors can change queue settings but not context settings. Only the account owner can.
|
|
837
|
+
29. **`lists:add-members` takes ids SuperX already knows**: it does no live lookup, so any id in the response's `not_found` was never added. Add those with `lists:add-member --handle <handle>` one at a time (that path resolves live and costs an enrichment unit).
|
|
838
|
+
30. **`contacts:get` and `contacts:notes:add` are known-contacts only**: they resolve engagers, contact-list members and scored signal leads, and 404 `contact_not_found` on any other id, including ids SuperX has a profile for. Get ids from `contacts:list`, `lists:members` or `signals:leads`; there is no general profile lookup yet. `contacts:notes`, `contacts:notes:update` and `contacts:notes:delete` are NOT restricted: they work on any id you already have a note on, so notes stay reachable after someone drops out of your contacts.
|
|
839
|
+
31. **Notes written through the API are attributed to the acting account**, not to a separate API identity: `created_by` on a note is the account named by `--account` (your main account when omitted). A note id from a different contact returns 404 `note_not_found`.
|
|
840
|
+
32. **`context:products:replace` REPLACES the whole product list**: products whose url is missing from `--json` are removed. Read `context:products` first, or use `context:products:set` for a single-product edit.
|
|
841
|
+
33. **`posts:publish` is irreversible and needs `--idempotency-key`**: it posts to X immediately. Confirm the exact text with the user first. Without the key the command exits 1; on a timeout retry with the SAME key (409 `idempotency_in_flight` means the first attempt is still running, so wait for the `Retry-After` delay and retry that same key again). `--at`, `--title` and `--scratchpad` are rejected.
|
|
842
|
+
34. **The bulk commands only touch QUEUED posts**: `scheduled:bulk-retime`, `scheduled:bulk-auto-retweet` and `scheduled:bulk-delete` skip drafts, sent posts and error rows, and `bulk-auto-retweet` also skips posts that already have an auto retweet. They answer with counts, so compare against `scheduled:list` rather than assuming every id was applied.
|
|
843
|
+
35. **`replies:list` page 1 can carry `metrics_pending` items**: replies sent from the SuperX app in the last 4 hours are merged in with zero metrics until X reports them, so page 1 can hold slightly more items than `--limit`. Later pages and `--since`/`--until` queries never include them.
|
|
844
|
+
36. **`engage:posts --limit` is keyword-feeds only**: list feeds return one page of about 10 to 25 posts per fetch, so page them with `--exclude` (the ids you already have, at most 100 per call), not a bigger `--limit`. Each plan also has a daily feed-fetch allowance (separate from reads) and a list feed that rotates its members counts as 3 fetches, so fetch big pages a few times a day rather than polling. Posts a fetch returns count as seen and are demoted in later fetches, in the app as well as here.
|
|
845
|
+
37. **A feed you create is not the feed the app has open**: `engage:feeds:create` saves the feed but never switches the person's view. Tell them where to find it. The cap is 8 feeds (409 `feed_limit_reached`), `engage:feeds:update` takes one source at a time, and deleting the open feed hands the slot to the first remaining one.
|
|
846
|
+
38. **An X list feed or signal costs enrichment and needs a PUBLIC list**: `engage:feeds:create --x-list`, `engage:feeds:update --x-list` and `signals:add-signal --type list_watch` each spend one enrichment unit and 404 `x_list_not_found` on a private or deleted list. Keyword and contact-list sources cost none.
|
|
847
|
+
39. **`signals:create-agent` is partial success**: entries that fail come back in `warnings` with a `code`, and the agent is still created from the ones that landed. Read `warnings` before telling the user what the agent watches; re-add fixed entries with `signals:add-signal`.
|
|
848
|
+
40. **`signals:feedback` takes the numeric LEAD id from `signals:leads`, not an X user id**, and it trains the scorer. Ask the user for the verdict rather than inferring one. An id from another account returns 404 `lead_not_found`; a repeated `signals:remove-signal` returns 404 `signal_not_found`.
|
|
849
|
+
41. **`articles:cover --style-id` and `--style` are mutually exclusive** (400 if both are sent). Style ids come from `articles:cover-styles`; an unknown one returns 404 `cover_style_not_found`.
|
|
850
|
+
42. **A dataset has to be `ready` before you read its rows, export it or add it to a list.** Poll `datasets:get <id>` until `status` is `ready`; anything else returns 409 `dataset_not_ready`, and a `failed` dataset has to be rebuilt in the SuperX app. Datasets expire after 30 days, after which the id 404s.
|
|
851
|
+
43. **`datasets:add-to-list` dedupes by person and skips rows without an X account id** (research rows sometimes have none), so `added + duplicates` can be lower than the dataset's `row_count`. `skipped_without_id` counts only the rows with no usable X account id or handle; repeat rows for the same person (a replier who replied twice) are deduped silently and are not counted anywhere. Re-running the same command is safe: people already in the list come back in `duplicates`.
|
|
852
|
+
44. **The `x:*` lookups share a 300/day allowance with Ask SuperX in the app**, on top of the enrichment allowance (1 unit each, 3 for `x:replies`, 2 for `x:post --quotes` or a handle SuperX has never seen). Look up what the user actually asked about; do not sweep an account's network. `429 lookup_quota_exceeded` covers three cases and the body says which: your own allowance is used up (it carries `limit`), the SuperX-wide allowance is used up (no `limit`, not your budget), or the counter could not be verified and the call was refused rather than run unmetered (no `limit`, short `retry_after`). Honour `retry_after` rather than assuming midnight, and report it rather than retrying in a loop. Repeats within 15 minutes come from a server-side cache and do not touch the daily allowance.
|
|
853
|
+
45. **`x:replies` is a sample, not every reply**: the best-liked direct replies from up to 3 relevance-ranked pages, not chronological, and it cannot page further. It also does NOT exclude the account owner's own replies, unlike the same view in the app. Use the audience collections (`datasets:list`) when someone needs everyone who replied. And a `post_not_found` on `x:post` can be a transient upstream failure rather than a deleted post, so retry once before saying it is gone.
|
|
854
|
+
|
|
855
|
+
46. **`audience:list` pages by cursor, not by page number.** Pass `pagination.next_cursor` back as `--cursor`; there is no `--page` and no `total`. Quote `meta.synced_count` for the size of the list, but note it may exceed the rows a full walk returns (edges that were later removed are still counted). Check `meta.status`: anything but `complete` means SuperX is still syncing, and `meta.is_capped: true` on the follow lists means it is the most recent slice, not everyone. `meta.account_id` is the account id you pass to `--account`; the X user id is `meta.x_account_id`. Repliers and reposters only cover a rolling 90 days.
|
|
856
|
+
47. **`engage:mentions` costs 3 feed fetches per call and shows more than the app.** It draws on the same daily feed allowance as `engage:posts`, so read one page and work from it rather than polling. It does NOT apply the skipped/blocked filtering the app's Mentions tab does (that lives with the app), and by default it leaves out mentions already replied to on X unless you pass `--include-replied true`.
|
|
857
|
+
48. **`datasets:collect` can return before the collection is done.** `status: "collecting"` means zero rows so far and work still running: use `--wait`, or poll `datasets:get` until `ready`, and never state a row count from the create result. A collection whose size cannot be established up front also runs in the background. It costs one of 10 collections a day shared with Ask SuperX in the app, only one runs per account at a time (409 `collection_in_progress`), and an empty result creates no dataset at all (`data: null` plus a `note`) and gives the daily slot back.
|
|
858
|
+
49. **Nothing in the outreach chain sends a DM.** `datasets:outreach-drafts` writes message TEXT onto a research dataset and stops there; a person reviews and sends them from the SuperX app. Never say messages were sent and never offer to send them. If the user explicitly asks, you may QUEUE them with `dm:campaign` (one recipient entry per person, each with its own `message`), which is still an enqueue: the app sends. Ask the user for the `--format`; never invent one. Re-running overwrites every draft, `generic` counts messages written with no personal claims (that brief had no usable hook), and `contaminated` counts drafts discarded for naming a different recipient - run it again to retry those rows.
|
|
859
|
+
50. **`signals:search` saves nothing and `datasets:research` charges per profile.** A search creates no agent and no stored leads, so keep what the user needs from that response; use `signals:create-agent` when they want leads to keep arriving. Research is a flat 1 credit per profile ACTUALLY researched (handles that cannot be resolved, and people with no recent posts, come back in `skipped` and are refunded), and over 5 profiles it runs in the background: never state a brief count from a `collecting` result. `datasets:refine` also creates a dataset, so it spends one of the same 10 collections a day.
|
|
860
|
+
51. **`ai_action_limited` has two scopes.** Read `error.scope` before telling the user anything: `"account"` is their plan's own daily cap for that action, `"platform"` is a fair-use ceiling on live-data actions shared by every SuperX account. On `"platform"` their own allowance is untouched, so wait for `reset_at` and retry rather than reporting them as out of quota.
|
|
861
|
+
52. **The writing helpers draft, they never publish.** `engage:reply-draft`, `posts:remix`, `tools:inline-edit`, `tools:rephrase`, `tools:factcheck` and `tools:predict` all return TEXT and stop there - nothing is posted, scheduled or sent. Show the output, let the user edit it, and use `posts:draft`, `scheduled:create` or `posts:publish` when they say so. A `tools:factcheck` verdict is a model reading two search results: report it with its sources, never as settled fact.
|
|
862
|
+
53. **The free helpers cost nothing but are not unlimited.** `context:regenerate-style-guide` is once an hour per account and does not override a manual style-guide setting; `context:scrape-product` and `signals:expand-icp --url` share 20 page reads a day with the SuperX app, and `--url` also inherits the app's limit of 10 prefills per 10 minutes (that one comes back as `rate_limited` and clears in about a minute, so retry rather than reporting a daily budget); `signals:suggest-keywords` and `signals:expand-icp --text` have no ceiling of their own, so do not loop them - each one is a model call. All five send `X-Credits-Remaining` but no `X-Credits-Charged`, because nothing was charged. All four commands still need a key with the write scope: they are POSTs, and every non-GET API route needs it.
|
|
863
|
+
54. **A DM campaign is an ENQUEUE, not a send.** `dm:campaign` returns counts of what was QUEUED; the SuperX app's scheduler sends them later, within the account's daily and monthly DM limits, so never report messages as delivered from that response - `dm:campaign-status` and `dm:queue` show what actually went out. Confirm the recipient list and the exact text with the user first: they are responsible for these messages under X's automation rules. Cancel the unsent ones with `dm:cancel`; anything already sent cannot be recalled.
|
|
474
864
|
|
|
475
865
|
---
|
|
476
866
|
|
|
@@ -494,25 +884,69 @@ superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"
|
|
|
494
884
|
superx posts:analytics --since "2026-06-01T00:00:00Z"
|
|
495
885
|
superx replies:list --limit 20
|
|
496
886
|
superx inspiration:search "build in public" --sort outlier --limit 10
|
|
887
|
+
superx inspiration:media "founder morning routine" --limit 10 # cross-platform media index (--limit up to 120, no paging)
|
|
497
888
|
superx contacts:list --sort engagement --limit 20
|
|
498
889
|
superx contacts:replies <id> --sort most_liked
|
|
890
|
+
superx contacts:get <x-user-id>
|
|
891
|
+
superx contacts:notes <x-user-id>
|
|
499
892
|
superx replies:received --sort most_liked --limit 20
|
|
500
893
|
superx lists:list
|
|
501
894
|
superx lists:members <list-id> --q "founder"
|
|
895
|
+
superx audience:list followers --limit 100 # system lists: cursor paging, no --page
|
|
896
|
+
superx engage:mentions --sort top # live @-mentions (costs 3 feed fetches)
|
|
897
|
+
superx signals:search --keywords "..." --icp "..." # live lead search, saves nothing
|
|
502
898
|
superx signals:agents
|
|
503
899
|
superx signals:leads --agent 3 --deposited false
|
|
504
|
-
|
|
505
|
-
|
|
900
|
+
superx engage:feeds
|
|
901
|
+
superx engage:posts <feed-id> --limit 50
|
|
902
|
+
superx datasets:list
|
|
903
|
+
superx datasets:get <dataset-id>
|
|
904
|
+
superx datasets:rows <dataset-id> --limit 50
|
|
905
|
+
superx datasets:export <dataset-id> # CSV file here; --out - streams to stdout
|
|
906
|
+
superx datasets:collect --source repliers --target <post-url> --wait # build one, poll until ready
|
|
907
|
+
superx datasets:refine <dataset-id> --criterion "..." --wait # filter by what each person wrote
|
|
908
|
+
superx datasets:research --handles a,b,c --wait # briefs, 1 credit per profile
|
|
909
|
+
superx datasets:outreach-drafts <dataset-id> --format "..." # message TEXT only, nothing sent
|
|
910
|
+
|
|
911
|
+
# Live X lookups (enrichment units + a shared 300/day allowance)
|
|
912
|
+
superx x:post <id-or-url> # one public post, live (--quotes for quotes)
|
|
913
|
+
superx x:replies <id-or-url> --limit 20 # best-liked direct replies (a sample)
|
|
914
|
+
superx x:user <handle> # one public profile, live
|
|
915
|
+
superx x:user-posts <handle> --no-reposts # one live page of their latest posts
|
|
916
|
+
|
|
917
|
+
# Contact writes (main or linked account)
|
|
918
|
+
superx contacts:notes:add <x-user-id> --body "..." # Private note, never posted
|
|
919
|
+
superx contacts:notes:update <x-user-id> <note-id> --body "..."
|
|
920
|
+
superx contacts:notes:delete <x-user-id> <note-id>
|
|
921
|
+
|
|
922
|
+
# Contact list writes (main or linked account)
|
|
506
923
|
superx lists:add-member <list-id> --handle levelsio
|
|
507
924
|
superx lists:remove-member <list-id> <member-id>
|
|
508
|
-
|
|
509
|
-
|
|
925
|
+
superx lists:create --name "Founder prospects"
|
|
926
|
+
superx lists:rename <list-id> --name "Q4 prospects"
|
|
927
|
+
superx lists:delete <list-id> # List + membership; the people stay
|
|
928
|
+
superx lists:add-members <list-id> --x-user-ids 44196397,944883311 # <=500, ids SuperX knows
|
|
929
|
+
superx lists:remove-members <list-id> --member-ids m1abc,m2def # <=500
|
|
930
|
+
superx datasets:add-to-list <dataset-id> --list-id <list-id> # people from a ready dataset
|
|
931
|
+
|
|
932
|
+
# Engage feed writes (main or linked account)
|
|
933
|
+
superx engage:feeds:create --name "AI builders" --keyword "shipping with LLMs"
|
|
934
|
+
superx engage:feeds:create --name "Founders" --x-list https://x.com/i/lists/1234567890
|
|
935
|
+
superx engage:feeds:update <feed-id> --name "AI builders v2"
|
|
936
|
+
superx engage:feeds:delete <feed-id>
|
|
937
|
+
|
|
938
|
+
# Signal agent writes (main or linked account)
|
|
510
939
|
superx signals:create-agent --name "..." --icp "..." --keyword "..." # Lead finder
|
|
940
|
+
superx signals:create-agent --name "..." --icp "..." --signal "profile:@naval"
|
|
941
|
+
superx signals:update-agent <id> --icp "..." --list-id <contact-list-id>
|
|
942
|
+
superx signals:add-signal <id> --type follower_watch --handle naval
|
|
943
|
+
superx signals:remove-signal <id> <signal-id>
|
|
944
|
+
superx signals:feedback <lead-id> --fit # or --not-fit / --clear
|
|
511
945
|
superx signals:pause-agent <id>
|
|
512
946
|
superx signals:resume-agent <id>
|
|
513
947
|
superx signals:delete-agent <id>
|
|
514
948
|
|
|
515
|
-
# Writes (main account
|
|
949
|
+
# Writes (main or linked account via --account)
|
|
516
950
|
superx scheduled:create --text "Post" # Draft
|
|
517
951
|
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" # Scheduled
|
|
518
952
|
superx scheduled:create --part "1/" --part "2/" --at "..." # Thread
|
|
@@ -526,6 +960,36 @@ superx scheduled:list --status draft,scheduled
|
|
|
526
960
|
superx scheduled:list --tags <tag-id>
|
|
527
961
|
superx scheduled:delete <id>
|
|
528
962
|
|
|
963
|
+
# Publish NOW (irreversible; key required, reuse it on a retry)
|
|
964
|
+
superx posts:publish --text "Post" --idempotency-key k1
|
|
965
|
+
|
|
966
|
+
# Writing helpers (text in, text out; nothing is posted)
|
|
967
|
+
superx engage:reply-draft --post <id> --thoughts "..." --tone concise
|
|
968
|
+
superx posts:remix --text "..." --closeness 70
|
|
969
|
+
superx tools:inline-edit --text "..." --full "..." --type hook
|
|
970
|
+
superx tools:rephrase --type concise --text "..."
|
|
971
|
+
superx tools:factcheck --text "..."
|
|
972
|
+
superx tools:predict --a "..." --b "..."
|
|
973
|
+
|
|
974
|
+
# DM campaigns (queued only; the SuperX app sends them)
|
|
975
|
+
superx dm:limits
|
|
976
|
+
superx dm:campaign --recipients people.json --message "Hey [first], ..."
|
|
977
|
+
superx dm:campaign-status <campaign-id>
|
|
978
|
+
superx dm:queue --status pending
|
|
979
|
+
superx dm:cancel <campaign-id>
|
|
980
|
+
|
|
981
|
+
# Free helpers (no AI credits)
|
|
982
|
+
superx context:regenerate-style-guide
|
|
983
|
+
superx context:scrape-product <product-id>
|
|
984
|
+
superx signals:suggest-keywords --icp "B2B SaaS founders worried about churn"
|
|
985
|
+
superx signals:expand-icp --text "Indie founders building SaaS in public"
|
|
986
|
+
superx signals:expand-icp --url superx.so
|
|
987
|
+
|
|
988
|
+
# Bulk queue operations (queued posts only; answers are counts)
|
|
989
|
+
superx scheduled:bulk-retime --moves-json '[{"id":"abc","scheduled_for":"2026-09-08T15:00:00Z"}]'
|
|
990
|
+
superx scheduled:bulk-auto-retweet --ids abc,def --auto-retweet 6
|
|
991
|
+
superx scheduled:bulk-delete --ids abc,def
|
|
992
|
+
|
|
529
993
|
# Tags
|
|
530
994
|
superx tags:list
|
|
531
995
|
superx tags:create "Launch week" --color amber
|
|
@@ -540,7 +1004,9 @@ superx articles:update <id> --file v2.md
|
|
|
540
1004
|
superx articles:schedule <id> --at "2026-08-01T15:00:00Z"
|
|
541
1005
|
superx articles:unschedule <id>
|
|
542
1006
|
superx articles:publish <id>
|
|
1007
|
+
superx articles:cover-styles
|
|
543
1008
|
superx articles:cover <id> --style "minimal"
|
|
1009
|
+
superx articles:cover <id> --style-id <style-id>
|
|
544
1010
|
superx articles:delete <id>
|
|
545
1011
|
|
|
546
1012
|
# Context settings (AI writing background)
|
|
@@ -550,6 +1016,7 @@ superx context:set --interests "indie hacking,SaaS" # replaces the list
|
|
|
550
1016
|
superx context:products
|
|
551
1017
|
superx context:products:set --url "https://superx.so" --name "SuperX"
|
|
552
1018
|
superx context:products:delete <id>
|
|
1019
|
+
superx context:products:replace --json '[{"url":"https://superx.so"}]' # FULL REPLACE
|
|
553
1020
|
|
|
554
1021
|
# Queue settings (posting schedule; 0 = Sunday)
|
|
555
1022
|
superx queue:get
|
|
@@ -562,4 +1029,4 @@ superx --help # All commands
|
|
|
562
1029
|
superx scheduled:create --help # Command help
|
|
563
1030
|
```
|
|
564
1031
|
|
|
565
|
-
Strategy lives in [PLAYBOOK.md](./PLAYBOOK.md). Read it before creating content (Rule 2).
|
|
1032
|
+
Strategy lives in [PLAYBOOK.md](./PLAYBOOK.md). Read it before creating content (Rule 2). Goal-shaped recipes live in [PLAYBOOKS.md](./PLAYBOOKS.md): open the entry that matches what the user asked for.
|