Reach-splitten (in/out-of-network) er native i LinkedIns post-analytics siden juni 2026, men vises som PROSENT og finnes ikke i CSV-eksporten. Planen antok to manuelle antall; verifiseringen viste prosent, så modellen er ett felt — outOfNetworkPct — og in-network er komplementet. - parseOptionalPercent: egen parser, ikke parseOptionalCount. Komma er desimal (36,5 -> 36.5, aldri 365), og verdi >100 avvises: i én kolonne kan ikke et absolutt antall skilles fra en andel, så svaret er unknown, ikke en gjetning. Blank/ikke-numerisk/negativ -> unknown; ekte 0 beholdes. - Ett lagret halvpart, kryssjekket: In-network godtas og lagres som komplement; et transkribert par som ikke summerer til ~100 (±1 avrunding) forkastes som unknown i stedet for å bli halvveis trodd. - weightedOutOfNetworkPct: impressions-vektet roll-up (avgOutOfNetworkPct, uke + måned). Flatt snitt lar en 50-visnings-post slå en på 10 000; poster uten avlesning ekskluderes, og null vekt gir undefined — aldri 0, aldri NaN. - Reach inngår ALDRI i engagementRate (distribusjon != engasjement). Rapporten leser den som akvisisjon (ut) vs resonans (inn), og sier «ikke ført for denne perioden» framfor å estimere. En reach-innsikt går inn i N15s do-next-kanal. - Step 7c (A2-F11): rapporten tilbyr diff mot brukerens engagement-patterns.md med eksplisitt go — aldri stille skriving, aldri inn i den shippede malen. - Boundary-map (E#9): dwell eksplisitt umålbar, saves partner-gated, reach native men CSV-eksport uverifisert. - Reach-frie importer er byte-identiske med før, på skjerm og på disk. TDD: rødt bevist først (10 feilende), analytics 119 -> 144 tester, tsc ren. test-runner 232 -> 247 (Section 16w, gulv 213 -> 228). Alle suiter grønne. CHANGELOG: N15-oppføringen manglet og er backfilt sammen med N16. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QxvWAjte7vPcF79QeSRvRJ
5.2 KiB
LinkedIn Analytics Data
This directory contains imported analytics data from LinkedIn CSV exports.
How to Import
- Go to LinkedIn Creator Analytics
- Click Export to download a CSV of your content analytics
- Save the CSV file to
exports/directory - Run
/linkedin:importin Claude Code
Optional: add per-post saves (manual)
LinkedIn's CSV export does not include saves, and there is no self-serve API
to pull them — but the per-post save count is visible in your native post
analytics (since ~Sept 2025). To track it, add a Saves column to the CSV and
type the count you read off LinkedIn. The importer picks it up automatically when
the column is present:
"Content","Date","Impressions","Reactions","Comments","Shares","Clicks","Saves"
"My post...",2026-02-10,5000,100,30,15,200,42
A missing column — or a blank Saves cell — leaves saves unknown (never
counted as 0), and saves is not folded into the engagement rate (which stays
comparable to older imports). Saves is the strongest organic engagement signal,
so the reports surface it as its own line. Dwell time stays unmeasurable —
it is internal to LinkedIn for organic posts, with no count to transcribe.
Optional: add the out-of-network reach share (manual)
LinkedIn splits a post's impressions into in-network (people who already follow or are connected to you) and out-of-network (people who found it through recommendations, reshares or search). It sits in your post analytics under Discovery, beneath the impressions count — a global rollout that began in June 2026 — and it is shown as percentages, not as two counts. It is not in the CSV export, and whether it will ever be exported is unverified.
To track it, add an Out-of-network column and type the percentage you read off
that panel. The % sign is optional:
"Content","Date","Impressions","Reactions","Comments","Shares","Clicks","Out-of-network"
"My post...",2026-03-10,5000,100,30,15,200,37%
Details worth knowing:
- Either half works. An
In-networkcolumn is accepted instead and stored as its complement (In-network 63%→ out-of-network 37). Only the out-of-network share is kept, because the two halves describe one split — storing both would let a record contradict itself. - Both halves are cross-checked. If you transcribe both and they do not sum to ~100 (one point of rounding slack allowed), the reading is discarded as unknown rather than guessing which cell was misread.
- Percent, not a count. A value above 100 is refused (
unknown): in one column an absolute impression count and a share are indistinguishable, so the importer will not guess. A comma is read as a decimal mark (36,5→ 36.5%). - Unknown is never 0. A missing column, a blank cell, or a non-numeric cell
leaves the share unknown. A genuine
0is kept — nothing left your network. - Not part of the engagement rate. Reach is a distribution signal, not engagement: a high out-of-network share means the post acquired new audience, while high in-network engagement means it deepened the audience you already have. Roll-ups are impressions-weighted, so a small post with a high share cannot outvote a large one.
Directory Structure
analytics/
├── exports/ # Place LinkedIn CSV exports here
├── posts/ # Auto-generated: imported post data (JSON)
├── weekly-reports/ # Auto-generated: weekly performance reports (JSON)
└── README.md # This file
Data Format
Post Analytics (posts/*.json)
Each file contains a batch of imported posts:
{
"batchId": "batch-...",
"importedAt": "2026-01-29T...",
"exportFilename": "content-analytics.csv",
"dateRange": { "from": "2026-01-13", "to": "2026-01-28" },
"postCount": 8,
"posts": [
{
"id": "abc123",
"title": "First 100 chars of post...",
"publishedDate": "2026-01-28",
"metrics": {
"impressions": 4523,
"reactions": 87,
"comments": 23,
"shares": 12,
"clicks": 156,
"engagementRate": 6.15
}
}
]
}
metrics.saves is optional — present only on posts where you supplied a
Saves column value (see "Optional: add per-post saves" above). Posts without
it omit the field entirely, so older imports round-trip unchanged.
Weekly Reports (weekly-reports/*.json)
Generated via /linkedin:report. Contains:
- Summary metrics (totals, averages)
- Top and underperforming posts
- Week-over-week trends
- Performance alerts (spikes, drops)
CLI Usage
The analytics CLI can also be invoked directly:
# Import a CSV export
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts import <filename>
# Generate weekly report
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts report --week 2026-W05
# Analyze trends
ANALYTICS_ROOT=./assets/analytics node --import tsx scripts/analytics/src/cli.ts trends --period month --metric impressions
Privacy
All data in this directory (except this README) is gitignored. Your analytics data stays local.