Publishing platform matrix — assessed 2026-10-08, reconciled with the registries 2026-10-09
This page is the human-readable view of what ReachWeaver itself can deliver per platform. It is derived from two machine-readable registries and the code, and a test keeps them in step:
reachweaver/platform_registry.json(shown byreachweaver capabilities, validated byreachweaver/capabilities.py): per-format API capability, thereachweaver_adaptervalue (live_textornonein the bundled registry;live_mediais also valid), the off-by-defaultlive_media_formats,reachweaver_reply_adapterand video switches, auth, approval and metrics facts with sources. Details: PLATFORMS.md.reachweaver/distribution_registry.json(validated byreachweaver/distribution.py): the native scheduling mode of each surface, with its official source. Details: DISTRIBUTION-GOVERNANCE.md.reachweaver/postiz.py(PROVIDERS/EXCLUDED): which platforms the optional Postiz backend accepts. Details: POSTIZ.md.
tests/test_platform_matrix_docs.py fails when the table below disagrees with those sources. If you change a registry or the Postiz mapping, update this table in the same change.
Separate audit registry: profile_audit_registry.json and profile/post audit guide provide offline, platform-specific owner-profile checks and content hypotheses. They do not grant API scopes, change adapter status, inspect accounts automatically or permit publishing. For native publishing availability use the original two registries below instead.
Three layers that must never be merged
Section titled “Three layers that must never be merged”| Layer | What it means | Where it is recorded | Evidence that exists today |
|---|---|---|---|
| Native platform scheduling | The owner can schedule a post in the platform’s own app or web UI. ReachWeaver plays no part. | scheduling.mode in the distribution registry, each with an official source |
Official help pages only |
| Mock-tested ReachWeaver adapter | ReachWeaver code can send one approved text post through the official API. Tested with mocked HTTP only. | reachweaver_adapter: live_text in the platform registry; policy.SUPPORTED_LIVE |
Offline unit tests |
| Real owner account receipt | A real owner account was connected and a ReachWeaver send produced a native post the owner confirmed. | Would be a dated pilot record (FIRST-LIVE-PILOT.md, FIELD-PILOT-PROTOCOL.md) | Bluesky and Mastodon: one text post each, 2026-10-11 (files listed in the Owner live receipt column). No other platform. |
A native scheduler never implies a ReachWeaver adapter, and an adapter never implies a receipt. A suggested time from calendar-plan is not a provider queue receipt. A Postiz acceptance is not a platform receipt either (see the backend table).
Adapter matrix
Section titled “Adapter matrix”Column meanings:
- ReachWeaver adapter: the registry’s
reachweaver_adaptervalue.live_text= one approved text post via the official API, mock-tested only.none= no ReachWeaver send path; the manual alternative follows (the same one TROUBLESHOOTING.md lists). - Via Postiz backend:
allowedmeans an owner may opt that account into the Postiz backend; it is still mock-tested only and still behind every ReachWeaver approval gate.refusedmeanspostiz.pyrejects the account configuration. - Native scheduling: the distribution registry’s
scheduling.modefor the same surface (devandfacebook_pagesthere aredevtoandfacebookhere). - Owner live receipt:
noneexcept Bluesky and Mastodon, whose cell shows the date of a checked-in receipt under receipts/ (the same file the readiness scorecard names). It may change only with a dated native post URL from a real send, a receipt file and a scorecard update, whichtests/test_platform_matrix_docs.pyrequires to agree. - Media: ReachWeaver uploads no media on any platform. Mock-tested media adapters exist for Mastodon images (#13, proposal), Instagram single images (#20), YouTube video (#22) and TikTok creator-inbox video (#23), all owner-approved 2026-10-09 and disabled until a live receipt: the capability registry lists no
live_media_formats, every video switch isoffandpolicy.SUPPORTED_LIVE_VIDEOis empty, so no upload path is reachable. The column lists the offline tools that cover the platform:media-check(sourced per-platform limits inmedia.CONSTRAINTS),media-storyboard(video targets and image specs instoryboard.py) andmanual-export(creator packages inmanual_export.py). - Analytics:
metricsandimport-metricsrecord owner-exported native snapshots for every platform. Only Bluesky and Mastodon also havemetrics-fetch --online.
| Platform | Registry id | ReachWeaver adapter | Via Postiz backend | Native scheduling | Owner live receipt | Onboarding dependency | Media | Analytics |
|---|---|---|---|---|---|---|---|---|
| Bluesky | bluesky |
live_text: text only, mock-tested |
allowed |
third_party: no general native scheduler confirmed |
2026-10-11: receipt |
App Password session + exact handle (optional HTTPS PDS service); connect-check --online verifies the session handle, not write scope |
No upload. media-check image/video limits; media-storyboard image spec (1200x675, unverified convention) |
metrics-fetch --online: public likes, reposts, replies, bookmarks from the public AppView, no credential sent. Views, impressions, clicks unknown |
| Mastodon | mastodon |
live_text: text only, mock-tested |
allowed |
api_or_client: server API supports scheduling; ReachWeaver uses a local due time |
2026-10-11: receipt |
Instance user token with write:statuses + expected local handle; connect-check --online verifies the token user (not write scope) and reads /api/v2/instance limits |
No upload. media-check image/video limits; media-storyboard image spec (1200x675, unverified convention) |
metrics-fetch --online: public favourites, reblogs, replies; unauthenticated first, one retry with {env_prefix}_TOKEN on 401/404. Views, impressions, clicks unknown |
| Telegram | telegram |
live_text: channel text only, mock-tested |
allowed |
native: in-app scheduling |
none |
Bot token, expected bot_username, exact channel; connect-check --online verifies bot/channel identity and admin posting rights |
No upload. No sourced Telegram limits in the media-check table | Channel statistics in the native app only; metrics/import-metrics |
linkedin |
live_text: personal profile (member) text only, mock-tested; organization pages refused |
allowed (linkedin or linkedin-page integration) |
native_conditional: member/Page UI differs |
none |
Own developer app with Share on LinkedIn (w_member_social) + OpenID Connect (openid profile); member token; person_id = userinfo sub; pinned linkedin_version; connect-check --online compares sub with person_id (not write scope). See LINKEDIN.md |
No upload (image/video are api_direct in the registry but have no adapter). media-check image/video limits; media-storyboard image draft (1200x627, unverified convention) |
r_member_social is restricted; owner-exported native snapshots via metrics/import-metrics only |
|
| X | x |
none: campaign-export text draft |
refused: needs the #24 cost ceiling |
native_conditional: X Pro/eligible accounts |
none |
Developer Console, pay-per-use credits and an owner-defined spending cap (go/no-go in PLATFORMS.md) | None | Manual native export |
| Threads | threads |
none: manual-export package; a mock-tested text adapter (issue #19, owner-approved 2026-10-09; disabled until a live receipt) stays registry-blocked |
allowed (Meta permissions held by the owner’s Postiz connection) |
native_conditional: in-app scheduler (secondary reports: up to 75 days, no replies); recheck the composer |
none |
Meta app + Threads OAuth; app review for publishing beyond test users | manual-export (text, link, image, video, carousel; attached media validated with the media-check rules; no Threads limit table) |
Manual import |
instagram |
none: manual-export package; a mock-tested single-image adapter (issue #20, owner-approved 2026-10-09; disabled until a live receipt) stays registry-blocked (INSTAGRAM.md) |
refused: text-only posts unavailable |
unverified |
none |
Professional (Business or Creator) account; Business-type Meta app with Instagram Login (instagram_business_basic + instagram_business_content_publish, no Facebook Page). Standard Access covers your own account; App Review and Business Verification only to serve accounts you do not own or manage. Consumer accounts refused. Official API facts verified 2026-10-15 (INSTAGRAM-SETUP.md) |
Adapter scope (mock-tested, registry-blocked; facts verified 2026-10-15): one JPEG feed image, at most 8 MB, aspect ratio 4:5 to 1.91:1, alt text up to 1,000 characters, caption up to 2,200 characters, 30 hashtags and 20 @ tags; no carousel, video, reel or story. media-check image/video limits; media-storyboard video target, 4:5 image spec and unverified safe zone; manual-export (image, video, carousel; media required; the fallback for personal or unsupported accounts) |
Manual import | |
| Facebook Pages | facebook |
none: manual-export package (Pages only); a mock-tested Page text/link adapter (issue #21, owner-approved 2026-10-09; disabled until a live receipt) stays registry-blocked (FACEBOOK.md) |
allowed (Page post defaults) |
unverified |
none |
Page access token, Page role and Meta app review; doctor names the eligible Page and the required permissions next to an owner-declared, unverified list; profiles and groups refused (Page feed reference, User feed reference, v19.0 changelog, checked 2026-10-15) |
manual-export (text, link, image, video) |
Manual import |
| TikTok | tiktok |
none: manual-export package; a mock-tested creator-inbox video adapter (issue #23, owner-approved 2026-10-09; disabled until a live receipt) stays off (video switches off, empty SUPPORTED_LIVE_VIDEO; TIKTOK.md) |
refused: text unknown (video-only) |
native_conditional: eligible accounts, browser scheduler |
none |
Content Posting API approval and app audit; unaudited clients are private-only | media-check image/video limits; media-storyboard video target, image spec and unverified safe zone; manual-export (video required; privacy left unselected) |
Manual import |
| YouTube | youtube |
none: manual-export package; a mock-tested resumable-upload adapter (issue #22, owner-approved 2026-10-09; disabled until a live receipt) stays off (reachweaver_video_upload off, empty SUPPORTED_LIVE_VIDEO; YOUTUBE.md) |
refused: text unknown (video-only) |
native: YouTube Studio |
none |
Google OAuth + upload scope; unverified API projects may be private-only | media-check youtube_shorts video limits; media-storyboard youtube_shorts target and unverified safe zone; manual-export (video) |
Manual import |
reddit |
none: human-only, ReachWeaver writes no Reddit text |
refused: human-only, moderator-only scheduling |
moderator_only |
none |
Data API access needs a reviewed request; community rules apply | None | Manual native observation only; no scraping | |
pinterest |
none: campaign-export text draft |
refused: text-only Pins unavailable |
native_conditional: business accounts |
none |
OAuth app approval (Trial, then Standard access); go/no-go in PLATFORMS.md | None (owner-supplied media) | Manual import | |
| DEV Community | devto |
none: campaign-export Markdown draft, human-authored |
refused: manual-export platform |
native: article editor (official help) |
none |
Native editor; no ReachWeaver OAuth/API adapter | No upload. media-check cover-image aspect (about 1000x420, warning only); file type and size limits are not stated by DEV |
Native dashboard; manual import |
| Hashnode | hashnode |
none: campaign-export Markdown draft |
refused: manual-export platform |
native_conditional: Hashnode Pro (June 2026 changelog) |
none |
Paid plan needed for GraphQL publishing and scheduled publishing; no ReachWeaver adapter | None | Native dashboard; manual import |
Publishing backend
Section titled “Publishing backend”| Backend | Kind | ReachWeaver status | Platforms | Approval authority | Owner live receipt |
|---|---|---|---|---|---|
| Postiz | postiz |
Optional, owner opt-in per account ("backend": "postiz"); cloud or self-hosted instance; REST API only (MCP not used); mock-tested only, no instance or account connected |
bluesky, mastodon, telegram, threads, linkedin, facebook |
ReachWeaver only: per-item approval, publish --live with the live environment flag, emergency stop, budgets and the approval hash all still apply; Postiz type now only, never Postiz drafts, schedules or approvals |
none: a Postiz acceptance sets needs_review with remote_id postiz:<id> until the owner confirms the native post and runs reconcile |
metrics-fetch skips Postiz-backed posts (backend_account_remote_id_is_not_a_platform_id), because postiz:<id> is not a platform post id. The owner smoke test for Postiz is documented and not run. There is no Postiz receipt in receipts/. Full flow, verified Postiz API facts and sources: POSTIZ.md, ADR-0001.
draft and export mean that a text draft or package can be prepared locally; neither implies an integrated platform API. Neither skills nor provider marketing pages authorize bypassing platform app review. Recheck official documentation before adding any API integration.
The distribution registry tracks 110 planning surfaces, including country and community channels that have no row here. None has a connected owner account in ReachWeaver. Only the four live_text adapters above (Bluesky, Mastodon, Telegram, LinkedIn member) are enabled, and they are mock-tested only. The Threads, Instagram, Facebook Page, YouTube and TikTok adapters, Mastodon images and Bluesky/Mastodon replies are mock-tested too but disabled until a live receipt, so those surfaces stay manual; every other surface is manual, draft or not applicable.
Official references: Bluesky, Mastodon, Telegram, Facebook Pages (Page feed, User feed and Groups removal re-checked 2026-10-15, FACEBOOK.md), LinkedIn, TikTok, YouTube, Postiz public API. Public-counter sources for metrics-fetch are cited in reachweaver/metrics_fetch.py (Bluesky app.bsky.feed.getPosts lexicon; Mastodon GET /api/v1/statuses/:id and the Status entity, fetched 2026-10-08).
Operational truth: nobody’s account has been authorized or tested here. The live_text adapters and the Postiz backend are API-shaped implementations with mocked unit tests, not verified integrations or guarantees of delivery. Accounts must be linked and tested with explicit owner involvement.
Online connection check (2026-10-08): connect-check --account ID --online performs authenticated identity probes without posting, for Bluesky, Mastodon, Telegram and LinkedIn. The Instagram, TikTok, YouTube, Threads and Facebook probes exist but are refused before any credential read while those adapters are disabled. postiz-check --account ID --online is the read-only equivalent for a Postiz-backed account. Both were verified only by offline mocked tests. Review provider scopes and permissions on the day of the pilot.
Planning versus posting: calendar-plan proposes audience-local timing for configured accounts, but cannot send or remotely queue posts on platforms whose adapter is none. The optional --apply records local due times only for already-approved Bluesky, Mastodon, Telegram and LinkedIn member text posts. Other platforms need native scheduling by the owner, official app permissions or a future consented adapter. Full instructions: calendar planner.
Regional official APIs (issue #68): the regional API feasibility matrix records what the official Douyin, LINE, WeChat, Bilibili, Weibo, Xiaohongshu and Kuaishou developer documentation says about posting. It is research only: none of those surfaces gains a row in the adapter matrix above, a ReachWeaver adapter or a receipt.
Research-only registry surfaces (issues #13 to #37)
Section titled “Research-only registry surfaces (issues #13 to #37)”These surfaces are in reachweaver/distribution_registry.json as planning metadata. None has a ReachWeaver adapter, a connected owner account or a live receipt: every one is manual_only, and human_only surfaces are never drafted or scheduled by a tool. “Native scheduling” is what the platform itself offers (unverified means no official page was found that says), never something ReachWeaver does for you. The last column says what could not be verified. Entries dated 2026-10-14 come from the regional-channels research (#64); those dated 2026-10-15 from the community and creator batch (notes). This table is checked against the registry by tests/test_distribution.py; edit the registry first, then the row.
| Surface | Registry id | Category | ReachWeaver delivery | Human only | Native scheduling | Checked | Source | Not verified |
|---|---|---|---|---|---|---|---|---|
| Medium | medium |
technical | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Substack | substack |
technical | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Lobsters | lobsters |
community | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Lemmy | lemmy |
community | manual_only |
yes | native_conditional |
2026-10-15 | page | Per-account and plan limits not checked |
| GitHub Discussions | github_discussions |
code | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Hugging Face community posts | huggingface |
community | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Quora | quora |
community | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Stack Overflow / Stack Exchange | stackexchange |
community | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Tumblr | tumblr |
writing | manual_only |
yes | native |
2026-10-15 | page | Per-account and plan limits not checked |
xing |
professional | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced | |
| VK | vk |
microblog | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Naver Blog | naver_blog |
technical | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Naver Cafe | naver_cafe |
community | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| KakaoTalk Open Chat | kakao_openchat |
messaging | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Kakao Talk Channel | kakao_talk_channel |
messaging | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| LINE OpenChat | line_openchat |
messaging | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| LINE Official Account | line_official_account |
messaging | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Beehiiv | beehiiv |
writing | manual_only |
no | native_conditional |
2026-10-15 | page | Per-account and plan limits not checked |
| Ghost | ghost |
writing | manual_only |
no | native |
2026-10-15 | page | Per-account and plan limits not checked |
| Vimeo | vimeo |
video | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Twitch | twitch |
video | manual_only |
yes | native_conditional |
2026-10-15 | page | Per-account and plan limits not checked |
| Snapchat Spotlight | snapchat |
video | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
flipboard |
writing | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced | |
| ResearchGate | researchgate |
professional | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Behance | behance |
visual | manual_only |
yes | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Dribbble | dribbble |
visual | manual_only |
yes | api_or_client |
2026-10-15 | page | Per-account and plan limits not checked |
| Viber | viber |
messaging | manual_only |
no | unverified |
2026-10-15 | page | Scheduling and automation limits not sourced |
| Slack communities | slack_communities |
community | manual_only |
yes | native_conditional |
2026-10-15 | page | Per-account and plan limits not checked |
