superx-cli 0.3.0 → 0.5.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 +1 -1
- package/PLAYBOOKS.md +542 -0
- package/README.md +2 -3
- package/SKILL.md +485 -16
- package/dist/index.js +1857 -30
- 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,
|
|
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 29 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 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. `
|
|
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. `--voice mine` is the voice of the `--account` you pass (its own posts and style guide); shared accounts are refused.
|
|
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
|
```
|
|
@@ -135,6 +135,40 @@ superx inspiration:search "AI tools" --min-likes 500 --min-followers 1000 --max-
|
|
|
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
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
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.
|
|
171
|
+
|
|
138
172
|
### Contacts (who engages with you)
|
|
139
173
|
|
|
140
174
|
```bash
|
|
@@ -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,10 +204,88 @@ 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
209
|
- Member writes work on your main or linked accounts (`--account`) and need a key with the write scope; shared accounts are read-only.
|
|
161
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
|
+
|
|
162
289
|
### Engage (feed posts to reply to)
|
|
163
290
|
|
|
164
291
|
```bash
|
|
@@ -167,9 +294,20 @@ superx engage:posts <feed-id> --limit 50 # one big page of candidate
|
|
|
167
294
|
superx engage:posts <feed-id> --mode latest --fresh true # newest, skipping the cache
|
|
168
295
|
superx engage:posts <feed-id> --exclude 1234567890,1234567891 # next batch, minus what you have
|
|
169
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>
|
|
170
304
|
```
|
|
171
305
|
|
|
172
|
-
- 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`.
|
|
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.
|
|
173
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.
|
|
174
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.
|
|
175
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`.
|
|
@@ -191,20 +329,124 @@ superx signals:create-agent \
|
|
|
191
329
|
--icp "Indie founders building SaaS in public, sharing MRR and launches" \
|
|
192
330
|
--keyword "building in public" --keyword "just shipped my MVP"
|
|
193
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
|
+
|
|
194
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>
|
|
195
339
|
superx signals:pause-agent 3
|
|
196
340
|
superx signals:resume-agent 3
|
|
197
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
|
|
198
353
|
```
|
|
199
354
|
|
|
200
|
-
- Signal agents are automated lead finders: they watch profiles, followers, keywords, or lists and score people against an ideal customer profile.
|
|
201
|
-
- `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`.
|
|
202
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.
|
|
203
362
|
- Deleting an agent keeps its saved leads and its contact list.
|
|
204
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).
|
|
205
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`.
|
|
206
365
|
- An agent's `destination_list_id` joins to `lists:list` for the target list's name; deposited leads appear there as members.
|
|
207
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
|
+
|
|
427
|
+
### Workers (posts written for you on a schedule)
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
superx workers:list # your Workers, schedules, next run times
|
|
431
|
+
superx workers:suggestions --limit 10 # newest posts waiting for review
|
|
432
|
+
superx workers:suggestions --worker 3 --status all # everything one Worker has written
|
|
433
|
+
superx workers:suggestions --status scheduled # the ones already queued
|
|
434
|
+
|
|
435
|
+
# Act on one (suggestion id from workers:suggestions; write scope)
|
|
436
|
+
superx workers:draft 4821 # save it to Drafts
|
|
437
|
+
superx workers:schedule 4821 --at "2026-09-15T14:00:00Z"
|
|
438
|
+
superx workers:dismiss 4821 # clear it out of To review
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
- A Worker is an agent inside SuperX that writes posts for one account on a schedule. Workers are CREATED, EDITED AND RUN IN THE APP: there is no create or run command here, and no API endpoint for either. This chain reads what they wrote and acts on it.
|
|
442
|
+
- `workers:suggestions` defaults to `--status to_review`, the ones waiting on a person. The other values are `drafted`, `scheduled`, `dismissed` and `all`. `--worker <id>` narrows to one Worker, `--limit` (max 100, default 20) and `--page` walk the list, newest first.
|
|
443
|
+
- Each suggestion carries `id`, `worker_id`, `text`, `status`, `generated_at`, the `drafted_at`/`scheduled_at`/`dismissed_at` stamps, `post_id` once it has been saved, and `reference` (the kind of source the Worker wrote from). The Worker's own collection ids stay private.
|
|
444
|
+
- AI OUTPUT NEEDS A HUMAN: show the user the text and let them edit it before it is saved or queued. `workers:draft` saves it as written, `workers:schedule` queues it as written, and neither asks for confirmation. To change the wording first, rewrite it with `posts:remix` or `tools:rephrase` and save your version with `scheduled:create` instead, then `workers:dismiss` the original so the list stays clean.
|
|
445
|
+
- `workers:schedule` requires `--at` in UTC ISO-8601. The post does NOT inherit the account's Default Post Settings: it carries only what the call passes, which from the CLI is nothing beyond the time, so no auto retweet, auto plug, auto delete or auto DM. Add those afterwards with `scheduled:update`, which is also how you retime it; `scheduled:delete` cancels it.
|
|
446
|
+
- One suggestion can only be saved once. A second `workers:draft` or `workers:schedule` on the same id is a 400, as is acting on a dismissed one. An id belonging to another account's Worker is a 404.
|
|
447
|
+
- `workers:draft` and `workers:schedule` land the post in the same Drafts and Queue the rest of the CLI reads: `scheduled:list --status draft` shows a drafted suggestion, newest first, and the response gives you its `post_id` directly.
|
|
448
|
+
- Endpoints behind these commands: `GET /v1/workers`, `GET /v1/workers/suggestions`, `POST /v1/workers/suggestions/{id}/draft`, `POST /v1/workers/suggestions/{id}/schedule`, `POST /v1/workers/suggestions/{id}/dismiss`. The three POSTs need a key with the **write** scope. Every command here takes `--account` for an account you own (main or linked); an account someone shared with you is read-only, so a write against it returns 403 `writes_main_account_only`.
|
|
449
|
+
|
|
208
450
|
### Scheduling
|
|
209
451
|
|
|
210
452
|
```bash
|
|
@@ -247,6 +489,48 @@ superx scheduled:delete <post-id>
|
|
|
247
489
|
- `scheduled:list` filters: `--status draft,scheduled,sent,error` (comma list), `--tags id,id` (any-of), `--from/--to` bounds on the scheduled time.
|
|
248
490
|
- `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.
|
|
249
491
|
|
|
492
|
+
### Publishing now (irreversible)
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
# Publishes to X the moment this returns. --idempotency-key is REQUIRED.
|
|
496
|
+
superx posts:publish --text "Post text" --idempotency-key "launch-2026-09-07"
|
|
497
|
+
|
|
498
|
+
# Thread, same shape as scheduled:create
|
|
499
|
+
superx posts:publish --part "1/ The hook" --part "2/ The close" --idempotency-key "thread-42"
|
|
500
|
+
|
|
501
|
+
# With an image and an auto retweet
|
|
502
|
+
KEY=$(superx media:upload ./chart.png | jq -r '.object_key')
|
|
503
|
+
superx posts:publish --text "Chart of the week" --media "$KEY" --alt-text "Weekly revenue line chart" \
|
|
504
|
+
--auto-retweet 6 --idempotency-key "chart-2026-09-07"
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
- **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.
|
|
508
|
+
- `--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.
|
|
509
|
+
- 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.
|
|
510
|
+
- No `--at`, `--title` or `--scratchpad`: a published post has no draft to organize (passing them returns 400).
|
|
511
|
+
- The result carries `status: "sent"`, `posted_at`, `x_post_id` and `url`.
|
|
512
|
+
- 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.
|
|
513
|
+
|
|
514
|
+
### Bulk queue operations
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
# Move queued posts to new times (up to 500, one transaction: all or none)
|
|
518
|
+
superx scheduled:bulk-retime --moves-json '[{"id":"abc","scheduled_for":"2026-09-08T15:00:00Z"}]'
|
|
519
|
+
|
|
520
|
+
# Turn Auto Retweet on for posts that do not have it (up to 100)
|
|
521
|
+
superx scheduled:bulk-auto-retweet --ids abc,def --auto-retweet 6 --auto-retweet-remove 4
|
|
522
|
+
|
|
523
|
+
# Delete queued posts and refund their post quota (up to 100)
|
|
524
|
+
superx scheduled:bulk-delete --ids abc,def
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
- 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>`.
|
|
528
|
+
- `bulk-auto-retweet` never overwrites a post's existing auto retweet; those posts land in `skipped`.
|
|
529
|
+
- 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.
|
|
530
|
+
- Each `scheduled_for` follows the normal window: at least 60 seconds ahead, within 18 months.
|
|
531
|
+
- The responses are COUNTS, not per-post results. Re-read with `scheduled:list` to see the new state.
|
|
532
|
+
- 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).
|
|
533
|
+
|
|
250
534
|
### Editing drafts and scheduled posts
|
|
251
535
|
|
|
252
536
|
```bash
|
|
@@ -262,7 +546,7 @@ superx scheduled:update <post-id> --clear-tags --clear-title --clear-scratchpad
|
|
|
262
546
|
- A new `--at` alone never schedules a draft. Promotion is always explicit via `--status scheduled` (which needs a future time, provided or already set).
|
|
263
547
|
- 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.
|
|
264
548
|
|
|
265
|
-
### Advanced settings (auto retweet, auto delete, auto plug, super followers)
|
|
549
|
+
### Advanced settings (auto retweet, auto delete, auto plug, auto DM, super followers)
|
|
266
550
|
|
|
267
551
|
```bash
|
|
268
552
|
# Explicit values on create
|
|
@@ -282,17 +566,41 @@ superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
|
282
566
|
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
283
567
|
--no-auto-retweet --no-auto-plug
|
|
284
568
|
|
|
569
|
+
# Auto DM the people who engage with the post once it is live
|
|
570
|
+
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
|
|
571
|
+
--auto-dm-message "Hey [first], here is the template I mentioned" \
|
|
572
|
+
--auto-dm-triggers reply,repost --auto-dm-max 50
|
|
573
|
+
|
|
285
574
|
# Edit or remove on an existing post (no inheritance on update)
|
|
286
575
|
superx scheduled:update <post-id> --auto-retweet 2
|
|
287
576
|
superx scheduled:update <post-id> --no-auto-delete
|
|
577
|
+
superx scheduled:update <post-id> --no-auto-dm # also gives back the month's slot
|
|
288
578
|
```
|
|
289
579
|
|
|
290
580
|
- 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.
|
|
291
581
|
- On `scheduled:update` there is no inheritance: passed flags override, omitted flags keep the post's current settings, `--no-*` removes them.
|
|
292
582
|
- 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.
|
|
293
|
-
- Auto DM
|
|
583
|
+
- 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.
|
|
294
584
|
- `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.
|
|
295
585
|
|
|
586
|
+
### DM campaigns (queue only; the app sends)
|
|
587
|
+
|
|
588
|
+
```bash
|
|
589
|
+
superx dm:limits # allowances before you queue anything
|
|
590
|
+
superx dm:campaign --recipients people.json --message "Hey [first], loved your thread"
|
|
591
|
+
superx dm:campaign --recipients=- --message "..." --spread # recipients from stdin
|
|
592
|
+
superx dm:campaign-status <campaign-id> # counts per status + the messages
|
|
593
|
+
superx dm:queue --status pending # everything still waiting to go out
|
|
594
|
+
superx dm:cancel <campaign-id> # remove the unsent ones
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
- **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`.
|
|
598
|
+
- 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.
|
|
599
|
+
- `--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.
|
|
600
|
+
- 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.
|
|
601
|
+
- `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.
|
|
602
|
+
- 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.
|
|
603
|
+
|
|
296
604
|
### Tags
|
|
297
605
|
|
|
298
606
|
```bash
|
|
@@ -326,12 +634,20 @@ superx context:products
|
|
|
326
634
|
superx context:products:set --url "https://superx.so" --name "SuperX" --description "X growth platform"
|
|
327
635
|
superx context:products:set --id 3 --updates "Shipped the public API"
|
|
328
636
|
superx context:products:delete <product-id>
|
|
637
|
+
superx context:products:replace --json '[{"url":"https://superx.so","name":"SuperX"}]' # FULL REPLACE
|
|
638
|
+
|
|
639
|
+
# Free helpers (no AI credits)
|
|
640
|
+
superx context:regenerate-style-guide # rebuild the generated guide; once an hour
|
|
641
|
+
superx context:scrape-product <product-id> # re-read that product's page and refresh it
|
|
329
642
|
```
|
|
330
643
|
|
|
331
644
|
- 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.
|
|
332
645
|
- `context:get` also returns the read-only generated style guide (`style_guide.generated`) so you can see what a cleared override falls back to.
|
|
646
|
+
- `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.
|
|
647
|
+
- `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`.
|
|
333
648
|
- 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.
|
|
334
649
|
- `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.
|
|
650
|
+
- `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.
|
|
335
651
|
- 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.
|
|
336
652
|
|
|
337
653
|
### Queue settings (posting schedule)
|
|
@@ -377,14 +693,18 @@ superx articles:unschedule <article-id> # back to draft, quota refunds
|
|
|
377
693
|
superx articles:publish <article-id> # LIVE NOW, irreversible, needs X Premium
|
|
378
694
|
superx articles:delete <article-id>
|
|
379
695
|
|
|
380
|
-
# AI cover (60-100s,
|
|
696
|
+
# AI cover (60-100s, a flat 25 AI credits, plus the daily/monthly cover caps)
|
|
697
|
+
superx articles:cover-styles # styles saved in the app, with their ids
|
|
381
698
|
superx articles:cover <article-id>
|
|
699
|
+
superx articles:cover <article-id> --style-id <style-id> # render in a saved style
|
|
382
700
|
superx articles:cover <article-id> --style "dark, minimal, geometric" --no-attach
|
|
383
701
|
```
|
|
384
702
|
|
|
385
703
|
- Publishing and scheduling spend post quota; the article needs a title and some content first.
|
|
386
704
|
- X enforces its own article limits (10 drafts/day, 5 publishes/day) and requires X Premium; those surface as publish failures.
|
|
387
705
|
- `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`.
|
|
706
|
+
- 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.
|
|
707
|
+
- 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.
|
|
388
708
|
- A publish timeout is AMBIGUOUS: run `articles:get` and check `status` before retrying.
|
|
389
709
|
|
|
390
710
|
### Docs
|
|
@@ -443,7 +763,7 @@ for attempt in 1 2 3; do
|
|
|
443
763
|
done
|
|
444
764
|
```
|
|
445
765
|
|
|
446
|
-
Rate limits per
|
|
766
|
+
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
|
|
447
767
|
|
|
448
768
|
### Pattern 5: Batch a week of content
|
|
449
769
|
|
|
@@ -459,12 +779,60 @@ superx scheduled:list --status scheduled
|
|
|
459
779
|
|
|
460
780
|
---
|
|
461
781
|
|
|
782
|
+
## Playbooks
|
|
783
|
+
|
|
784
|
+
Full recipes with flags and MCP tool chains: [PLAYBOOKS.md](./PLAYBOOKS.md). Pick by goal, then open that entry.
|
|
785
|
+
|
|
786
|
+
### Recaps and analytics
|
|
787
|
+
- **Weekly Growth Recap**: the week in review, one focus for next week. `posts:analytics` -> `posts:list` -> `signals:leads` -> `replies:received`
|
|
788
|
+
- **Growth Plan Builder**: multi-week plan tied to real numbers. `posts:analytics` -> `posts:list` -> `replies:list` -> `queue:get`
|
|
789
|
+
- **Post Post-Mortem**: why one post over- or underperformed. `posts:list` -> `posts:analytics` -> `x:user-posts`
|
|
790
|
+
- **Top Performers Breakdown**: the shape the best posts share. `posts:list` -> `posts:analytics`
|
|
791
|
+
- **My Replies Report**: which replies earned attention. `replies:list`
|
|
792
|
+
|
|
793
|
+
### Content
|
|
794
|
+
- **Daily Post Ideas**: two or three drafts for today. `scheduled:list` -> `posts:list` -> `posts:draft` -> `scheduled:create`
|
|
795
|
+
- **Week of Posts**: a week of drafts on the real slots. `posts:list` -> `queue:get` -> `posts:draft` -> `scheduled:create`
|
|
796
|
+
- **Thread Builder**: notes turned into a thread draft. `posts:draft` -> `scheduled:create`
|
|
797
|
+
- **Repurpose a Winner**: the best post, reworked. `posts:list` -> `posts:remix` -> `scheduled:create`
|
|
798
|
+
- **Viral Format Remix**: proven shapes in this account's voice. `inspiration:search` -> `posts:draft` -> `scheduled:create`
|
|
799
|
+
- **Trending Now Scan**: what is working in the niche now. `inspiration:search`
|
|
800
|
+
|
|
801
|
+
### Queue
|
|
802
|
+
- **Cadence & Queue Audit**: gaps, pile-ups, a cadence verdict. `queue:get` -> `scheduled:list` -> `posts:list` -> `scheduled:update`
|
|
803
|
+
- **Queue Reshuffle**: move and rewrite queued posts. `scheduled:list` -> `scheduled:bulk-retime` -> `scheduled:update`
|
|
804
|
+
|
|
805
|
+
### Replies (stop at a draft, by design)
|
|
806
|
+
- **Reply Sprint**: five audience replies, each with a draft. `replies:received` -> `engage:reply-draft`
|
|
807
|
+
- **Reply to Any Post**: context plus one strong reply draft. `x:post` -> `x:replies` -> `engage:reply-draft`
|
|
808
|
+
|
|
809
|
+
### Leads
|
|
810
|
+
- **Who Is This Person?**: a fast read plus your history. `x:user` -> `x:user-posts` -> `contacts:get` -> `contacts:replies`
|
|
811
|
+
- **Your Warmest Leads**: the people engaging most, ranked. `contacts:list` -> `contacts:replies`
|
|
812
|
+
- **Instant Lead Hunt**: live search for matching people now. `signals:suggest-keywords` -> `signals:search`
|
|
813
|
+
- **Standing Lead Agent**: an agent that keeps finding leads. `signals:expand-icp` -> `signals:create-agent` -> `signals:leads`
|
|
814
|
+
- **Lead Review**: found leads, prioritized and checked. `signals:agents` -> `signals:leads` -> `x:user-posts` -> `signals:feedback`
|
|
815
|
+
|
|
816
|
+
### Audiences, research and DMs
|
|
817
|
+
- **Profile Research Briefs**: structured briefs plus a CSV. `datasets:research` -> `datasets:rows` -> `datasets:export`
|
|
818
|
+
- **DM-Ready Audience Builder**: a clean DM-able audience. `datasets:collect` -> `datasets:get` -> `datasets:add-to-list`
|
|
819
|
+
- **Sentiment Slice**: keep only the people who said it. `datasets:list` -> `datasets:refine` -> `datasets:rows`
|
|
820
|
+
- **Audience Export**: everyone who engaged a post, as CSV. `datasets:collect` -> `datasets:export`
|
|
821
|
+
- **My Content Export**: your own posts or replies, as CSV. `datasets:collect` -> `datasets:export`
|
|
822
|
+
- **Warm Outreach Pipeline**: briefs, a message each, queued. `datasets:research` -> `datasets:outreach-drafts` -> `dm:campaign`
|
|
823
|
+
- **Reply-to-DM Campaign**: DM the people who replied. `datasets:collect` -> `datasets:refine` -> `dm:campaign`
|
|
824
|
+
|
|
825
|
+
### Settings
|
|
826
|
+
- **Teach SuperX Your Rules**: standing rules for AI drafts. `context:get` -> `context:set`
|
|
827
|
+
|
|
828
|
+
---
|
|
829
|
+
|
|
462
830
|
## Common Gotchas
|
|
463
831
|
|
|
464
832
|
1. **Naive timestamps are rejected (400)**. Always include `Z` or an offset: `2026-08-01T15:00:00Z`, not `2026-08-01T15:00:00`.
|
|
465
833
|
2. **Schedule window**: `--at` must be at least 60 seconds in the future and within 18 months.
|
|
466
834
|
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.
|
|
467
|
-
4. **
|
|
835
|
+
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, and for `posts:draft`. `context:*` and `queue:set` are per-account settings that do accept a shared account.
|
|
468
836
|
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.
|
|
469
837
|
6. **Size caps**: max 25 thread parts, 25,000 characters total.
|
|
470
838
|
7. **Rate limited (429)**: `rate_limited` on stderr with a retry delay. Back off; do not hammer.
|
|
@@ -489,7 +857,33 @@ superx scheduled:list --status scheduled
|
|
|
489
857
|
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.
|
|
490
858
|
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.
|
|
491
859
|
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.
|
|
492
|
-
29. **`
|
|
860
|
+
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).
|
|
861
|
+
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.
|
|
862
|
+
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`.
|
|
863
|
+
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.
|
|
864
|
+
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.
|
|
865
|
+
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.
|
|
866
|
+
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.
|
|
867
|
+
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.
|
|
868
|
+
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.
|
|
869
|
+
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.
|
|
870
|
+
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`.
|
|
871
|
+
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`.
|
|
872
|
+
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`.
|
|
873
|
+
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.
|
|
874
|
+
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`.
|
|
875
|
+
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.
|
|
876
|
+
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.
|
|
877
|
+
|
|
878
|
+
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.
|
|
879
|
+
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`.
|
|
880
|
+
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.
|
|
881
|
+
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.
|
|
882
|
+
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.
|
|
883
|
+
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.
|
|
884
|
+
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. Unlike `posts:draft`, they also accept an account shared with you. 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.
|
|
885
|
+
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.
|
|
886
|
+
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.
|
|
493
887
|
|
|
494
888
|
---
|
|
495
889
|
|
|
@@ -513,22 +907,64 @@ superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"
|
|
|
513
907
|
superx posts:analytics --since "2026-06-01T00:00:00Z"
|
|
514
908
|
superx replies:list --limit 20
|
|
515
909
|
superx inspiration:search "build in public" --sort outlier --limit 10
|
|
910
|
+
superx inspiration:media "founder morning routine" --limit 10 # cross-platform media index (--limit up to 120, no paging)
|
|
516
911
|
superx contacts:list --sort engagement --limit 20
|
|
517
912
|
superx contacts:replies <id> --sort most_liked
|
|
913
|
+
superx contacts:get <x-user-id>
|
|
914
|
+
superx contacts:notes <x-user-id>
|
|
518
915
|
superx replies:received --sort most_liked --limit 20
|
|
519
916
|
superx lists:list
|
|
520
917
|
superx lists:members <list-id> --q "founder"
|
|
918
|
+
superx audience:list followers --limit 100 # system lists: cursor paging, no --page
|
|
919
|
+
superx engage:mentions --sort top # live @-mentions (costs 3 feed fetches)
|
|
920
|
+
superx signals:search --keywords "..." --icp "..." # live lead search, saves nothing
|
|
521
921
|
superx signals:agents
|
|
522
922
|
superx signals:leads --agent 3 --deposited false
|
|
523
923
|
superx engage:feeds
|
|
524
924
|
superx engage:posts <feed-id> --limit 50
|
|
925
|
+
superx datasets:list
|
|
926
|
+
superx datasets:get <dataset-id>
|
|
927
|
+
superx datasets:rows <dataset-id> --limit 50
|
|
928
|
+
superx datasets:export <dataset-id> # CSV file here; --out - streams to stdout
|
|
929
|
+
superx datasets:collect --source repliers --target <post-url> --wait # build one, poll until ready
|
|
930
|
+
superx datasets:refine <dataset-id> --criterion "..." --wait # filter by what each person wrote
|
|
931
|
+
superx datasets:research --handles a,b,c --wait # briefs, 1 credit per profile
|
|
932
|
+
superx datasets:outreach-drafts <dataset-id> --format "..." # message TEXT only, nothing sent
|
|
933
|
+
|
|
934
|
+
# Live X lookups (enrichment units + a shared 300/day allowance)
|
|
935
|
+
superx x:post <id-or-url> # one public post, live (--quotes for quotes)
|
|
936
|
+
superx x:replies <id-or-url> --limit 20 # best-liked direct replies (a sample)
|
|
937
|
+
superx x:user <handle> # one public profile, live
|
|
938
|
+
superx x:user-posts <handle> --no-reposts # one live page of their latest posts
|
|
939
|
+
|
|
940
|
+
# Contact writes (main or linked account)
|
|
941
|
+
superx contacts:notes:add <x-user-id> --body "..." # Private note, never posted
|
|
942
|
+
superx contacts:notes:update <x-user-id> <note-id> --body "..."
|
|
943
|
+
superx contacts:notes:delete <x-user-id> <note-id>
|
|
525
944
|
|
|
526
945
|
# Contact list writes (main or linked account)
|
|
527
946
|
superx lists:add-member <list-id> --handle levelsio
|
|
528
947
|
superx lists:remove-member <list-id> <member-id>
|
|
948
|
+
superx lists:create --name "Founder prospects"
|
|
949
|
+
superx lists:rename <list-id> --name "Q4 prospects"
|
|
950
|
+
superx lists:delete <list-id> # List + membership; the people stay
|
|
951
|
+
superx lists:add-members <list-id> --x-user-ids 44196397,944883311 # <=500, ids SuperX knows
|
|
952
|
+
superx lists:remove-members <list-id> --member-ids m1abc,m2def # <=500
|
|
953
|
+
superx datasets:add-to-list <dataset-id> --list-id <list-id> # people from a ready dataset
|
|
954
|
+
|
|
955
|
+
# Engage feed writes (main or linked account)
|
|
956
|
+
superx engage:feeds:create --name "AI builders" --keyword "shipping with LLMs"
|
|
957
|
+
superx engage:feeds:create --name "Founders" --x-list https://x.com/i/lists/1234567890
|
|
958
|
+
superx engage:feeds:update <feed-id> --name "AI builders v2"
|
|
959
|
+
superx engage:feeds:delete <feed-id>
|
|
529
960
|
|
|
530
961
|
# Signal agent writes (main or linked account)
|
|
531
962
|
superx signals:create-agent --name "..." --icp "..." --keyword "..." # Lead finder
|
|
963
|
+
superx signals:create-agent --name "..." --icp "..." --signal "profile:@naval"
|
|
964
|
+
superx signals:update-agent <id> --icp "..." --list-id <contact-list-id>
|
|
965
|
+
superx signals:add-signal <id> --type follower_watch --handle naval
|
|
966
|
+
superx signals:remove-signal <id> <signal-id>
|
|
967
|
+
superx signals:feedback <lead-id> --fit # or --not-fit / --clear
|
|
532
968
|
superx signals:pause-agent <id>
|
|
533
969
|
superx signals:resume-agent <id>
|
|
534
970
|
superx signals:delete-agent <id>
|
|
@@ -547,6 +983,36 @@ superx scheduled:list --status draft,scheduled
|
|
|
547
983
|
superx scheduled:list --tags <tag-id>
|
|
548
984
|
superx scheduled:delete <id>
|
|
549
985
|
|
|
986
|
+
# Publish NOW (irreversible; key required, reuse it on a retry)
|
|
987
|
+
superx posts:publish --text "Post" --idempotency-key k1
|
|
988
|
+
|
|
989
|
+
# Writing helpers (text in, text out; nothing is posted)
|
|
990
|
+
superx engage:reply-draft --post <id> --thoughts "..." --tone concise
|
|
991
|
+
superx posts:remix --text "..." --closeness 70
|
|
992
|
+
superx tools:inline-edit --text "..." --full "..." --type hook
|
|
993
|
+
superx tools:rephrase --type concise --text "..."
|
|
994
|
+
superx tools:factcheck --text "..."
|
|
995
|
+
superx tools:predict --a "..." --b "..."
|
|
996
|
+
|
|
997
|
+
# DM campaigns (queued only; the SuperX app sends them)
|
|
998
|
+
superx dm:limits
|
|
999
|
+
superx dm:campaign --recipients people.json --message "Hey [first], ..."
|
|
1000
|
+
superx dm:campaign-status <campaign-id>
|
|
1001
|
+
superx dm:queue --status pending
|
|
1002
|
+
superx dm:cancel <campaign-id>
|
|
1003
|
+
|
|
1004
|
+
# Free helpers (no AI credits)
|
|
1005
|
+
superx context:regenerate-style-guide
|
|
1006
|
+
superx context:scrape-product <product-id>
|
|
1007
|
+
superx signals:suggest-keywords --icp "B2B SaaS founders worried about churn"
|
|
1008
|
+
superx signals:expand-icp --text "Indie founders building SaaS in public"
|
|
1009
|
+
superx signals:expand-icp --url superx.so
|
|
1010
|
+
|
|
1011
|
+
# Bulk queue operations (queued posts only; answers are counts)
|
|
1012
|
+
superx scheduled:bulk-retime --moves-json '[{"id":"abc","scheduled_for":"2026-09-08T15:00:00Z"}]'
|
|
1013
|
+
superx scheduled:bulk-auto-retweet --ids abc,def --auto-retweet 6
|
|
1014
|
+
superx scheduled:bulk-delete --ids abc,def
|
|
1015
|
+
|
|
550
1016
|
# Tags
|
|
551
1017
|
superx tags:list
|
|
552
1018
|
superx tags:create "Launch week" --color amber
|
|
@@ -561,7 +1027,9 @@ superx articles:update <id> --file v2.md
|
|
|
561
1027
|
superx articles:schedule <id> --at "2026-08-01T15:00:00Z"
|
|
562
1028
|
superx articles:unschedule <id>
|
|
563
1029
|
superx articles:publish <id>
|
|
1030
|
+
superx articles:cover-styles
|
|
564
1031
|
superx articles:cover <id> --style "minimal"
|
|
1032
|
+
superx articles:cover <id> --style-id <style-id>
|
|
565
1033
|
superx articles:delete <id>
|
|
566
1034
|
|
|
567
1035
|
# Context settings (AI writing background)
|
|
@@ -571,6 +1039,7 @@ superx context:set --interests "indie hacking,SaaS" # replaces the list
|
|
|
571
1039
|
superx context:products
|
|
572
1040
|
superx context:products:set --url "https://superx.so" --name "SuperX"
|
|
573
1041
|
superx context:products:delete <id>
|
|
1042
|
+
superx context:products:replace --json '[{"url":"https://superx.so"}]' # FULL REPLACE
|
|
574
1043
|
|
|
575
1044
|
# Queue settings (posting schedule; 0 = Sunday)
|
|
576
1045
|
superx queue:get
|
|
@@ -583,4 +1052,4 @@ superx --help # All commands
|
|
|
583
1052
|
superx scheduled:create --help # Command help
|
|
584
1053
|
```
|
|
585
1054
|
|
|
586
|
-
Strategy lives in [PLAYBOOK.md](./PLAYBOOK.md). Read it before creating content (Rule 2).
|
|
1055
|
+
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.
|