# Retrieve a thread **GET /threads/{thread}** Read one thread and its opening message. The replies are a separate collection at `GET /threads/{thread}/messages`, so a busy thread does not make this response unbounded. A thread opened by an article inherits that article's audience: if the article is not readable by this key, neither is its thread. ## Servers - Production. There is no separate sandbox host. : https://api.usecommune.com (Production. There is no separate sandbox host. ) ## Authentication methods - Api key ## Parameters ### Headers - **Commune-Version** (string(date)) The contract version this request is written against, as a release date (`YYYY-MM-DD`). Omitting the header pins the request to the version that was current when the API key was issued, so an integration keeps working when a newer version ships. An unknown value answers `400` with `invalid_version`. ### Path parameters - **thread** (string) The thread's `id` (a UUID) or its `short_id`. A thread that Commune opened under an article has no `short_id`, because it is addressed on the web through the article's own permalink, so use its `id`. ### Query parameters - **expand** (string) Comma separated list of relationship paths to inline in the response. Unexpanded relationships are returned as a reference object carrying only `id` and `object`. Each operation documents the paths it accepts, and an unknown path answers `400`. Nested paths use a dot, for example `article.newsletter`. One accepted path is not a relationship. `?expand=content` on `GET /articles/{article}` adds the Markdown rendition of the body beside the HTML one. It is the same trade the parameter always offers, a fuller response for a larger one, over a property that has more than one representation rather than over a reference. - **fields** (string) Comma separated allow list of top level properties to return on each object, so a client can trim a response it does not need in full. `id` and `object` are always returned. An unknown property name answers `400`. Properties omitted by an operation, such as `content` on any article list, cannot be brought back with `fields`. A trimmed body is a subset of the schema this operation declares, and a property that schema marks required is absent when it was not asked for. That is the point of the parameter, so a client that validates responses against the schema either sends no `fields` or relaxes `required`. ## Responses ### 200 The thread. #### Body: application/json (object | null) - **object** (string) Always `thread`. - **id** (string(uuid)) Stable identifier. - **short_id** (string | null) Eight character base62 identifier used by the thread's own URL at `/n/{handle}/chat/{short_id}`. Null for a thread Commune opened under an article, which is reached through the article instead. - **newsletter** (object | null) The community this thread lives in. A `Ref` unless `newsletter` is named in `?expand=`. - **author** (object | null) Who opened the thread. A `Ref` unless `author` is named in `?expand=`. - **content** (string) The opening message. HTML, since people format what they write. Treat it as untrusted markup and render it in a sandboxed context. - **media** (array[object]) Attachments on the opening message. - **visibility** (string) Where a thread is placed. `public` puts it on the global Commune feed and makes it readable by anyone. `subscribers` keeps it inside the newsletter. `paid` narrows it further to the paying part of the audience. Set and changed by the newsletter's team. - **is_article_thread** (boolean) `true` when Commune opened this thread under an article rather than a person starting it. These are kept off the global feed, because the article card already represents the conversation there. - **article** (object | null) The article that opened this thread, when `is_article_thread` is `true`. `null` otherwise. A `Ref` unless `article` is named in `?expand=`. - **is_pinned** (boolean) Whether the team pinned this thread to the top of the community. - **is_locked** (boolean) Whether the team closed the thread to new replies. - **reply_count** (integer) Undeleted replies in the thread, at any depth. - **view_count** (integer) How many times the thread was opened. - **created_at** (string(date-time)) When the thread was opened. - **updated_at** (string(date-time)) When the thread row last changed for any reason. - **edited_at** (string(date-time) | null) When the author last edited the opening message. Null when it was never edited, which is what drives the edited marker in the product. - **last_activity_at** (string(date-time)) When the thread last received a reply, or when it was opened if it never did. This is the sort key for the thread list. ### 400 The request was malformed: an unknown query parameter, an unparseable cursor, an unknown `expand` path, or an unrecognised `Commune-Version`. #### Body: application/json (object) - **error** (object) ### 401 No API key was presented, or the key is unknown, revoked or expired. All four answer identically, down to the wording. Saying that a key was revoked rather than never issued confirms to whoever is holding the string that it was once real, which a legitimate caller does not need and a thief should not get. #### Headers - **WWW-Authenticate** (string) The authentication scheme this API accepts. Always `Bearer realm="Commune API"`; there is no second scheme and no query-parameter fallback, because a credential that can travel in a URL ends up in access logs and referer headers. #### Body: application/json (object) - **error** (object) ### 404 No such resource, or the key is not allowed to know that it exists. Commune answers `404` rather than `403` where distinguishing the two would leak the existence of private content. #### Body: application/json (object) - **error** (object) ### 429 Too many requests. Back off and retry after the interval named by the `Retry-After` response header. #### Headers - **Retry-After** (integer) Seconds to wait before retrying. #### Body: application/json (object) - **error** (object) ### 500 Something failed inside Commune. The request may be retried. #### Body: application/json (object) - **error** (object) [Powered by Bump.sh](https://bump.sh)