AI content labels: which label to apply, per platform
Status: ai-label-check released in 0.14.0 (advisory); the approval precondition for posts with media since 0.15.0. Platforms and lawmakers now ask people to say when what they post was made with AI. The rules differ by platform, change often, and mostly concern realistic images, video and audio rather than text. ai-label-check reads one draft and tells you, for each platform you target, whether the platform’s own rule asks for a label, what to tick in the platform’s own composer, and which page says so.
The command itself never blocks, approves, schedules or sends anything. Since the owner-approved change of 2026-10-21, approve of a post with images or a video asks for your answer when the decision for the post’s platform is required or unknown; see When approval asks for an answer. Text-only posts are never blocked.
Not legal advice. Rules change: re-verify. Every rule below was read on 2026-10-21 from the page linked next to it. Before you rely on an entry, open that page again. The EU AI Act wording comes from a secondary site (artificialintelligenceact.eu), not from the Official Journal. Whether a law applies to you is a legal question for you or a qualified lawyer.
Run it
Section titled “Run it”# A campaign or draft file: authorship is read from the file, or set it yourselfreachweaver ai-label-check --file examples/campaign.reachweaver.json --authorship ai_generated
# Several platforms, with the media manifest that says which asset is realistic AI-made mediareachweaver ai-label-check --file draft.json --platform youtube,instagram,tiktok --media media-manifest.json
# A stored post (database opened read-only): uses what you recorded with ai-declare; --authorship overrides it oncereachweaver ai-label-check --post-id POST_ID --authorship ai_assisted --platform linkedin
# Also check the EU AI Act Article 50 duty (you publish from, or for an audience in, the EU)reachweaver ai-label-check --file draft.json --eu --public-interest yes --editorial-review no --jsonInputs:
--filetakes a draft (authorship,platformorplatforms), a variant (platform) or a campaign (variants, each with aplatformand optionally its ownauthorship).--post-idreads one stored post instead.--authorship human|ai_assisted|ai_generatedis the draft schema’sauthorshipfield (SCHEMAS.md). For a stored post, the authorship you recorded withai-declareis used; without either, it is checked asunknown.--mediareads a media manifest (MEDIA-ASSETS.md). Two fields decide the answer:provenance.created_by(owner,tool,third_party) and the optionalrealistic_syntheticflag:truewhen the image or video was made or meaningfully altered with AI and looks real. An asset withtargetscounts only for those platforms. Without--media, a stored post’s images and video are read from the database together with therealistic_syntheticanswers you recorded withai-declare; media with no answer and nocreated_by ownercomes backunknown.--eu,--public-interest yes|noand--editorial-review yes|noadd the EU AI Act Article 50 check below.
Each target gets one of four answers: required (the cited rule asks you to disclose or label it), recommended (the rule labels or asks about it but does not clearly require it here), not required (the cited rules do not ask for a label in this case), or unknown (a fact is missing, or the platform’s rule was not verified). The output also names the native control to tick, the API field where ReachWeaver already knows one (it sends nothing here), whether the platform reads C2PA Content Credentials, and the consequence the platform states. --json prints the same as JSON. The command exits 0 after a check and 2 on an input error.
Platform rules (checked 2026-10-21)
Section titled “Platform rules (checked 2026-10-21)”| Platform | When a label is required | What to tick | Reads C2PA | Stated consequence | Source |
|---|---|---|---|---|---|
| YouTube | Realistic content made or meaningfully altered with AI (a real person saying or doing something they did not, altered footage of a real event or place, a realistic scene that did not happen, AI music as the main focus). AI help with a script, title or thumbnail needs no disclosure. | YouTube Studio upload > Attributes > “AI use”: Yes. API: status.containsSyntheticMedia |
Yes | Manual label, removal, or suspension from the YouTube Partner Program for creators who consistently do not disclose | help, API |
| Instagram, Facebook, Threads (Meta) | Organic posts with photorealistic video or realistic-sounding audio that was digitally created or altered. Realistic images: recommended, Meta labels them “AI info” when it detects C2PA or IPTC indicators. | Meta’s AI disclosure / label tool in the composer (exact setting name not verified) | Yes (C2PA and IPTC) | Meta “may apply penalties” | Feb 2024, Apr 2024 |
| TikTok | AI-generated or significantly edited content that shows realistic-looking scenes or people (Community Guidelines effective 2026-09-24). | The creator AI-generated content label, or a sticker or caption (exact in-app name not verified). API: post_info.is_aigc |
Yes | Unlabeled content may be removed, restricted or labelled by TikTok | guidelines, label tool, C2PA, API |
| Synthetic or manipulated media that depicts a person saying or doing something they did not must clearly disclose that it is fake or altered. Other realistic AI-made media: recommended. | Say it in the post; where offered (select countries), self-attest on upload that the media was created using AI | Yes | Not stated on the cited pages | policy, Content Credentials | |
| X | Unknown. The policy page returned a browser challenge to a plain request on 2026-10-21, so nothing about X is asserted. | Check X’s policy yourself | Unknown | Unknown | manipulated media policy (not read) |
| Chinese platforms (Weibo, Xiaohongshu, Douyin, Bilibili, WeChat and the others in CHINA.md) | Anyone who publishes AI-generated or synthesized content must declare it and use the platform’s labelling function (CAC measures, Art. 10, in force since 2025-09-01). | The composer’s own AI declaration (for example Xiaohongshu 笔记含AI合成内容) | n/a | See CHINA.md | reachweaver/china.py (source cited there) |
For every other platform the answer is unknown: no rule is recorded, so check the platform’s own pages.
AI-written text alone needs no platform label on any verified platform above: the cited rules are about realistic images, video and audio, and YouTube lists AI help with a script or title as production assistance that needs no disclosure. China’s rule and the EU rule below are different.
EU AI Act, Article 50 (secondary source, not legal advice)
Section titled “EU AI Act, Article 50 (secondary source, not legal advice)”The AI Act “shall apply from 2 August 2026” (Art. 113). Article 50(4) puts two transparency duties on deployers of an AI system:
- Deep fakes. A deployer of a system that generates or manipulates image, audio or video content constituting a deep fake “shall disclose that the content has been artificially generated or manipulated”. A deep fake is content that “resembles existing persons, objects, places, entities or events and would falsely appear to a person to be authentic or truthful” (Art. 3(60)). For an evidently artistic, creative, satirical or fictional work, the duty is limited to disclosing that such content exists, in a way that does not hamper the work.
- Text on matters of public interest. A deployer of a system “that generates or manipulates text which is published with the purpose of informing the public on matters of public interest shall disclose that the text has been artificially generated or manipulated”. This does not apply “where the AI-generated content has undergone a process of human review or editorial control and where a natural or legal person holds editorial responsibility for the publication of the content.”
The disclosure must be given “in a clear and distinguishable manner at the latest at the time of the first interaction or exposure” (Art. 50(5)). “Deployer” excludes use “in the course of a personal non-professional activity” (Art. 3(4)). Penalties are not summarised here.
With --eu, ai-label-check reports: realistic synthetic media is required; AI-generated text on a matter of public interest is required unless you answer --editorial-review yes (then not required, the exemption); --public-interest no makes the text duty not required; a missing answer, or ai_assisted text without review, is unknown. The tool cannot decide whether you are a deployer, whether a post is “public interest” or whether your review counts as editorial control.
When approval asks for an answer
Section titled “When approval asks for an answer”Owner-approved on 2026-10-21 after a security review (decisions D1-D4 and D6; D5, filling TikTok is_aigc or YouTube containsSyntheticMedia from your answer, is not part of it).
Which posts. Only posts that carry images or a video. approve computes the same platform decision ai-label-check --post-id prints, for the post’s own platform, from what is stored on the post: your authorship, your realistic_synthetic answer per attachment and the image’s recorded provenance.created_by. The EU Art. 50 duty is left out (D4: advisory only). When the decision is required or unknown (D2), approval is refused with ai_label_unanswered until you answer. A text-only post is never blocked: check and show print the advice and nothing else changes.
How you answer. Two ways, both recorded by you and bound into the approval:
# 1. Record what is true about the post; this may settle it (for example a non-realistic image on Instagram)reachweaver ai-declare POST_ID --realistic-synthetic no # every attachment; --attachment N for onereachweaver ai-declare POST_ID --authorship ai_assisted # who wrote the text (human|ai_assisted|ai_generated)reachweaver check POST_ID # prints "AI label (PLATFORM): DECISION; ..."
# 2. Answer the label question itself when you approve (owner, in your own terminal)reachweaver approve POST_ID --ai-label applied # you label it yourself: platform composer or the post textreachweaver approve POST_ID --ai-label not_needed # you decided no label is neededapplied records that you label the post. ReachWeaver sets no platform label field in this change: for a manual post, tick the control named under “Tick:”; for a disabled video adapter, the TikTok record’s own --aigc option is separate and unchanged.
Some decisions can only be settled with --ai-label: realistic video on Instagram, Facebook, Threads, YouTube or TikTok is required, and a platform with no recorded rule (Mastodon, for example, or X, whose page was not read) is always unknown.
What is bound. For a post with media, the approval hash binds authorship, realistic_synthetic_json and approved_ai_label under the add-on tag reachweaver.storage.approval/media-3 (key ai_label_binding, next to the media-1, media-2 or video-1 tag) whenever one of them is set. Changing any of them after approval refuses the send with approval_hash_mismatch_reapproval_required. Declarations can only change on a draft. The approve audit event records ai_label_decision=DECISION ai_label=ANSWER|none. The registry file is not bound: updating it never silently invalidates an approval.
At send time. publish (dry run and --live), schedule, health and the claim re-run the same decision on the bound values and the bundled registry (no fetch, no network). A media post that needs an answer and has none bound is refused with ai_label_unanswered and stays approved or scheduled. This happens to a media post approved before the upgrade (no grandfathering), and to one whose decision became required or unknown because the bundled rules changed in an update. Re-approve it: reachweaver unapprove POST_ID, reachweaver show POST_ID, then approve with --ai-label.
Registry age. health adds ai_disclosure_registry_aging (attention, never blocks) when the oldest checked date in ai_disclosure_registry.json is more than 90 days old, and ai_disclosure_registry_invalid when the file cannot be loaded; in that case every media post needs an explicit --ai-label.
Limits. Every input is your declaration: ReachWeaver cannot see how a file was made. A bound answer proves that you answered, not that the answer or the label was right; the platform may still label or act on the post itself.
What it is not
Section titled “What it is not”- Not a label setter. The approval precondition above makes you answer for posts with media; it does not set any label on the platform, and
ai-label-checkitself still blocks nothing. - Not an AI detector. ReachWeaver cannot see how a file or text was made. It uses what you record:
authorship,provenance.created_byandrealistic_synthetic. - Not a guarantee. A platform may label your post itself (from C2PA metadata or its own classifiers) whatever you tick.
Keeping it current
Section titled “Keeping it current”The rules live in reachweaver/ai_disclosure_registry.json: each entry cites a URL, the exact quote read there and the date. tests/test_ai_labels.py checks the file’s structure (every decision cites a page that was actually read, EU sources are marked secondary, an unverified platform can only answer unknown). It cannot check that a page still says the same thing: re-read each source, update the quote and checked_on, then run python3 scripts/sync_skill.py and the tests.
Human review evidence report (eu-review-evidence)
Section titled “Human review evidence report (eu-review-evidence)”Evidence of human review recorded by ReachWeaver; not legal advice; wording from a secondary source (artificialintelligenceact.eu); verify on EUR-Lex.
The Article 50(4) text duty does not apply “where the AI-generated content has undergone a process of human review or editorial control and where a natural or legal person holds editorial responsibility for the publication of the content” (Art. 50, secondary site, checked 2026-10-21). reachweaver eu-review-evidence lists, for each published post, what ReachWeaver recorded about the human approval, so you can keep it with your own records:
python3 -m reachweaver eu-review-evidence # text, newest firstpython3 -m reachweaver eu-review-evidence --since 30d --account my-linkedin --format markdown > review-evidence.mdpython3 -m reachweaver eu-review-evidence --post-id ID --jsonPer post it shows:
| Field | Where it comes from |
|---|---|
approved_at, approved_by, approver_source |
The post row. approver_source says how the name was obtained: typed with approve --approver, the operating-system user name, none, or a library call. |
approved_payload_sha256 |
The approval hash stored at approve (it binds the exact text, account, media and schedule). |
text_sha256 |
SHA-256 of the stored post text, to match the published text. |
human_confirmation |
tty_hash_prefix when the opt-in human-presence check (approval-mode --confirmation) was used for the approval; only that fixed token of the audit event is read. |
ledger |
The approval-ledger line for the post’s approval nonce: consumed with its time and whether its payload hash equals the row’s; no_nonce for posts approved before the ledger existed; ledger_unreadable when the ledger is missing or its hash chain is broken. The report also carries ledger.audit’s integrity status. |
authorship |
The stored authorship declaration, when the database has an authorship column; otherwise “not recorded”. |
evidence |
recorded (approval time, payload hash, a named approver and a matching consumed ledger line), partial (time and hash, but no name or no matching ledger line) or missing (no approval time or no payload hash). gaps lists what is missing. |
--json and --format markdown carry the same notice, the exemption wording with its source and date, and the limits below.
Strictly read-only. The database is opened read-only and the ledger file is opened read-only through the ledger’s own reader and chain check. Nothing is created, migrated, repaired, approved or sent; a missing or broken ledger is reported, never fixed.
What it does not show. An approval records that someone ran approve for this exact payload, not that the text was read, edited or fact-checked. ReachWeaver does not record who holds editorial responsibility for the publication, which the exemption also requires. approved_by is what the approver typed or what the operating system reported, not an authenticated identity. The ledger is editable by the same Unix user; its hash chain makes in-place edits detectable, not impossible. Whether you are a deployer, whether a post informs the public on matters of public interest and whether your review counts as editorial control are legal questions for you or a qualified lawyer.
