Install SuperX CLI if it doesn't exist
npm install -g superx-cli
npm release: https://www.npmjs.com/package/superx-cli
superx-agent github: https://github.com/superx-so/superx-agent
API docs: https://docs.superx.so
official website: https://superx.so
| Property |
Value |
| name |
superx |
| description |
Twitter/X growth CLI: posts, analytics, contacts, contact lists, audience replies, signal agents and their leads, inspiration, tags, scheduling (with images), long-form Articles, and Context settings (AI writing background) via the SuperX API |
| allowed-tools |
Bash(superx:*) |
Three Hard Rules (Read First)
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.
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.
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 the main account only. 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. articles:publish posts a long-form article to X IMMEDIATELY and irreversibly; treat it like hitting Publish in public and get human confirmation unless the user already gave it.
Output Contract
- stdout is clean JSON for every command except
docs (markdown). Pipe anything into jq directly.
- Human/status lines go to stderr, never stdout.
- Exit code 0 on success, 1 on any error. Error details (including the API error code) are printed to stderr as
Error [code] (HTTP status): message.
POSTS=$(superx posts:list --sort likes --limit 5)
echo "$POSTS" | jq '.data[].text'
Core Workflow
- Check auth:
superx status (verifies the key and shows plan + rate-limit state)
- Discover accounts:
superx accounts (main account first; note ids for --account)
- Read the data: top posts, analytics, most engaged contacts
- Read PLAYBOOK.md, then draft content informed by what already works for this account
- Create:
superx scheduled:create (draft first when unsure; add --at to schedule)
- Verify:
superx scheduled:list shows the draft/queue state
# 1. Auth
superx status
# 2. Accounts
superx accounts
# 3. Read data
superx posts:list --sort likes --limit 10
superx posts:analytics
superx contacts:list --sort engagement --limit 20
# 4. Read PLAYBOOK.md (in this skill's directory), then write content
# 5. Create (draft, review, then schedule)
superx scheduled:create --text "Post text"
superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z"
# 6. Verify
superx scheduled:list --status draft,scheduled
Essential Commands
Authentication
superx login # Guided: prints the key page URL, prompts for a paste
superx login --key "sxk_..." # Non-interactive
superx status # Verify credentials; shows plan, key scopes, rate limits
superx logout # Delete ~/.superx/credentials.json
export SUPERX_API_KEY=sxk_... # Env alternative (credentials file wins when both exist)
Credentials are stored in ~/.superx/credentials.json (file mode 0600). SUPERX_API_URL overrides the API base URL with a full base including path (default https://api.superx.so/v1).
Identity and accounts
superx me # Key owner, plan tier, key name and scopes
superx accounts # X accounts this key can read; use ids with --account
Reads accept --account <id> to select a linked or shared account. Omitting it means the main account.
Posts and analytics
superx posts:list # Recent posts with metrics
superx posts:list --type posts --sort likes # Original posts by likes
superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"
superx posts:analytics # Totals + daily series, last 30 days
superx posts:analytics --since "2026-06-01T00:00:00Z"
superx replies:list --limit 20 # Replies the account has sent
superx replies:received --limit 20 # Replies the audience has sent the account
posts:list flags: --type posts|replies|all, --sort posted_at|likes|impressions, --since/--until, --limit (max 100), --page.
- Post objects include
metrics (likes, replies, reposts, quotes, bookmarks, impressions).
posts:analytics range is capped at 366 days.
replies:received shows who replied, what they said, likes, and the post they replied to. Flags: --sort recent|most_liked, --since/--until, --limit (max 100), --page. Use it to find replies worth answering (see PLAYBOOK.md on closing engagement loops).
Inspiration (viral post library)
superx inspiration:search "build in public" --limit 10 # Topic search
superx inspiration:search "indie hackers" --sort outlier # Biggest overperformers
superx inspiration:search "AI tools" --min-likes 500 --min-followers 1000 --max-followers 50000
- Searches a library of 50M+ real high-performing posts. Use results for structures, hooks, and angles to remix. Never copy them.
- 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).
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.
- Results are relevance-ranked, strongest matches first. Weak and promotional matches are filtered out, so a page may return fewer than
--limit posts.
Contacts (who engages with you)
superx contacts:list --sort engagement --limit 20 # Most engaged people
superx contacts:list --sort replies # By reply count
superx contacts:replies <contact-id> --sort recent # One person's reply history to you
Sort options: contacts:list takes engagement|replies|reposts; contacts:replies takes recent|most_liked.
Contact lists
superx lists:list # All lists; system lists flagged is_system
superx lists:members <list-id> --q "founder" # Members of a list the user created
superx lists:add-member <list-id> --handle levelsio # or --x-user-id 44196397
superx lists:remove-member <list-id> <member-id> # member-id from lists:members
- Lists are the saved people-collections from the SuperX app. Use them to track prospects, customers, or people worth engaging.
- System lists (Followers, Following, Repliers, Reposters) appear in
lists:list with is_system: true but are read-only and their members are NOT available through the API.
- Adding someone already in a list is harmless: the existing member returns with
"duplicate": true and nothing changes.
- Member writes are main account only and need a key with the write scope.
Signals (automated lead finding)
superx signals:agents # agents, what they watch, lead counts
superx signals:leads --limit 20 # newest leads across all agents
superx signals:leads --agent 3 --deposited false # one agent's leads not yet in its list
superx signals:leads --since "2026-07-01T00:00:00Z" # leads discovered since July
# Create an agent (main account only, write scope)
superx signals:create-agent \
--name "Build in public founders" \
--icp "Indie founders building SaaS in public, sharing MRR and launches" \
--keyword "building in public" --keyword "just shipped my MVP"
# Lifecycle (agent id from signals:agents)
superx signals:pause-agent 3
superx signals:resume-agent 3
superx signals:delete-agent 3
- Signal agents are automated lead finders: they watch profiles, followers, keywords, or lists and score people against an ideal customer profile. The API creates keyword-watch agents and pauses, resumes, or deletes any agent; name/ICP/precision/destination edits happen in the app.
signals:create-agent requires --name (max 80) and --icp (max 500). Repeat --keyword for 1-5 plain-language watches ("what does the target customer post about"); omit it and 1-3 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.
- 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.
- Deleting an agent keeps its saved leads and its contact list.
- 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).
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.
- An agent's
destination_list_id joins to lists:list for the target list's name; deposited leads appear there as members.
Scheduling
# Draft (no --at): saved, never publishes on its own
superx scheduled:create --text "Post text"
# Scheduled post (UTC ISO-8601 with Z or offset, at least 60s in the future)
superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z"
# Thread: repeat --part in order (1-25 parts, 25,000 chars total)
superx scheduled:create \
--part "1/ The hook" \
--part "2/ The substance" \
--part "3/ The close" \
--at "2026-08-01T15:00:00Z"
# Safe retries: same key + same body returns the original result
superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z" \
--idempotency-key "agent-run-42"
# Organizer fields on drafts: title and scratchpad show in the app, never post
superx scheduled:create --text "Post text" --title "Launch teaser" \
--scratchpad "Angle: contrast with last week's thread" --tag <tag-id>
# Images: upload first, then attach the object_key
KEY=$(superx media:upload ./chart.png | jq -r '.object_key')
superx scheduled:create --text "Chart of the week" --media "$KEY" --alt-text "Weekly revenue line chart"
# Thread with media on one part: pass the parts array as JSON
superx scheduled:create --parts-json '[{"text":"1/ Hook","media":[{"object_key":"'"$KEY"'","alt_text":"Chart"}]},{"text":"2/ Detail"}]'
# Queue state and cleanup
superx scheduled:list --status draft,scheduled
superx scheduled:list --tags <tag-id> # posts carrying ANY listed tag
superx scheduled:delete <post-id>
--text, --part, and --parts-json are mutually exclusive; one is required.
- Replays add
"replayed": true to the JSON output and print a stderr note.
scheduled:list filters: --status draft,scheduled,sent,error (comma list), --tags id,id (any-of), --from/--to bounds on the scheduled time.
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.
Editing drafts and scheduled posts
superx scheduled:update <post-id> --title "Better hook" # Only the title changes
superx scheduled:update <post-id> --text "New text" # Replace the text
superx scheduled:update <post-id> --at "2026-08-01T15:00:00Z" --status scheduled # Promote a draft
superx scheduled:update <post-id> --status draft # Back to drafts (quota refunds)
superx scheduled:update <post-id> --tag <id-a> --tag <id-b> # Replaces ALL current tags
superx scheduled:update <post-id> --clear-tags --clear-title --clear-scratchpad
- Only the flags you pass change; everything else on the post is preserved.
- A new
--at alone never schedules a draft. Promotion is always explicit via --status scheduled (which needs a future time, provided or already set).
- CAUTION: replacement text is a FULL replace, media included.
--text without --media REMOVES any images the post carried; re-list the current object_keys (visible in scheduled:list) to keep them. Title, scratchpad, tag, and time edits never touch media.
Advanced settings (auto retweet, auto delete, auto plug, super followers)
# Explicit values on create
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
--auto-retweet 6 --auto-retweet-remove 4
# Auto plug: reply with a template once the post hits a likes threshold
superx plug-templates:list # id, text, has_media
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
--auto-plug <template-id> --auto-plug-threshold 50
# Auto delete underperformers (delete after 8h if under 500 views)
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
--auto-delete 8 --auto-delete-threshold 500
# Turn the user's defaults OFF for one post
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
--no-auto-retweet --no-auto-plug
# Edit or remove on an existing post (no inheritance on update)
superx scheduled:update <post-id> --auto-retweet 2
superx scheduled:update <post-id> --no-auto-delete
- 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.
- On
scheduled:update there is no inheritance: passed flags override, omitted flags keep the post's current settings, --no-* removes them.
- 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.
- Auto DM has no flag: it always follows the user's app defaults. If a plan limit strips it at create time, the response carries
"auto_dm_skipped": true; relay that to the user instead of ignoring it.
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.
Tags
superx tags:list # id, name, color
superx tags:create "Launch week" --color amber # colors: rose, amber, lime, emerald, teal, cyan, blue, indigo, violet, fuchsia, slate, stone
superx tags:update <tag-id> --name "Launch" --color violet
superx tags:delete <tag-id> # also removes it from every post
Tag names are unique per workspace (409 duplicate_name) and capped at 40 characters. Assign tags with scheduled:create --tag or scheduled:update --tag.
Context settings (AI writing background)
The Context settings are the background SuperX's AI uses when writing for the account: who the user is, what they post about, hard rules, whose style they admire, and what products they sell. Editing them changes every AI writing surface in the app.
superx context:get # The whole context document
superx context:get | jq '.data.rules' # One section
# Only the flags you pass change; "" clears a string; lists fully replace
superx context:set --rules "Never use hashtags. Keep posts under 200 chars."
superx context:set --profile-description "Indie hacker building SuperX" --profile-description-enabled
superx context:set --interests "indie hacking,SaaS,AI agents" # replaces the list
superx context:set --favorite-creators "levelsio,marc_louvion" # max 3, replaces the list
superx context:set --reply-rules "Be helpful, never salesy" --no-reply-author-name
superx context:set --style-audience "Bootstrapped SaaS founders" # outranks the generated guide
superx context:set --style-audience "" # revert to the generated guide
# Products (max 5): mentioned naturally in generated content
superx context:products
superx context:products:set --url "https://superx.so" --name "SuperX" --description "X growth platform"
superx context:products:set --id 3 --updates "Shipped the public API"
superx context:products:delete <product-id>
- 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.
context:get also returns the read-only generated style guide (style_guide.generated) so you can see what a cleared override falls back to.
- 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.
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.
- 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.
Queue settings (posting schedule)
The posting schedule is the set of predefined time slots the queue fills, plus the timezone they run in.
superx queue:get # slots, timezone, is_default flags
# Slots are JSON so weekday sets stay unambiguous; 0 = Sunday
superx queue:set --slots-json '[{"time":"09:00","days":[1,2,3,4,5]},{"time":"17:30","days":[1,3,5]}]'
superx queue:set --timezone "Europe/London" # never moves queued posts
superx queue:set --slots-json '[]' # clear every predefined slot
--slots-json is a FULL REPLACE: max 50 entries, one per unique time, each with at least one weekday. Send the complete set the user should end up with.
- Changing the slots also re-flows the queue the way the app does: a queued post sitting exactly on an old slot moves to the matching new slot (Nth old occurrence to Nth new occurrence), so gaps are preserved and hand-picked custom times stay put. Read
reflow.moved in the response to see how many posts moved.
reflow.bailed: true means the settings were saved but the queue was deliberately left alone (a post had nowhere to land, or the move set was too large). Rerunning the same command is safe.
- A timezone-only change never moves posts. Changing the timezone and the slots in one call usually moves nothing, because the existing posts were placed under the old timezone; to re-flow them, change the timezone first, then send the slots in a second call.
slots_are_default / timezone_is_default mark values the account has never set; SuperX is using its own default.
- Writes need a key with the write scope and work on any linked or shared account via
--account, Editor-permission shares included (running the queue is exactly what a delegate is there for).
Articles (long-form X posts)
Article bodies are markdown in BOTH directions: headings (h1-h3), bullet and numbered lists (one nesting level), blockquotes, bold/italic/strikethrough, links, images by URL, and bare X post URLs alone on a line as embeds. Code blocks and --- rules degrade to plain text; the response lists degradations in warnings.
# Create: --file, --content, or piped stdin supplies the markdown body
superx articles:create --title "My article" --file draft.md
cat draft.md | superx articles:create --title "My article"
superx articles:list --status draft,scheduled
superx articles:get <article-id> # body returns as markdown
# Update: only the flags you pass change; --file/--content replaces the WHOLE body
superx articles:update <article-id> --title "Sharper title"
superx articles:update <article-id> --file v2.md
superx articles:update <article-id> --cover-url "https://..." # or --clear-cover
# Lifecycle
superx articles:schedule <article-id> --at "2026-08-01T15:00:00Z" # >2 min ahead
superx articles:unschedule <article-id> # back to draft, quota refunds
superx articles:publish <article-id> # LIVE NOW, irreversible, needs X Premium
superx articles:delete <article-id>
# AI cover (60-100s, spends AI credits against daily/monthly caps)
superx articles:cover <article-id>
superx articles:cover <article-id> --style "dark, minimal, geometric" --no-attach
- Publishing and scheduling spend post quota; the article needs a title and some content first.
- X enforces its own article limits (10 drafts/day, 5 publishes/day) and requires X Premium; those surface as publish failures.
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.
- A publish timeout is AMBIGUOUS: run
articles:get and check status before retrying.
Docs
superx docs # Prints the API quickstart as markdown (works before login)
Common Patterns
Pattern 1: Study what works before writing
# Top posts by engagement, last 60 days
SINCE=$(date -u -v-60d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "60 days ago" +"%Y-%m-%dT00:00:00Z")
superx posts:list --sort likes --since "$SINCE" --limit 10 | jq '[.data[] | {text, metrics}]'
# What does the trend look like?
superx posts:analytics --since "$SINCE" | jq '.data.totals, .data.followers'
Pattern 2: Draft first, schedule after review
DRAFT=$(superx scheduled:create --text "Candidate post text")
DRAFT_ID=$(echo "$DRAFT" | jq -r '.data.id')
# ... surface the draft for human review ...
# To publish it at a time, delete the draft and re-create with --at:
superx scheduled:delete "$DRAFT_ID"
superx scheduled:create --text "Final post text" --at "2026-08-01T15:00:00Z"
Pattern 3: Find who to engage with today
# The people already engaging with you (reply to them first)
superx contacts:list --sort engagement --limit 10 | jq '[.data[] | {id, username, name}]'
# What has this person said to you lately?
superx contacts:replies "$CONTACT_ID" --sort recent --limit 5 | jq '.data'
Pattern 4: Retry with backoff on rate limits
for attempt in 1 2 3; do
if OUT=$(superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \
--idempotency-key "job-17"); then
echo "$OUT" | jq -r '.data.id'
break
fi
# Exit 1: stderr had "Error [rate_limited] ..." and a Retry-After hint
sleep $((attempt * 30))
done
Rate limits per key: 60 reads/min and 10,000 reads/day; 10 writes/min and 300 writes/day. Every authenticated response carries X-RateLimit-* headers; superx status shows the current window. On 429 the stderr message includes the retry delay.
Pattern 5: Batch a week of content
TIMES=("2026-08-03T15:00:00Z" "2026-08-04T15:00:00Z" "2026-08-05T15:00:00Z")
TEXTS=("Monday post" "Tuesday post" "Wednesday post")
for i in "${!TIMES[@]}"; do
superx scheduled:create --text "${TEXTS[$i]}" --at "${TIMES[$i]}" \
--idempotency-key "week32-$i" | jq -r '.data.id'
done
superx scheduled:list --status scheduled
Common Gotchas
- Naive timestamps are rejected (400). Always include
Z or an offset: 2026-08-01T15:00:00Z, not 2026-08-01T15:00:00.
- Schedule window:
--at must be at least 60 seconds in the future and within 18 months.
- 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.
- Writes are main-account-only: passing a linked or shared account to
scheduled:create returns 403 writes_main_account_only. Reads accept any account superx accounts lists. The exceptions are context:* and queue:set, which are per-account settings.
- Images need an upload first:
--media takes object_keys 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.
- Size caps: max 25 thread parts, 25,000 characters total.
- Rate limited (429):
rate_limited on stderr with a retry delay. Back off; do not hammer.
- Draft vs scheduled: no
--at means DRAFT. Drafts never publish on their own.
- Idempotency-Key reuse with a DIFFERENT body returns 409
idempotency_key_reuse. Same body replays the original result with "replayed": true.
account_not_found (404): the --account id is not one of the key owner's accounts. Run superx accounts for valid ids.
- Subscription errors: a lapsed SuperX subscription returns 403. The account owner needs to resubscribe in the app.
scheduled:list --status draft --from ... returns nothing: drafts have no scheduled time, so time bounds exclude them. Query drafts without --from/--to.
scheduled:update --at alone never publishes a draft: promotion needs an explicit --status scheduled. Setting --status scheduled without any future time returns 400.
scheduled:update --tag replaces the FULL tag set: pass every tag the post should keep, or use --clear-tags to remove all.
- Text replacement wipes media unless re-listed:
scheduled:update --text (or --part) without --media removes the post's images. Re-include the current object_keys to keep them.
articles:publish is irreversible and needs X Premium: without it the publish fails with 403 x_premium_required. On a timeout, articles:get first; the publish may have completed.
- Article schedule lead time is 2 minutes (posts need only 60 seconds). 400
invalid_parameter under that.
articles:cover needs a title (400 article_title_required) and is capped daily/monthly (429 with remaining_day/remaining_month). One generation at a time per article (409 cover_gen_in_progress).
- Article markdown degrades, never fails, for unsupported constructs (code fences,
---); check warnings in the response. Non-http(s) image or link URLs DO fail with 400.
- System lists are index-only:
lists:members on a system list returns 400 system_list_not_supported; add/remove returns 400 system_list_read_only. Work with lists the user created.
lists:add-member takes exactly one of --handle or --x-user-id. An unknown handle returns 404 user_not_found.
- An unknown signal agent id returns 404
agent_not_found (on signals:leads --agent, signals:pause-agent, signals:resume-agent, and signals:delete-agent; a repeated delete too).
- Signal agents find leads asynchronously:
signals:create-agent returns the created agent, not leads. Leads land over the following minutes and days; read them with signals:leads.
- Plan caps on agents return 403
cap_reached: the plan allows only so many agents (and keyword signals per agent). Pause/delete an existing agent or ask the account owner to upgrade.
- Agent creation is composite: with an auto-created list, a mid-failure can leave an empty
Leads: ... contact list behind (visible in lists:list, deletable in the app). The agent itself is never left without signals.
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.
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.
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.
Quick Reference
# AUTHENTICATE FIRST
superx status # Check auth + rate limits
superx login # Guided key paste
superx login --key "sxk_..." # Non-interactive
superx logout # Remove credentials
export SUPERX_API_KEY=sxk_... # Env alternative (CI)
# Identity
superx me # Owner, plan, key scopes
superx accounts # Readable accounts + ids
# Reads
superx posts:list --type posts --sort likes --limit 10
superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"
superx posts:analytics --since "2026-06-01T00:00:00Z"
superx replies:list --limit 20
superx inspiration:search "build in public" --sort outlier --limit 10
superx contacts:list --sort engagement --limit 20
superx contacts:replies <id> --sort most_liked
superx replies:received --sort most_liked --limit 20
superx lists:list
superx lists:members <list-id> --q "founder"
superx signals:agents
superx signals:leads --agent 3 --deposited false
# Contact list writes (main account only)
superx lists:add-member <list-id> --handle levelsio
superx lists:remove-member <list-id> <member-id>
# Signal agent writes (main account only)
superx signals:create-agent --name "..." --icp "..." --keyword "..." # Lead finder
superx signals:pause-agent <id>
superx signals:resume-agent <id>
superx signals:delete-agent <id>
# Writes (main account only)
superx scheduled:create --text "Post" # Draft
superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" # Scheduled
superx scheduled:create --part "1/" --part "2/" --at "..." # Thread
superx scheduled:create --text "Post" --at "..." --idempotency-key k1 # Safe retry
superx scheduled:create --text "Post" --title "Hook v2" --tag <id> # Organizer fields
superx media:upload ./chart.png # Image -> object_key
superx scheduled:create --text "Post" --media <object_key> --alt-text "..." # With image
superx scheduled:update <id> --title "Better hook" # Edit; only passed flags change
superx scheduled:update <id> --at "..." --status scheduled # Promote a draft
superx scheduled:list --status draft,scheduled
superx scheduled:list --tags <tag-id>
superx scheduled:delete <id>
# Tags
superx tags:list
superx tags:create "Launch week" --color amber
superx tags:update <id> --name "Launch"
superx tags:delete <id>
# Articles (markdown bodies; publish is live + irreversible)
superx articles:create --title "My article" --file draft.md
superx articles:list --status draft
superx articles:get <id>
superx articles:update <id> --file v2.md
superx articles:schedule <id> --at "2026-08-01T15:00:00Z"
superx articles:unschedule <id>
superx articles:publish <id>
superx articles:cover <id> --style "minimal"
superx articles:delete <id>
# Context settings (AI writing background)
superx context:get
superx context:set --rules "Never use hashtags."
superx context:set --interests "indie hacking,SaaS" # replaces the list
superx context:products
superx context:products:set --url "https://superx.so" --name "SuperX"
superx context:products:delete <id>
# Queue settings (posting schedule; 0 = Sunday)
superx queue:get
superx queue:set --slots-json '[{"time":"09:00","days":[1,3,5]}]' # replaces the slots
superx queue:set --timezone "Europe/London" # never moves posts
# Docs and help
superx docs # API quickstart (markdown)
superx --help # All commands
superx scheduled:create --help # Command help
Strategy lives in PLAYBOOK.md. Read it before creating content (Rule 2).
1---2name: superx3description: 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.4---56## Install SuperX CLI if it doesn't exist78```bash9npm install -g superx-cli10```1112npm release: https://www.npmjs.com/package/superx-cli13superx-agent github: https://github.com/superx-so/superx-agent14API docs: https://docs.superx.so15official website: https://superx.so1617---1819| Property | Value |20|----------|-------|21| **name** | superx |22| **description** | Twitter/X growth CLI: posts, analytics, contacts, contact lists, audience replies, signal agents and their leads, inspiration, tags, scheduling (with images), long-form Articles, and Context settings (AI writing background) via the SuperX API |23| **allowed-tools** | Bash(superx:*) |2425---2627## Three Hard Rules (Read First)2829**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.3031**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.3233**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 the main account only. 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. `articles:publish` posts a long-form article to X IMMEDIATELY and irreversibly; treat it like hitting Publish in public and get human confirmation unless the user already gave it.3435---3637## Output Contract3839- **stdout is clean JSON** for every command except `docs` (markdown). Pipe anything into `jq` directly.40- Human/status lines go to **stderr**, never stdout.41- Exit code **0** on success, **1** on any error. Error details (including the API error code) are printed to stderr as `Error [code] (HTTP status): message`.4243```bash44POSTS=$(superx posts:list --sort likes --limit 5)45echo "$POSTS" | jq '.data[].text'46```4748---4950## Core Workflow51521. **Check auth**: `superx status` (verifies the key and shows plan + rate-limit state)532. **Discover accounts**: `superx accounts` (main account first; note ids for `--account`)543. **Read the data**: top posts, analytics, most engaged contacts554. **Read PLAYBOOK.md**, then draft content informed by what already works for this account565. **Create**: `superx scheduled:create` (draft first when unsure; add `--at` to schedule)576. **Verify**: `superx scheduled:list` shows the draft/queue state5859```bash60# 1. Auth61superx status6263# 2. Accounts64superx accounts6566# 3. Read data67superx posts:list --sort likes --limit 1068superx posts:analytics69superx contacts:list --sort engagement --limit 207071# 4. Read PLAYBOOK.md (in this skill's directory), then write content7273# 5. Create (draft, review, then schedule)74superx scheduled:create --text "Post text"75superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z"7677# 6. Verify78superx scheduled:list --status draft,scheduled79```8081---8283## Essential Commands8485### Authentication8687```bash88superx login # Guided: prints the key page URL, prompts for a paste89superx login --key "sxk_..." # Non-interactive90superx status # Verify credentials; shows plan, key scopes, rate limits91superx logout # Delete ~/.superx/credentials.json92export SUPERX_API_KEY=sxk_... # Env alternative (credentials file wins when both exist)93```9495Credentials are stored in `~/.superx/credentials.json` (file mode 0600). `SUPERX_API_URL` overrides the API base URL with a full base including path (default `https://api.superx.so/v1`).9697### Identity and accounts9899```bash100superx me # Key owner, plan tier, key name and scopes101superx accounts # X accounts this key can read; use ids with --account102```103104Reads accept `--account <id>` to select a linked or shared account. Omitting it means the main account.105106### Posts and analytics107108```bash109superx posts:list # Recent posts with metrics110superx posts:list --type posts --sort likes # Original posts by likes111superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"112superx posts:analytics # Totals + daily series, last 30 days113superx posts:analytics --since "2026-06-01T00:00:00Z"114superx replies:list --limit 20 # Replies the account has sent115superx replies:received --limit 20 # Replies the audience has sent the account116```117118- `posts:list` flags: `--type posts|replies|all`, `--sort posted_at|likes|impressions`, `--since/--until`, `--limit` (max 100), `--page`.119- Post objects include `metrics` (likes, replies, reposts, quotes, bookmarks, impressions).120- `posts:analytics` range is capped at 366 days.121- `replies:received` shows who replied, what they said, likes, and the post they replied to. Flags: `--sort recent|most_liked`, `--since/--until`, `--limit` (max 100), `--page`. Use it to find replies worth answering (see PLAYBOOK.md on closing engagement loops).122123### Inspiration (viral post library)124125```bash126superx inspiration:search "build in public" --limit 10 # Topic search127superx inspiration:search "indie hackers" --sort outlier # Biggest overperformers128superx inspiration:search "AI tools" --min-likes 500 --min-followers 1000 --max-followers 50000129```130131- Searches a library of 50M+ real high-performing posts. Use results for structures, hooks, and angles to remix. Never copy them.132- 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).133- `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.134- Results are relevance-ranked, strongest matches first. Weak and promotional matches are filtered out, so a page may return fewer than `--limit` posts.135136### Contacts (who engages with you)137138```bash139superx contacts:list --sort engagement --limit 20 # Most engaged people140superx contacts:list --sort replies # By reply count141superx contacts:replies <contact-id> --sort recent # One person's reply history to you142```143144Sort options: `contacts:list` takes `engagement|replies|reposts`; `contacts:replies` takes `recent|most_liked`.145146### Contact lists147148```bash149superx lists:list # All lists; system lists flagged is_system150superx lists:members <list-id> --q "founder" # Members of a list the user created151superx lists:add-member <list-id> --handle levelsio # or --x-user-id 44196397152superx lists:remove-member <list-id> <member-id> # member-id from lists:members153```154155- Lists are the saved people-collections from the SuperX app. Use them to track prospects, customers, or people worth engaging.156- System lists (Followers, Following, Repliers, Reposters) appear in `lists:list` with `is_system: true` but are read-only and their members are NOT available through the API.157- Adding someone already in a list is harmless: the existing member returns with `"duplicate": true` and nothing changes.158- Member writes are main account only and need a key with the write scope.159160### Signals (automated lead finding)161162```bash163superx signals:agents # agents, what they watch, lead counts164superx signals:leads --limit 20 # newest leads across all agents165superx signals:leads --agent 3 --deposited false # one agent's leads not yet in its list166superx signals:leads --since "2026-07-01T00:00:00Z" # leads discovered since July167168# Create an agent (main account only, write scope)169superx signals:create-agent \170 --name "Build in public founders" \171 --icp "Indie founders building SaaS in public, sharing MRR and launches" \172 --keyword "building in public" --keyword "just shipped my MVP"173174# Lifecycle (agent id from signals:agents)175superx signals:pause-agent 3176superx signals:resume-agent 3177superx signals:delete-agent 3178```179180- Signal agents are automated lead finders: they watch profiles, followers, keywords, or lists and score people against an ideal customer profile. The API creates keyword-watch agents and pauses, resumes, or deletes any agent; name/ICP/precision/destination edits happen in the app.181- `signals:create-agent` requires `--name` (max 80) and `--icp` (max 500). Repeat `--keyword` for 1-5 plain-language watches ("what does the target customer post about"); omit it and 1-3 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`.182- 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.183- Deleting an agent keeps its saved leads and its contact list.184- 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).185- `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`.186- An agent's `destination_list_id` joins to `lists:list` for the target list's name; deposited leads appear there as members.187188### Scheduling189190```bash191# Draft (no --at): saved, never publishes on its own192superx scheduled:create --text "Post text"193194# Scheduled post (UTC ISO-8601 with Z or offset, at least 60s in the future)195superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z"196197# Thread: repeat --part in order (1-25 parts, 25,000 chars total)198superx scheduled:create \199 --part "1/ The hook" \200 --part "2/ The substance" \201 --part "3/ The close" \202 --at "2026-08-01T15:00:00Z"203204# Safe retries: same key + same body returns the original result205superx scheduled:create --text "Post text" --at "2026-08-01T15:00:00Z" \206 --idempotency-key "agent-run-42"207208# Organizer fields on drafts: title and scratchpad show in the app, never post209superx scheduled:create --text "Post text" --title "Launch teaser" \210 --scratchpad "Angle: contrast with last week's thread" --tag <tag-id>211212# Images: upload first, then attach the object_key213KEY=$(superx media:upload ./chart.png | jq -r '.object_key')214superx scheduled:create --text "Chart of the week" --media "$KEY" --alt-text "Weekly revenue line chart"215216# Thread with media on one part: pass the parts array as JSON217superx scheduled:create --parts-json '[{"text":"1/ Hook","media":[{"object_key":"'"$KEY"'","alt_text":"Chart"}]},{"text":"2/ Detail"}]'218219# Queue state and cleanup220superx scheduled:list --status draft,scheduled221superx scheduled:list --tags <tag-id> # posts carrying ANY listed tag222superx scheduled:delete <post-id>223```224225- `--text`, `--part`, and `--parts-json` are mutually exclusive; one is required.226- Replays add `"replayed": true` to the JSON output and print a stderr note.227- `scheduled:list` filters: `--status draft,scheduled,sent,error` (comma list), `--tags id,id` (any-of), `--from/--to` bounds on the scheduled time.228- `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.229230### Editing drafts and scheduled posts231232```bash233superx scheduled:update <post-id> --title "Better hook" # Only the title changes234superx scheduled:update <post-id> --text "New text" # Replace the text235superx scheduled:update <post-id> --at "2026-08-01T15:00:00Z" --status scheduled # Promote a draft236superx scheduled:update <post-id> --status draft # Back to drafts (quota refunds)237superx scheduled:update <post-id> --tag <id-a> --tag <id-b> # Replaces ALL current tags238superx scheduled:update <post-id> --clear-tags --clear-title --clear-scratchpad239```240241- Only the flags you pass change; everything else on the post is preserved.242- A new `--at` alone never schedules a draft. Promotion is always explicit via `--status scheduled` (which needs a future time, provided or already set).243- 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.244245### Advanced settings (auto retweet, auto delete, auto plug, super followers)246247```bash248# Explicit values on create249superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \250 --auto-retweet 6 --auto-retweet-remove 4251252# Auto plug: reply with a template once the post hits a likes threshold253superx plug-templates:list # id, text, has_media254superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \255 --auto-plug <template-id> --auto-plug-threshold 50256257# Auto delete underperformers (delete after 8h if under 500 views)258superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \259 --auto-delete 8 --auto-delete-threshold 500260261# Turn the user's defaults OFF for one post262superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \263 --no-auto-retweet --no-auto-plug264265# Edit or remove on an existing post (no inheritance on update)266superx scheduled:update <post-id> --auto-retweet 2267superx scheduled:update <post-id> --no-auto-delete268```269270- 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.271- On `scheduled:update` there is no inheritance: passed flags override, omitted flags keep the post's current settings, `--no-*` removes them.272- 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.273- Auto DM has no flag: it always follows the user's app defaults. If a plan limit strips it at create time, the response carries `"auto_dm_skipped": true`; relay that to the user instead of ignoring it.274- `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.275276### Tags277278```bash279superx tags:list # id, name, color280superx tags:create "Launch week" --color amber # colors: rose, amber, lime, emerald, teal, cyan, blue, indigo, violet, fuchsia, slate, stone281superx tags:update <tag-id> --name "Launch" --color violet282superx tags:delete <tag-id> # also removes it from every post283```284285Tag names are unique per workspace (409 `duplicate_name`) and capped at 40 characters. Assign tags with `scheduled:create --tag` or `scheduled:update --tag`.286287### Context settings (AI writing background)288289The Context settings are the background SuperX's AI uses when writing for the account: who the user is, what they post about, hard rules, whose style they admire, and what products they sell. Editing them changes every AI writing surface in the app.290291```bash292superx context:get # The whole context document293superx context:get | jq '.data.rules' # One section294295# Only the flags you pass change; "" clears a string; lists fully replace296superx context:set --rules "Never use hashtags. Keep posts under 200 chars."297superx context:set --profile-description "Indie hacker building SuperX" --profile-description-enabled298superx context:set --interests "indie hacking,SaaS,AI agents" # replaces the list299superx context:set --favorite-creators "levelsio,marc_louvion" # max 3, replaces the list300superx context:set --reply-rules "Be helpful, never salesy" --no-reply-author-name301superx context:set --style-audience "Bootstrapped SaaS founders" # outranks the generated guide302superx context:set --style-audience "" # revert to the generated guide303304# Products (max 5): mentioned naturally in generated content305superx context:products306superx context:products:set --url "https://superx.so" --name "SuperX" --description "X growth platform"307superx context:products:set --id 3 --updates "Shipped the public API"308superx context:products:delete <product-id>309```310311- 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.312- `context:get` also returns the read-only generated style guide (`style_guide.generated`) so you can see what a cleared override falls back to.313- 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.314- `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.315- 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.316317### Queue settings (posting schedule)318319The posting schedule is the set of predefined time slots the queue fills, plus the timezone they run in.320321```bash322superx queue:get # slots, timezone, is_default flags323324# Slots are JSON so weekday sets stay unambiguous; 0 = Sunday325superx queue:set --slots-json '[{"time":"09:00","days":[1,2,3,4,5]},{"time":"17:30","days":[1,3,5]}]'326superx queue:set --timezone "Europe/London" # never moves queued posts327superx queue:set --slots-json '[]' # clear every predefined slot328```329330- `--slots-json` is a FULL REPLACE: max 50 entries, one per unique time, each with at least one weekday. Send the complete set the user should end up with.331- Changing the slots also re-flows the queue the way the app does: a queued post sitting exactly on an old slot moves to the matching new slot (Nth old occurrence to Nth new occurrence), so gaps are preserved and hand-picked custom times stay put. Read `reflow.moved` in the response to see how many posts moved.332- `reflow.bailed: true` means the settings were saved but the queue was deliberately left alone (a post had nowhere to land, or the move set was too large). Rerunning the same command is safe.333- A timezone-only change never moves posts. Changing the timezone and the slots in one call usually moves nothing, because the existing posts were placed under the old timezone; to re-flow them, change the timezone first, then send the slots in a second call.334- `slots_are_default` / `timezone_is_default` mark values the account has never set; SuperX is using its own default.335- Writes need a key with the write scope and work on any linked or shared account via `--account`, Editor-permission shares included (running the queue is exactly what a delegate is there for).336337### Articles (long-form X posts)338339Article bodies are markdown in BOTH directions: headings (h1-h3), bullet and numbered lists (one nesting level), blockquotes, bold/italic/strikethrough, links, images by URL, and bare X post URLs alone on a line as embeds. Code blocks and `---` rules degrade to plain text; the response lists degradations in `warnings`.340341```bash342# Create: --file, --content, or piped stdin supplies the markdown body343superx articles:create --title "My article" --file draft.md344cat draft.md | superx articles:create --title "My article"345346superx articles:list --status draft,scheduled347superx articles:get <article-id> # body returns as markdown348349# Update: only the flags you pass change; --file/--content replaces the WHOLE body350superx articles:update <article-id> --title "Sharper title"351superx articles:update <article-id> --file v2.md352superx articles:update <article-id> --cover-url "https://..." # or --clear-cover353354# Lifecycle355superx articles:schedule <article-id> --at "2026-08-01T15:00:00Z" # >2 min ahead356superx articles:unschedule <article-id> # back to draft, quota refunds357superx articles:publish <article-id> # LIVE NOW, irreversible, needs X Premium358superx articles:delete <article-id>359360# AI cover (60-100s, spends AI credits against daily/monthly caps)361superx articles:cover <article-id>362superx articles:cover <article-id> --style "dark, minimal, geometric" --no-attach363```364365- Publishing and scheduling spend post quota; the article needs a title and some content first.366- X enforces its own article limits (10 drafts/day, 5 publishes/day) and requires X Premium; those surface as publish failures.367- `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`.368- A publish timeout is AMBIGUOUS: run `articles:get` and check `status` before retrying.369370### Docs371372```bash373superx docs # Prints the API quickstart as markdown (works before login)374```375376---377378## Common Patterns379380### Pattern 1: Study what works before writing381382```bash383# Top posts by engagement, last 60 days384SINCE=$(date -u -v-60d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "60 days ago" +"%Y-%m-%dT00:00:00Z")385superx posts:list --sort likes --since "$SINCE" --limit 10 | jq '[.data[] | {text, metrics}]'386387# What does the trend look like?388superx posts:analytics --since "$SINCE" | jq '.data.totals, .data.followers'389```390391### Pattern 2: Draft first, schedule after review392393```bash394DRAFT=$(superx scheduled:create --text "Candidate post text")395DRAFT_ID=$(echo "$DRAFT" | jq -r '.data.id')396# ... surface the draft for human review ...397# To publish it at a time, delete the draft and re-create with --at:398superx scheduled:delete "$DRAFT_ID"399superx scheduled:create --text "Final post text" --at "2026-08-01T15:00:00Z"400```401402### Pattern 3: Find who to engage with today403404```bash405# The people already engaging with you (reply to them first)406superx contacts:list --sort engagement --limit 10 | jq '[.data[] | {id, username, name}]'407408# What has this person said to you lately?409superx contacts:replies "$CONTACT_ID" --sort recent --limit 5 | jq '.data'410```411412### Pattern 4: Retry with backoff on rate limits413414```bash415for attempt in 1 2 3; do416 if OUT=$(superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" \417 --idempotency-key "job-17"); then418 echo "$OUT" | jq -r '.data.id'419 break420 fi421 # Exit 1: stderr had "Error [rate_limited] ..." and a Retry-After hint422 sleep $((attempt * 30))423done424```425426Rate limits per key: 60 reads/min and 10,000 reads/day; 10 writes/min and 300 writes/day. Every authenticated response carries `X-RateLimit-*` headers; `superx status` shows the current window. On 429 the stderr message includes the retry delay.427428### Pattern 5: Batch a week of content429430```bash431TIMES=("2026-08-03T15:00:00Z" "2026-08-04T15:00:00Z" "2026-08-05T15:00:00Z")432TEXTS=("Monday post" "Tuesday post" "Wednesday post")433for i in "${!TIMES[@]}"; do434 superx scheduled:create --text "${TEXTS[$i]}" --at "${TIMES[$i]}" \435 --idempotency-key "week32-$i" | jq -r '.data.id'436done437superx scheduled:list --status scheduled438```439440---441442## Common Gotchas4434441. **Naive timestamps are rejected (400)**. Always include `Z` or an offset: `2026-08-01T15:00:00Z`, not `2026-08-01T15:00:00`.4452. **Schedule window**: `--at` must be at least 60 seconds in the future and within 18 months.4463. **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.4474. **Writes are main-account-only**: passing a linked or shared account to `scheduled:create` returns 403 `writes_main_account_only`. Reads accept any account `superx accounts` lists. The exceptions are `context:*` and `queue:set`, which are per-account settings.4485. **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.4496. **Size caps**: max 25 thread parts, 25,000 characters total.4507. **Rate limited (429)**: `rate_limited` on stderr with a retry delay. Back off; do not hammer.4518. **Draft vs scheduled**: no `--at` means DRAFT. Drafts never publish on their own.4529. **Idempotency-Key reuse with a DIFFERENT body** returns 409 `idempotency_key_reuse`. Same body replays the original result with `"replayed": true`.45310. **`account_not_found` (404)**: the `--account` id is not one of the key owner's accounts. Run `superx accounts` for valid ids.45411. **Subscription errors**: a lapsed SuperX subscription returns 403. The account owner needs to resubscribe in the app.45512. **`scheduled:list --status draft --from ...` returns nothing**: drafts have no scheduled time, so time bounds exclude them. Query drafts without `--from/--to`.45613. **`scheduled:update --at` alone never publishes a draft**: promotion needs an explicit `--status scheduled`. Setting `--status scheduled` without any future time returns 400.45714. **`scheduled:update --tag` replaces the FULL tag set**: pass every tag the post should keep, or use `--clear-tags` to remove all.45815. **Text replacement wipes media unless re-listed**: `scheduled:update --text` (or `--part`) without `--media` removes the post's images. Re-include the current `object_key`s to keep them.45916. **`articles:publish` is irreversible and needs X Premium**: without it the publish fails with 403 `x_premium_required`. On a timeout, `articles:get` first; the publish may have completed.46017. **Article schedule lead time is 2 minutes** (posts need only 60 seconds). 400 `invalid_parameter` under that.46118. **`articles:cover` needs a title** (400 `article_title_required`) and is capped daily/monthly (429 with `remaining_day`/`remaining_month`). One generation at a time per article (409 `cover_gen_in_progress`).46219. **Article markdown degrades, never fails, for unsupported constructs** (code fences, `---`); check `warnings` in the response. Non-http(s) image or link URLs DO fail with 400.46320. **System lists are index-only**: `lists:members` on a system list returns 400 `system_list_not_supported`; add/remove returns 400 `system_list_read_only`. Work with lists the user created.46421. **`lists:add-member` takes exactly one of `--handle` or `--x-user-id`**. An unknown handle returns 404 `user_not_found`.46522. **An unknown signal agent id returns 404 `agent_not_found`** (on `signals:leads --agent`, `signals:pause-agent`, `signals:resume-agent`, and `signals:delete-agent`; a repeated delete too).46623. **Signal agents find leads asynchronously**: `signals:create-agent` returns the created agent, not leads. Leads land over the following minutes and days; read them with `signals:leads`.46724. **Plan caps on agents return 403 `cap_reached`**: the plan allows only so many agents (and keyword signals per agent). Pause/delete an existing agent or ask the account owner to upgrade.46825. **Agent creation is composite**: with an auto-created list, a mid-failure can leave an empty `Leads: ...` contact list behind (visible in `lists:list`, deletable in the app). The agent itself is never left without signals.46926. **`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.47027. **`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.47128. **`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.472473---474475## Quick Reference476477```bash478# AUTHENTICATE FIRST479superx status # Check auth + rate limits480superx login # Guided key paste481superx login --key "sxk_..." # Non-interactive482superx logout # Remove credentials483export SUPERX_API_KEY=sxk_... # Env alternative (CI)484485# Identity486superx me # Owner, plan, key scopes487superx accounts # Readable accounts + ids488489# Reads490superx posts:list --type posts --sort likes --limit 10491superx posts:list --since "2026-06-01T00:00:00Z" --until "2026-07-01T00:00:00Z"492superx posts:analytics --since "2026-06-01T00:00:00Z"493superx replies:list --limit 20494superx inspiration:search "build in public" --sort outlier --limit 10495superx contacts:list --sort engagement --limit 20496superx contacts:replies <id> --sort most_liked497superx replies:received --sort most_liked --limit 20498superx lists:list499superx lists:members <list-id> --q "founder"500superx signals:agents501superx signals:leads --agent 3 --deposited false502503# Contact list writes (main account only)504superx lists:add-member <list-id> --handle levelsio505superx lists:remove-member <list-id> <member-id>506507# Signal agent writes (main account only)508superx signals:create-agent --name "..." --icp "..." --keyword "..." # Lead finder509superx signals:pause-agent <id>510superx signals:resume-agent <id>511superx signals:delete-agent <id>512513# Writes (main account only)514superx scheduled:create --text "Post" # Draft515superx scheduled:create --text "Post" --at "2026-08-01T15:00:00Z" # Scheduled516superx scheduled:create --part "1/" --part "2/" --at "..." # Thread517superx scheduled:create --text "Post" --at "..." --idempotency-key k1 # Safe retry518superx scheduled:create --text "Post" --title "Hook v2" --tag <id> # Organizer fields519superx media:upload ./chart.png # Image -> object_key520superx scheduled:create --text "Post" --media <object_key> --alt-text "..." # With image521superx scheduled:update <id> --title "Better hook" # Edit; only passed flags change522superx scheduled:update <id> --at "..." --status scheduled # Promote a draft523superx scheduled:list --status draft,scheduled524superx scheduled:list --tags <tag-id>525superx scheduled:delete <id>526527# Tags528superx tags:list529superx tags:create "Launch week" --color amber530superx tags:update <id> --name "Launch"531superx tags:delete <id>532533# Articles (markdown bodies; publish is live + irreversible)534superx articles:create --title "My article" --file draft.md535superx articles:list --status draft536superx articles:get <id>537superx articles:update <id> --file v2.md538superx articles:schedule <id> --at "2026-08-01T15:00:00Z"539superx articles:unschedule <id>540superx articles:publish <id>541superx articles:cover <id> --style "minimal"542superx articles:delete <id>543544# Context settings (AI writing background)545superx context:get546superx context:set --rules "Never use hashtags."547superx context:set --interests "indie hacking,SaaS" # replaces the list548superx context:products549superx context:products:set --url "https://superx.so" --name "SuperX"550superx context:products:delete <id>551552# Queue settings (posting schedule; 0 = Sunday)553superx queue:get554superx queue:set --slots-json '[{"time":"09:00","days":[1,3,5]}]' # replaces the slots555superx queue:set --timezone "Europe/London" # never moves posts556557# Docs and help558superx docs # API quickstart (markdown)559superx --help # All commands560superx scheduled:create --help # Command help561```562563Strategy lives in [PLAYBOOK.md](./PLAYBOOK.md). Read it before creating content (Rule 2).