# Commune > Commune turns newsletters into communities. Each newsletter has an > archive of articles, and every article has a chat thread attached to it, so > the discussion lives with the article rather than in a comment box > underneath it. This document is the complete corpus for > https://usecommune.com: how to read any page as Markdown, what those documents > contain, what a caller may and may not read, and where the API > documentation lives. The short index is at https://usecommune.com/llms.txt. ## The Markdown interface Every public reader page on this origin is also served as Markdown. There is no need to fetch HTML and strip it, and no need to run JavaScript. ### Two ways to ask **A `.md` suffix on the reader URL.** This is the primary form, because the consumer is usually a model or an agent that was handed a link: a suffix can be constructed from the link it already has, pasted into a chat, put in a citation, and handed to any HTTP client including ones that cannot set headers. **Content negotiation.** Send `Accept: text/markdown` to the page URL and the same document comes back, at the canonical URL, with no suffix. A page that has a Markdown twin advertises it two ways: a `` in the HTML head, and a `Link: <...>; rel="alternate"; type="text/markdown"` response header. The header is there so a client that fetched the page over HTTP can find the twin without parsing the HTML. ### Every addressable path - `/n/{handle}.md`: a newsletter, and its recent articles - `/n/{handle}/archive.md`: every article, paginated with `?page=N` - `/n/{handle}/a/{slug}.md`: one article: the full body AND its discussion - `/n/{handle}/a/{slug}/chat.md`: just that article's discussion - `/n/{handle}/a/{slug}/chat/{replyId}.md`: one reply under an article's discussion, and its sub-replies - `/n/{handle}/chat/{threadId}.md`: a standalone chat thread - `/n/{handle}/chat/{threadId}/{replyId}.md`: one reply and its sub-replies - `/article/{uuid}.md`: an article by id (the legacy permalink shape) A newsletter served on its own custom domain uses the same paths with the `/n/{handle}` prefix stripped, because on that domain the newsletter is the site. Its landing page is `/index.md` rather than `/.md`, since the root has no last segment to carry a suffix. Nothing else is Markdown addressable. A path not in that list answers with the ordinary page, or with a 404, and never with a Markdown document. ## What a Markdown document contains YAML front matter, then the content. Front matter is the convention every static site generator and every agent already parses, and it means a caller that wants only the canonical URL does not have to read prose to find it. ### An article `type: article`. The front matter carries `title`, `summary`, `newsletter`, `newsletter_handle`, `newsletter_url`, `author`, `published`, `canonical_url`, `markdown_url`, `chat_url`, `source_url`, `body_source` (`native` when Commune sent it, `imported` when it came from an email provider or a feed), `likes`, `replies` and `body_words`. Then an H1 with the title, the full body, and, below a horizontal rule, the article's discussion. ### A newsletter, and its archive `type: newsletter` or `type: newsletter_archive`. The front matter carries `title`, `handle`, `owner`, `canonical_url`, `markdown_url`, `archive_url`, `website`, `articles_total` and `articles_listed`. An archive page also carries `page` and `page_size`, and is paginated with `?page=N`. ### A chat thread, or one reply `type: chat_thread` or `type: chat_reply`. The front matter carries `title`, `newsletter`, `newsletter_handle`, `newsletter_url`, `last_activity`, `canonical_url`, `markdown_url`, `replies`, and, when the thread is attached to an article, `article_title`. A reply document also carries `thread_url` and `thread_title`, so a reader that started in the middle can get back to the whole conversation. ### How a discussion is numbered Each reply is a heading numbered by its position in the reply tree. `### 3` is the third top-level reply; `#### 3.2` is the second reply to it. The numbering is the structure, so a model does not have to infer nesting from indentation that Markdown would flatten. Message text is reproduced verbatim as posted, because it is already Markdown. A quoted message appears as a blockquote naming who was quoted. Discussions are capped at 500 replies per document. When the cap bites, the document says so, with the exact number of replies omitted and a link to the web page that holds the rest. Nothing is truncated silently, because a model cannot tell it is reading a partial conversation. ## What you will not get A Markdown document is exactly what the corresponding web page would show the same caller. It is not a privileged view, and asking for Markdown grants nothing that asking for HTML would not. Three rules gate every article, and all three apply in Markdown: - An article sent to a subscriber segment is readable only by that newsletter's team and by subscribers holding one of its tags. - An article dated in the future is scheduled, not published, and is invisible until that moment passes. - An unpublished draft is not here at all. It is off every listing, out of search, and absent from this corpus. A creator may hand a specific person a private review link to one; that link serves HTML only, and the page it serves carries `noindex, nofollow`. There is no Markdown twin of a draft, deliberately: a draft is the one thing on this origin its author has not decided to publish. Markdown responses are `Cache-Control: private, no-store` with `Vary: Accept`. No shared cache may store any of it, deliberately: these surfaces are viewer dependent, so a cache holding one reader's copy and serving it to another would be a leak rather than an optimisation. ## Content on this origin ### Articles Newsletter articles, either written on Commune and sent by it, or imported from Substack, Ghost, beehiiv, Kit, Mailchimp and MailerLite. - Canonical URL: `/n/{handle}/a/{slug}` - Legacy permalink: `/article/{uuid}` ### Newsletters Each newsletter has a public landing page and a full archive. A newsletter owns its articles, its chat, its subscribers and its team. - Landing: `/n/{handle}` - Archive: `/n/{handle}/archive` ### Chat Discussion is threaded and lives per newsletter. There is no separate posts or comments stack: a creator's broadcast, a reader's question and the discussion under an article are all threads in the same newsletter scoped chat. - Newsletter chat: `/n/{handle}/chat` - A thread: `/n/{handle}/chat/{threadId}` - A reply: `/n/{handle}/chat/{threadId}/{replyId}` - An article's discussion: `/n/{handle}/a/{slug}/chat` ### Profiles Public user profiles, at `/@{username}`. Only the public profile is readable, never an email address. ## The API, on another origin Commune has a public HTTP API, and its documentation is not on this origin. It is on a separate registrable domain, so an agent that only crawls this host will not find it. - [usecommune.dev llms.txt](https://usecommune.dev/llms.txt): the index for the API reference. - [usecommune.dev llms-full.txt](https://usecommune.dev/llms-full.txt): every operation, webhook and schema, inlined as one Markdown document. Fetch this one to answer a question about the API. - [Developer guides](https://usecommune.dev/guides): how to authenticate, build an integration, and verify a webhook signature. - [API reference](https://api-reference.usecommune.dev): the same contract, rendered, on its own host. - [openapi.json](https://api.usecommune.com/openapi.json?profile=docs): the published contract, as bytes to generate a client from. The split is deliberate. Session cookie scope follows the domain and ignores what the DNS points at, so a reference served from a usecommune.com subdomain would receive a live session token on every page load. A different apex cannot. ## Crawl policy The policy this origin serves at https://usecommune.com/robots.txt, restated so an agent reading only this file still knows it. Content signals: `search=yes, ai-input=yes, ai-train=no`. `ai-input=yes` is explicit and is the reason this whole Markdown surface exists: a model may fetch a page to answer a question now, and cite it. `ai-train=no` is equally explicit, and separable: training on creators' articles is a different bargain and not ours to grant on their behalf. Everything is crawlable except these prefixes, which are the signed-in app and its plumbing: - `/api/` - `/dashboard` - `/dashboard/` - `/inbox` - `/notifications` - `/settings` - `/chat` - `/monitoring` - `/n/*/x/` Those are advisory. What actually protects a private surface is the session check in the route handler, never this list. ## Sitemaps - Index: https://usecommune.com/sitemap.xml - Static pages: https://usecommune.com/sitemap/0/sitemap.xml - Newsletters: https://usecommune.com/sitemap/1/sitemap.xml - Articles: https://usecommune.com/sitemap/2/sitemap.xml and upward, one partition per chunk of articles ## Website https://usecommune.com