Skip to content

CLI reference: Measure and learn

14 commands. Every command runs on your own computer; nothing is sent to a social network unless a publishing command is run by the owner with its live switches.

Record one post’s numbers (likes, replies…) that you read in the platform’s insights or a native export

Terminal window
reachweaver metrics [-h] [--observed-at WHEN] [--source SOURCE] [--views VALUE]
[--impressions VALUE] [--likes VALUE] [--replies VALUE]
[--reposts VALUE] [--saves VALUE] [--clicks VALUE]
[--signups VALUE] [--window-start WINDOW_START]
[--window-end WINDOW_END]
[post_id]
Option Description
post_id The post id (‘reachweaver list’ shows them); for a post you made by hand, ‘reachweaver posted LINK –likes N’ needs no id
--observed-at WHEN When you read the numbers (default: now): now, today, yesterday, YYYY-MM-DD, ‘YYYY-MM-DD HH:MM’ (your computer’s time zone) or ISO 8601 with a timezone
--source SOURCE Where the numbers come from (default ‘entered-by-hand’: you typed them from the platform’s own insights; ReachWeaver did not fetch them). Use a label such as native-export for an exported file
--views VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--impressions VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--likes VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--replies VALUE, --comments VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N (–comments is the same option)
--reposts VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--saves VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--clicks VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--signups VALUE Count, or unknown / suppressed / not_available / delayed / estimated:N
--window-start WINDOW_START Optional start of the period the counts cover (same forms as –observed-at)
--window-end WINDOW_END Optional end of that period; give both or neither (neither = unknown)

Import native-analytics snapshots normalized as CSV (all rows or none)

Terminal window
reachweaver import-metrics [-h] --csv CSV [--json]
Option Description
--csv CSV Columns post_id, observed_at, source, metric columns; optional window_start, window_end. A metric cell is a count, empty/unknown, suppressed, not_available, delayed or estimated:N
--json Machine-readable result

Explicit online, READ-ONLY poll of public Bluesky/Mastodon post counters into metric snapshots; not private analytics, never posts

Terminal window
reachweaver metrics-fetch [-h] [--online] [--account ACCOUNT] [--post-id POST_ID]
[--max-posts MAX_POSTS] [--dry-run]
Option Description
--online Required (unless –dry-run): allow read-only GET requests
--account ACCOUNT Only this bluesky/mastodon account id
--post-id POST_ID Only this local published post
--max-posts MAX_POSTS Posts fetched per run (1..200, default 50)
--dry-run Print the planned GET requests; no network, no DB write

Coverage-aware local analytics; no fabricated reach or results

Terminal window
reachweaver report [-h] [--format {json,markdown,csv,text}] [--since WHEN | --week]
Option Description
--format REPORT_FORMAT text (the default at a terminal: a short summary, a table per network and your top 5 posts), json (the default when the output is piped or redirected; unchanged envelope), markdown, or csv (one row per platform and metric; spreadsheet-formula cells neutralised) One of: json, markdown, csv, text.
--since WHEN Only posts sent in this window and their snapshots observed in it: 24h, 7d, 30d, a date (2026-10-01, midnight UTC) or an ISO time with a timezone. Read-only
--week The last 7 days: the same as –since 7d

#22: offline sampling report over stored metric snapshots of published YouTube videos (exact/sampled/unknown labels); read-only, fetches nothing

Terminal window
reachweaver youtube-analytics [-h] [--account ACCOUNT] [--post-id POST_ID]
Option Description
--account ACCOUNT Only this YouTube account id
--post-id POST_ID Only this local published YouTube post

Read-only per-account matched-age outcome analysis; NOT optimal-time proof

Terminal window
reachweaver timing-evaluate [-h] --account ACCOUNT --timezone TIMEZONE --source SOURCE
--metric
{views,impressions,likes,replies,reposts,saves,clicks,signups}
--denominator {views,impressions} [--age-hours AGE_HOURS]
[--tolerance-hours TOLERANCE_HOURS]
[--min-posts-per-slot MIN_POSTS_PER_SLOT]
[--campaign CAMPAIGN] [--since SINCE] [--until UNTIL]
[--stratify {format,campaign}]
Option Description
--account ACCOUNT Configured account ID; exact cohort only
--timezone TIMEZONE Audience IANA timezone for posting time groups
--source SOURCE Exact source of manually imported native snapshots
--metric METRIC Goal numerator, e.g. clicks One of: views, impressions, likes, replies, reposts, saves, clicks, signups.
--denominator DENOMINATOR One of: views, impressions.
--age-hours AGE_HOURS Compare post ages (24..720 hours)
--tolerance-hours TOLERANCE_HOURS Observation tolerance, 1..168 hours
--min-posts-per-slot MIN_POSTS_PER_SLOT Min comparable posts per time group
--campaign CAMPAIGN Optional narrow cohort; important for topic/format comparability
--since SINCE Optional YYYY-MM-DD audience-local first date
--until UNTIL Optional YYYY-MM-DD audience-local final date
--stratify STRATIFY Also report each format (text/image/video) or campaign separately; a stratum with too little data names no winner and points to calendar-plan’s generic baseline One of: format, campaign.

Read-only: personalized slots/variant campaigns/readouts vs calendar-plan’s generic baseline over –since/–until; bootstrap CI + Holm; non-causal

Terminal window
reachweaver baseline-eval [-h] --account ACCOUNT --timezone TIMEZONE [--source SOURCE]
[--metric {views,impressions,likes,replies,reposts,saves,clicks,signups}]
[--denominator {views,impressions}] [--attribution ATTR.json]
[--outcome {docs_visits,repo_stars_utm}]
[--attribution-source {analytics,ga4}] --since SINCE --until
UNTIL [--slot SLOT] [--campaign-arm CAMPAIGN_ARM]
[--readout READOUT] [--age-hours AGE_HOURS]
[--tolerance-hours TOLERANCE_HOURS]
[--slot-tolerance-minutes SLOT_TOLERANCE_MINUTES]
[--min-posts MIN_POSTS] [--resamples RESAMPLES]
[--confidence CONFIDENCE] [--seed SEED] [--json]
Option Description
--account ACCOUNT Configured account ID; exact cohort only
--timezone TIMEZONE Audience IANA timezone for slots and the period
--source SOURCE Exact source of imported native snapshots (required without –attribution)
--metric METRIC Goal numerator, e.g. clicks (required without –attribution) One of: views, impressions, likes, replies, reposts, saves, clicks, signups.
--denominator DENOMINATOR Required without –attribution One of: views, impressions.
--attribution ATTR.json Saved ‘attribution-report –json’ output: use each post’s attributed count (–outcome) instead of –source/–metric/–denominator; a post without one is excluded, never 0
--outcome OUTCOME With –attribution: docs_visits = attributed sessions, repo_stars_utm = attributed conversions One of: docs_visits, repo_stars_utm.
--attribution-source ATTRIBUTION_SOURCE Which section of –attribution to read: analytics (the –analytics join, default) or ga4 (the –ga4-csv join; key events count as conversions). Never mixed One of: analytics, ga4.
--since SINCE First audience-local send date YYYY-MM-DD (inclusive)
--until UNTIL Last audience-local send date YYYY-MM-DD (inclusive)
--slot SLOT Personalized arm [explore:|exploit:]Wed@16:00; repeat, one comparison each
--campaign-arm CAMPAIGN_ARM Variant campaign arm [explore:|exploit:]CAMPAIGN; repeat
--readout READOUT Saved ‘experiment-readout –json’ file; repeat
--age-hours AGE_HOURS Matched post age (24..720 hours)
--tolerance-hours TOLERANCE_HOURS Snapshot age tolerance, 1..168 hours
--slot-tolerance-minutes SLOT_TOLERANCE_MINUTES Send-time match around a slot, 0..120
--min-posts MIN_POSTS Minimum posts with a rate per group, 3..100
--resamples RESAMPLES Bootstrap/permutation resamples, 200..20000
--confidence CONFIDENCE Interval level; alpha = 1 - confidence
--seed SEED Fixed seed: same inputs give identical output
--json

Read-only ‘What works for you’: compares your own published posts’ matched-age results by time, weekday, length, link, format, hashtags and opening hook; observations to test, never causes

Terminal window
reachweaver insights [-h] [--account ID] [--platform PLATFORM] [--since WHEN]
[--timezone TIMEZONE] [--source SOURCE]
[--metric {interactions,views,impressions,likes,replies,reposts,saves,clicks,signups}]
[--denominator {views,impressions}] [--age-hours AGE_HOURS]
[--tolerance-hours TOLERANCE_HOURS] [--min-posts MIN_POSTS]
[--resamples RESAMPLES] [--seed SEED] [--now NOW] [--json]
Option Description
--account ID Only this account (each account is always analysed apart)
--platform PLATFORM Only this platform id
--since WHEN Only posts sent since 30d (days ago), YYYY-MM-DD or an ISO time
--timezone TIMEZONE IANA time zone for time-of-day and weekday groups (default UTC)
--source SOURCE Exact snapshot source label (default: the one with the most matched posts)
--metric METRIC Result to compare (default interactions = likes + replies + reposts) One of: interactions, views, impressions, likes, replies, reposts, saves, clicks, signups.
--denominator DENOMINATOR Compare a rate: –metric per views or impressions One of: views, impressions.
--age-hours AGE_HOURS Matched post age (24..720 hours, default 168)
--tolerance-hours TOLERANCE_HOURS Snapshot age tolerance (1..168 hours)
--min-posts MIN_POSTS Fewer posts than this in a group (or the rest) = ‘too little data’ (3..100, default 5)
--resamples RESAMPLES Bootstrap resamples for the approximate interval; 0 = none (200..20000)
--seed SEED Fixed seed: same inputs give identical output
--now NOW Reference time for –since 30d (ISO 8601 with timezone; default now)
--json Machine-readable report (schema reachweaver.insights v1)

Read-only multi-homing report: share of your recorded reach per platform, concentration (HHI), sourced platform risk flags and hypotheses; never sends

Terminal window
reachweaver platform-risk [-h] [--account ID] [--since WHEN]
[--metric {views,impressions}] [--age-hours AGE_HOURS]
[--tolerance-hours TOLERANCE_HOURS] [--owned ID]
[--owned-reach NAME=N] [--owned-posts NAME=N]
[--market MARKET] [--site URL] [--setup FILE] [--now NOW]
[--json]
Option Description
--account ID Only this account
--since WHEN Only posts sent since 30d (days ago), YYYY-MM-DD or an ISO time
--metric METRIC Reach counter (default views) One of: views, impressions.
--age-hours AGE_HOURS Matched post age (24..720 hours, default 168)
--tolerance-hours TOLERANCE_HOURS Snapshot age tolerance (1..168 hours, default 48)
--owned ID Treat this platform or account id as an owned channel (your statement); repeat
--owned-reach NAME=N Reach of an owned channel in the same window, e.g. newsletter=1200 (your own number); repeat
--owned-posts NAME=N Items published on an owned channel in the window, e.g. site=4; repeat
--market MARKET Audience market for market-specific flags: US, global or PLATFORM@MARKET (tiktok@US); repeat
--site URL Your owned site (https), for the canonical-home hint (social-web-plan)
--setup FILE social-web-plan setup JSON, for the canonical-home hint
--now NOW Reference time for –since 30d (ISO 8601 with timezone; default now)
--json Machine-readable report (kind reachweaver.platform-risk v1)

Read-only UTM/referrer join of local analytics exports; NOT causal

Terminal window
reachweaver attribution-report [-h] [--analytics ANALYTICS]
[--github-traffic GITHUB_TRAFFIC] [--ga4-csv CSV]
[--gsc-csv CSV] [--json]
Option Description
--analytics ANALYTICS Website-analytics CSV export (one of –analytics, –ga4-csv or –gsc-csv is required)
--github-traffic GITHUB_TRAFFIC Saved traffic/views or popular/referrers JSON; repeat for both
--ga4-csv CSV GA4 report or exploration downloaded as CSV (Session source / medium, Session campaign, Session manual ad content, Sessions, …); repeat for non-overlapping periods. Local file only
--gsc-csv CSV Search Console Performance export table (Pages, Queries, Dates or Filters CSV); repeat, one per table. Search-side context only, never credited to a post. Local file only
--json Full machine-readable report

Offline per-arm readout of an owner field-pilot CSV log; descriptive, never causal

Terminal window
reachweaver pilot-report [-h] --log LOG [--min-weeks MIN_WEEKS] [--json]
Option Description
--log LOG Operations log CSV (examples/pilot-log.template.csv)
--min-weeks MIN_WEEKS Refuse the arm comparison unless every logged arm covers N ISO weeks (default 2)
--json Machine-readable report

Offline: compare your public counters with peers’ public counters that you copied by hand into a local file (#11); no fetching, no logins, nothing stored

Terminal window
reachweaver peer-benchmark [-h] --file FILE [--platform PLATFORM]
[--include-individuals] [--now NOW] [--json]
Option Description
--file FILE Local JSON (schema reachweaver.peer-benchmark.v1); see examples/peer-benchmark.example.json
--platform PLATFORM Only this platform id
--include-individuals Also accept kind: person entries (excluded by default; privacy check first)
--now NOW Reference time for the staleness warning (ISO 8601 with offset); default: the current time
--json Machine-readable result

Read-only ranked human review of profile, posts, SEO, engagement, experiments and local queue; with no input flag it reads an existing local database (query-only) and the ideas inbox

Terminal window
reachweaver suggest [-h] [--snapshot SNAPSHOT] [--metrics-csv METRICS_CSV]
[--owner-authorized] [--engagement-export ENGAGEMENT_EXPORT]
[--seo-briefs SEO_BRIEFS] [--experiments EXPERIMENTS]
[--include-db] [--limit LIMIT] [--json]
Option Description
--snapshot SNAPSHOT Owner-supplied profile/post snapshot (local JSON, no remote access)
--metrics-csv METRICS_CSV Optional normalized owner-authorized native post CSV, merged only in memory
--owner-authorized Explicitly confirm the metrics CSV was lawfully exported from your own account
--engagement-export ENGAGEMENT_EXPORT Existing owner-exported engagement JSON; only aggregate labels are returned
--seo-briefs SEO_BRIEFS Local SEO export already used by seo-destinations
--experiments EXPERIMENTS Local classified experiment results JSON list
--include-db Explicitly read an EXISTING local SQLite DB in query-only mode
--limit LIMIT Show 1..50 ranked review tasks (default 10)
--json Machine-readable curated findings; no raw comments or profile text

Write suggest (and with –include-db the local report) as one private Markdown file; local only, never sent

Terminal window
reachweaver weekly-digest [-h] --out OUT [--snapshot SNAPSHOT]
[--metrics-csv METRICS_CSV] [--owner-authorized]
[--engagement-export ENGAGEMENT_EXPORT]
[--seo-briefs SEO_BRIEFS] [--experiments EXPERIMENTS]
[--include-db] [--limit LIMIT]
Option Description
--out OUT NEW Markdown file (mode 0600); refuses an existing file or symlink
--snapshot SNAPSHOT Owner-supplied profile/post snapshot (local JSON, no remote access)
--metrics-csv METRICS_CSV Optional normalized owner-authorized native post CSV, merged only in memory
--owner-authorized Confirm the metrics CSV was lawfully exported from your own account
--engagement-export ENGAGEMENT_EXPORT Existing owner-exported engagement JSON; only aggregate labels are used
--seo-briefs SEO_BRIEFS Local SEO export already used by seo-destinations
--experiments EXPERIMENTS Local classified experiment results JSON list
--include-db Also read an EXISTING local SQLite DB in query-only mode (queue health and report)
--limit LIMIT Show 1..50 ranked review tasks (default 10)