Reply in a thread Run in API Explorer
Posts a reply in a thread and returns it. Needs content: write, and
is a write.
The reply is written by the person the credential belongs to, and the
people in the thread are notified the way they are for any reply.
It needs content, media, or both.
Leave parent out to reply to the thread itself. Name a reply in
parent to reply to it: a conversation is two levels deep, so the
parent has to be a direct reply to the thread, and a reply to a reply
to a reply answers 422. quoted optionally quotes the thread or any
message in it. Both take a message's id or short_id, and both have
to be in this thread.
A reply has no visibility of its own: it is exactly as readable as its
thread. A locked thread takes no replies and answers 409.
Publishes message.created.
Headers
-
A value of your choosing naming the change this request is making.
Send the same value again to retry the same request. Commune replays the answer the first attempt gave instead of making the change twice, and marks the replay with an
Idempotent-Replay: trueresponse header. Send a different value for a different change: a key reused for a request that differs in any way answers409, because replaying an answer to a question you did not ask is a wrong answer you could not detect.A UUID per change is the usual choice. Remembered for 24 hours, per credential, so two credentials choosing the same value never see each other's answers.
Required, not optional.
Minimum length is
1, maximum length is255. -
The contract version this request is written against. Every version published so far is a release date (
YYYY-MM-DD), which is why the examples look like one, but the value is an opaque identifier: match it against the versions this API publishes rather than parsing it, because a future one may not be only a date. An unknown value answers400withinvalid_version.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.
Minimum length is
1.
Path parameters
-
The thread's
id(a UUID) or itsshort_id. A thread that Commune opened under an article has noshort_id, because it is addressed on the web through the article's own permalink, so use itsid.
A reply in a thread.
-
The reply, as Markdown. Surrounding whitespace is trimmed. Optional when
mediaattaches something: a post needs text, attachments, or both.Maximum length is
5000. -
The reply this answers, by
idorshort_id. Leave it out to reply to the thread itself. It has to be a direct reply to this thread. -
The thread or a message in it to quote, by
idorshort_id. -
Images or videos to attach, by URL.
Not more than
10elements.Hide media attributes Show media attributes object
An attachment, by URL. Commune does not copy it: the URL is shown as given, so it has to stay reachable.
-
Where the attachment is served from.
httporhttps.Maximum length is
2000. -
What it is. Leave it out and Commune decides from the URL's extension:
.mp4,.webmand.movare videos, anything else an image.Values are
imageorvideo. -
A description for people who cannot see it.
Maximum length is
500.
-
A reply in a thread.
-
The reply, as Markdown. Surrounding whitespace is trimmed. Optional when
mediaattaches something: a post needs text, attachments, or both.Maximum length is
5000. -
The reply this answers, by
idorshort_id. Leave it out to reply to the thread itself. It has to be a direct reply to this thread. -
The thread or a message in it to quote, by
idorshort_id. -
Images or videos to attach, by URL.
Not more than
10elements.Hide media attributes Show media attributes object
An attachment, by URL. Commune does not copy it: the URL is shown as given, so it has to stay reachable.
-
Where the attachment is served from.
httporhttps.Maximum length is
2000. -
What it is. Leave it out and Commune decides from the URL's extension:
.mp4,.webmand.movare videos, anything else an image.Values are
imageorvideo. -
A description for people who cannot see it.
Maximum length is
500.
-
Responses
-
The reply, as created.
Hide response attributes Show response attributes object
-
Always
message.Value is
message. -
Stable identifier.
-
Eight character base62 identifier used by the message's permalink. Null for a message old enough that none was assigned.
- thread
object | null Required The thread this reply belongs to. A
Refunlessthreadis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A conversation in a newsletter's community, together with the message that opened it. Its replies are a separate collection.
Hide attributes Show attributes
-
Always
thread.Value is
thread. -
Stable identifier.
-
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 Required The community this thread lives in. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Hide attributes Show attributes
-
Always
newsletter.Value is
newsletter. -
Stable identifier.
-
The short, unique, URL safe name. Resolves the public profile at
/n/{handle}and is accepted anywhere{newsletter}is. -
Display name, as the creator writes it.
-
The profile blurb. Sanitised HTML, not plain text, because creators format it. Treat it as untrusted markup and render it in a sandboxed context.
-
Where a newsletter is published from.
communemeans Commune itself sends the email. Every other value is an email service provider whose posts Commune imports.rsscovers any feed that is not one of the named providers.Values are
commune,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
The creator's own site, if they linked one.
-
The creator's other homes on the internet, stored as canonical profile URLs. Every key is optional and a newsletter that set none returns an empty object.
Additional properties are NOT allowed.
Hide social_links attributes Show social_links attributes object
-
X or Twitter profile URL.
-
Bluesky profile URL.
-
LinkedIn profile URL.
-
Mastodon profile URL, including the instance host.
-
YouTube channel URL.
-
Instagram profile URL.
-
Threads profile URL.
-
GitHub profile URL.
-
-
Best known language of the newsletter's writing as a BCP 47 tag. Detected from recent articles rather than declared, so treat it as a hint. Null before enough has been published to tell.
-
Who may start a new chat thread in this community.
Values are
editors,subscribers, oranyone. -
Whether people who have not subscribed may reply in existing threads.
- owner
object | null The account that owns the newsletter. A
Refunlessowneris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- featured_article
object | null The article the creator pinned to the top of the profile, or
nullwhen none is pinned. ARefunlessfeatured_articleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent.Hide attributes Show attributes
-
Always
article.Value is
article. -
Stable identifier.
-
Eight character base62 identifier, unique across Commune. Safe in a URL and accepted anywhere
{article}is. -
URL segment under the newsletter, unique within it but not across Commune. The permalink is
/n/{handle}/a/{slug}. Falls back to theshort_idfor an untitled article. - newsletter
object | null Required The newsletter this article belongs to. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Additional properties are NOT allowed.
-
-
Subject line of the article. Null for an untitled draft.
-
The short line email clients show after the subject, and what Commune uses as the excerpt on a card.
-
Cover image. When the creator set none, Commune stamps the first image in the body at send time, so this is usually populated for a sent article.
-
The article's canonical URL on the newsletter's own provider, for an imported article. Null for one written in Commune.
-
Where an article is in its life. A credential holding only
readpermissions ever seessentand nothing else. An imported article is alwayssent, since Commune sees it after the provider delivered it.Values are
draft,scheduled,sending,sent,failed, orarchived. -
truewhen the article came in from the newsletter's provider,falsewhen it was written and sent in Commune. -
When the article went out. An article dated in the future is not returned by any read operation until that moment passes, so this is never ahead of now in a response.
-
When a queued article may go out. Set while
statusisscheduledand null otherwise.This is not
posted_atand the difference matters: a queued article has no publication date yet, which is why it stays invisible on every reader surface until it really goes out. Commune dispatches in passes, so this is the moment from which the article may go rather than the moment it will. -
The byline, in order. Each entry is a
Refunlessauthorsis named in?expand=. Empty when no Commune account is credited.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- thread
object | null The chat thread this article opened, where its discussion lives.
nullwhen the newsletter does not open a thread per article. ARefunlessthreadis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A conversation in a newsletter's community, together with the message that opened it. Its replies are a separate collection.
Additional properties are NOT allowed.
-
-
Engagement counts for an article, computed at read time. These are Commune side counts, not provider side email metrics: opens, clicks and deliveries are not here.
Additional properties are NOT allowed.
Hide stats attributes Show stats attributes object
-
How many people liked the article.
Minimum value is
0. -
Replies in the article's chat thread. Commune has no separate comments store: an article's discussion is a thread like any other, so this counts the undeleted replies hanging off it.
0when the article has no thread.Minimum value is
0. -
How many passages readers highlighted.
Minimum value is
0.
-
-
When the row was created in Commune.
-
When the article was last edited.
-
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
- author
object | null Who opened the thread. A
Refunlessauthoris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
-
The opening message. HTML, since people format what they write. Treat it as untrusted markup and render it in a sandboxed context.
-
Attachments on the opening message.
Hide media attributes Show media attributes object
An image or file attached to a thread or a message.
-
Where the attachment is served from.
-
The attachment's media type when Commune recorded one, for example
image/png. Null for an attachment old enough that none was recorded. -
A smaller rendition, when one was generated.
-
-
Where a thread is placed.
publicputs it on the global Commune feed and makes it readable by anyone.subscriberskeeps it inside the newsletter.paidnarrows it further to the paying part of the audience. Set and changed by the newsletter's team.Values are
public,subscribers, orpaid. -
truewhen 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_threadistrue.nullotherwise. ARefunlessarticleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent.Hide attributes Show attributes
-
Always
article.Value is
article. -
Stable identifier.
-
Eight character base62 identifier, unique across Commune. Safe in a URL and accepted anywhere
{article}is. -
URL segment under the newsletter, unique within it but not across Commune. The permalink is
/n/{handle}/a/{slug}. Falls back to theshort_idfor an untitled article. - newsletter
object | null Required The newsletter this article belongs to. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Hide attributes Show attributes
-
Always
newsletter.Value is
newsletter. -
Stable identifier.
-
The short, unique, URL safe name. Resolves the public profile at
/n/{handle}and is accepted anywhere{newsletter}is. -
Display name, as the creator writes it.
-
The profile blurb. Sanitised HTML, not plain text, because creators format it. Treat it as untrusted markup and render it in a sandboxed context.
-
Where a newsletter is published from.
communemeans Commune itself sends the email. Every other value is an email service provider whose posts Commune imports.rsscovers any feed that is not one of the named providers.Values are
commune,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
The creator's own site, if they linked one.
-
The creator's other homes on the internet, stored as canonical profile URLs. Every key is optional and a newsletter that set none returns an empty object.
Additional properties are NOT allowed.
Hide social_links attributes Show social_links attributes object
-
X or Twitter profile URL.
-
Bluesky profile URL.
-
LinkedIn profile URL.
-
Mastodon profile URL, including the instance host.
-
YouTube channel URL.
-
Instagram profile URL.
-
Threads profile URL.
-
GitHub profile URL.
-
-
Best known language of the newsletter's writing as a BCP 47 tag. Detected from recent articles rather than declared, so treat it as a hint. Null before enough has been published to tell.
-
Who may start a new chat thread in this community.
Values are
editors,subscribers, oranyone. -
Whether people who have not subscribed may reply in existing threads.
- owner
object | null The account that owns the newsletter. A
Refunlessowneris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- featured_article
object | null The article the creator pinned to the top of the profile, or
nullwhen none is pinned. ARefunlessfeatured_articleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent. -
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
-
Subject line of the article. Null for an untitled draft.
-
The short line email clients show after the subject, and what Commune uses as the excerpt on a card.
-
Cover image. When the creator set none, Commune stamps the first image in the body at send time, so this is usually populated for a sent article.
-
The article's canonical URL on the newsletter's own provider, for an imported article. Null for one written in Commune.
-
Where an article is in its life. A credential holding only
readpermissions ever seessentand nothing else. An imported article is alwayssent, since Commune sees it after the provider delivered it.Values are
draft,scheduled,sending,sent,failed, orarchived. -
truewhen the article came in from the newsletter's provider,falsewhen it was written and sent in Commune. -
When the article went out. An article dated in the future is not returned by any read operation until that moment passes, so this is never ahead of now in a response.
-
When a queued article may go out. Set while
statusisscheduledand null otherwise.This is not
posted_atand the difference matters: a queued article has no publication date yet, which is why it stays invisible on every reader surface until it really goes out. Commune dispatches in passes, so this is the moment from which the article may go rather than the moment it will. -
The byline, in order. Each entry is a
Refunlessauthorsis named in?expand=. Empty when no Commune account is credited.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- thread
object | null The chat thread this article opened, where its discussion lives.
nullwhen the newsletter does not open a thread per article. ARefunlessthreadis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A conversation in a newsletter's community, together with the message that opened it. Its replies are a separate collection.
Additional properties are NOT allowed.
-
-
Engagement counts for an article, computed at read time. These are Commune side counts, not provider side email metrics: opens, clicks and deliveries are not here.
Additional properties are NOT allowed.
Hide stats attributes Show stats attributes object
-
How many people liked the article.
Minimum value is
0. -
Replies in the article's chat thread. Commune has no separate comments store: an article's discussion is a thread like any other, so this counts the undeleted replies hanging off it.
0when the article has no thread.Minimum value is
0. -
How many passages readers highlighted.
Minimum value is
0.
-
-
When the row was created in Commune.
-
When the article was last edited.
-
-
Undeleted replies in the thread, at any depth.
Minimum value is
0. -
How many times the thread was opened.
Minimum value is
0. -
When the thread was opened.
-
When the thread row last changed for any reason.
-
When the author last edited the opening message. Null when it was never edited, which is what drives the edited marker in the product.
-
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.
-
- newsletter
object | null Required The community the thread lives in, denormalised so a client does not have to walk up to it. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Hide attributes Show attributes
-
Always
newsletter.Value is
newsletter. -
Stable identifier.
-
The short, unique, URL safe name. Resolves the public profile at
/n/{handle}and is accepted anywhere{newsletter}is. -
Display name, as the creator writes it.
-
The profile blurb. Sanitised HTML, not plain text, because creators format it. Treat it as untrusted markup and render it in a sandboxed context.
-
Where a newsletter is published from.
communemeans Commune itself sends the email. Every other value is an email service provider whose posts Commune imports.rsscovers any feed that is not one of the named providers.Values are
commune,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
The creator's own site, if they linked one.
-
The creator's other homes on the internet, stored as canonical profile URLs. Every key is optional and a newsletter that set none returns an empty object.
Additional properties are NOT allowed.
Hide social_links attributes Show social_links attributes object
-
X or Twitter profile URL.
-
Bluesky profile URL.
-
LinkedIn profile URL.
-
Mastodon profile URL, including the instance host.
-
YouTube channel URL.
-
Instagram profile URL.
-
Threads profile URL.
-
GitHub profile URL.
-
-
Best known language of the newsletter's writing as a BCP 47 tag. Detected from recent articles rather than declared, so treat it as a hint. Null before enough has been published to tell.
-
Who may start a new chat thread in this community.
Values are
editors,subscribers, oranyone. -
Whether people who have not subscribed may reply in existing threads.
- owner
object | null The account that owns the newsletter. A
Refunlessowneris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- featured_article
object | null The article the creator pinned to the top of the profile, or
nullwhen none is pinned. ARefunlessfeatured_articleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent.Hide attributes Show attributes
-
Always
article.Value is
article. -
Stable identifier.
-
Eight character base62 identifier, unique across Commune. Safe in a URL and accepted anywhere
{article}is. -
URL segment under the newsletter, unique within it but not across Commune. The permalink is
/n/{handle}/a/{slug}. Falls back to theshort_idfor an untitled article. - newsletter
object | null Required The newsletter this article belongs to. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Additional properties are NOT allowed.
-
-
Subject line of the article. Null for an untitled draft.
-
The short line email clients show after the subject, and what Commune uses as the excerpt on a card.
-
Cover image. When the creator set none, Commune stamps the first image in the body at send time, so this is usually populated for a sent article.
-
The article's canonical URL on the newsletter's own provider, for an imported article. Null for one written in Commune.
-
Where an article is in its life. A credential holding only
readpermissions ever seessentand nothing else. An imported article is alwayssent, since Commune sees it after the provider delivered it.Values are
draft,scheduled,sending,sent,failed, orarchived. -
truewhen the article came in from the newsletter's provider,falsewhen it was written and sent in Commune. -
When the article went out. An article dated in the future is not returned by any read operation until that moment passes, so this is never ahead of now in a response.
-
When a queued article may go out. Set while
statusisscheduledand null otherwise.This is not
posted_atand the difference matters: a queued article has no publication date yet, which is why it stays invisible on every reader surface until it really goes out. Commune dispatches in passes, so this is the moment from which the article may go rather than the moment it will. -
The byline, in order. Each entry is a
Refunlessauthorsis named in?expand=. Empty when no Commune account is credited.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- thread
object | null The chat thread this article opened, where its discussion lives.
nullwhen the newsletter does not open a thread per article. ARefunlessthreadis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A conversation in a newsletter's community, together with the message that opened it. Its replies are a separate collection.
Hide attributes Show attributes
-
Always
thread.Value is
thread. -
Stable identifier.
-
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 Required The community this thread lives in. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Additional properties are NOT allowed.
-
- author
object | null Who opened the thread. A
Refunlessauthoris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
-
The opening message. HTML, since people format what they write. Treat it as untrusted markup and render it in a sandboxed context.
-
Attachments on the opening message.
Hide media attributes Show media attributes object
An image or file attached to a thread or a message.
-
Where the attachment is served from.
-
The attachment's media type when Commune recorded one, for example
image/png. Null for an attachment old enough that none was recorded. -
A smaller rendition, when one was generated.
-
-
Where a thread is placed.
publicputs it on the global Commune feed and makes it readable by anyone.subscriberskeeps it inside the newsletter.paidnarrows it further to the paying part of the audience. Set and changed by the newsletter's team.Values are
public,subscribers, orpaid. -
truewhen 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_threadistrue.nullotherwise. ARefunlessarticleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent. -
-
Undeleted replies in the thread, at any depth.
Minimum value is
0. -
How many times the thread was opened.
Minimum value is
0. -
When the thread was opened.
-
When the thread row last changed for any reason.
-
When the author last edited the opening message. Null when it was never edited, which is what drives the edited marker in the product.
-
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.
-
-
Engagement counts for an article, computed at read time. These are Commune side counts, not provider side email metrics: opens, clicks and deliveries are not here.
Additional properties are NOT allowed.
Hide stats attributes Show stats attributes object
-
How many people liked the article.
Minimum value is
0. -
Replies in the article's chat thread. Commune has no separate comments store: an article's discussion is a thread like any other, so this counts the undeleted replies hanging off it.
0when the article has no thread.Minimum value is
0. -
How many passages readers highlighted.
Minimum value is
0.
-
-
When the row was created in Commune.
-
When the article was last edited.
-
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
- author
object | null Who wrote the reply. A
Refunlessauthoris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- parent
object | null The message this one replies to, or
nullwhen it replies to the thread itself. ARefunlessparentis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A reply inside a thread. Commune allows two levels: a reply to the thread, and a reply to that reply. A deleted message is omitted from every read rather than returned as a tombstone.
Additional properties are NOT allowed.
-
- quoted
object | null The message this one quotes, when the author quoted rather than replied.
nullotherwise. ARefunlessquotedis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A reply inside a thread. Commune allows two levels: a reply to the thread, and a reply to that reply. A deleted message is omitted from every read rather than returned as a tombstone.
Additional properties are NOT allowed.
-
-
1for a reply to the thread,2for a reply to a reply. Commune does not nest deeper, so a client can render the tree with a fixed two level layout.Minimum value is
1, maximum value is2. -
The message body as HTML. Treat it as untrusted markup and render it in a sandboxed context.
-
Attachments on the message.
Hide media attributes Show media attributes object
An image or file attached to a thread or a message.
-
Where the attachment is served from.
-
The attachment's media type when Commune recorded one, for example
image/png. Null for an attachment old enough that none was recorded. -
A smaller rendition, when one was generated.
-
- highlight
object | null The passage of an article this reply is anchored to, when the reader wrote it from a highlight.
nullotherwise. ARefunlesshighlightis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A passage of an article a reader marked. Highlights are the anchor for an inline comment, which is why one can carry a link to the message it started.
Hide attributes Show attributes
-
Always
highlight.Value is
highlight. -
Stable identifier.
- article
object | null Required The article the passage is in. A
Refunlessarticleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent.Hide attributes Show attributes
-
Always
article.Value is
article. -
Stable identifier.
-
Eight character base62 identifier, unique across Commune. Safe in a URL and accepted anywhere
{article}is. -
URL segment under the newsletter, unique within it but not across Commune. The permalink is
/n/{handle}/a/{slug}. Falls back to theshort_idfor an untitled article. - newsletter
object | null Required The newsletter this article belongs to. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Hide attributes Show attributes
-
Always
newsletter.Value is
newsletter. -
Stable identifier.
-
The short, unique, URL safe name. Resolves the public profile at
/n/{handle}and is accepted anywhere{newsletter}is. -
Display name, as the creator writes it.
-
The profile blurb. Sanitised HTML, not plain text, because creators format it. Treat it as untrusted markup and render it in a sandboxed context.
-
Where a newsletter is published from.
communemeans Commune itself sends the email. Every other value is an email service provider whose posts Commune imports.rsscovers any feed that is not one of the named providers.Values are
commune,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
The creator's own site, if they linked one.
-
The creator's other homes on the internet, stored as canonical profile URLs. Every key is optional and a newsletter that set none returns an empty object.
Additional properties are NOT allowed.
Hide social_links attributes Show social_links attributes object
-
X or Twitter profile URL.
-
Bluesky profile URL.
-
LinkedIn profile URL.
-
Mastodon profile URL, including the instance host.
-
YouTube channel URL.
-
Instagram profile URL.
-
Threads profile URL.
-
GitHub profile URL.
-
-
Best known language of the newsletter's writing as a BCP 47 tag. Detected from recent articles rather than declared, so treat it as a hint. Null before enough has been published to tell.
-
Who may start a new chat thread in this community.
Values are
editors,subscribers, oranyone. -
Whether people who have not subscribed may reply in existing threads.
- owner
object | null The account that owns the newsletter. A
Refunlessowneris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- featured_article
object | null The article the creator pinned to the top of the profile, or
nullwhen none is pinned. ARefunlessfeatured_articleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent. -
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
-
Subject line of the article. Null for an untitled draft.
-
The short line email clients show after the subject, and what Commune uses as the excerpt on a card.
-
Cover image. When the creator set none, Commune stamps the first image in the body at send time, so this is usually populated for a sent article.
-
The article's canonical URL on the newsletter's own provider, for an imported article. Null for one written in Commune.
-
Where an article is in its life. A credential holding only
readpermissions ever seessentand nothing else. An imported article is alwayssent, since Commune sees it after the provider delivered it.Values are
draft,scheduled,sending,sent,failed, orarchived. -
truewhen the article came in from the newsletter's provider,falsewhen it was written and sent in Commune. -
When the article went out. An article dated in the future is not returned by any read operation until that moment passes, so this is never ahead of now in a response.
-
When a queued article may go out. Set while
statusisscheduledand null otherwise.This is not
posted_atand the difference matters: a queued article has no publication date yet, which is why it stays invisible on every reader surface until it really goes out. Commune dispatches in passes, so this is the moment from which the article may go rather than the moment it will. -
The byline, in order. Each entry is a
Refunlessauthorsis named in?expand=. Empty when no Commune account is credited.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- thread
object | null The chat thread this article opened, where its discussion lives.
nullwhen the newsletter does not open a thread per article. ARefunlessthreadis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A conversation in a newsletter's community, together with the message that opened it. Its replies are a separate collection.
Hide attributes Show attributes
-
Always
thread.Value is
thread. -
Stable identifier.
-
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 Required The community this thread lives in. A
Refunlessnewsletteris named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A newsletter and its public profile. Nothing operational is exposed: ESP credentials, OAuth tokens, group and audience ids, feed polling state and language detection bookkeeping all stay server side.
Hide attributes Show attributes
-
Always
newsletter.Value is
newsletter. -
Stable identifier.
-
The short, unique, URL safe name. Resolves the public profile at
/n/{handle}and is accepted anywhere{newsletter}is. -
Display name, as the creator writes it.
-
The profile blurb. Sanitised HTML, not plain text, because creators format it. Treat it as untrusted markup and render it in a sandboxed context.
-
Where a newsletter is published from.
communemeans Commune itself sends the email. Every other value is an email service provider whose posts Commune imports.rsscovers any feed that is not one of the named providers.Values are
commune,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
The creator's own site, if they linked one.
-
The creator's other homes on the internet, stored as canonical profile URLs. Every key is optional and a newsletter that set none returns an empty object.
Additional properties are NOT allowed.
Hide social_links attributes Show social_links attributes object
-
X or Twitter profile URL.
-
Bluesky profile URL.
-
LinkedIn profile URL.
-
Mastodon profile URL, including the instance host.
-
YouTube channel URL.
-
Instagram profile URL.
-
Threads profile URL.
-
GitHub profile URL.
-
-
Best known language of the newsletter's writing as a BCP 47 tag. Detected from recent articles rather than declared, so treat it as a hint. Null before enough has been published to tell.
-
Who may start a new chat thread in this community.
Values are
editors,subscribers, oranyone. -
Whether people who have not subscribed may reply in existing threads.
- owner
object | null The account that owns the newsletter. A
Refunlessowneris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
- featured_article
object | null The article the creator pinned to the top of the profile, or
nullwhen none is pinned. ARefunlessfeatured_articleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent. -
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
- author
object | null Who opened the thread. A
Refunlessauthoris named in?expand=.Any of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A person's public profile, and the whole of what this API returns about anybody other than the credential's own owner. Email address, theme, notification preferences, push subscriptions, read state and saved articles are never carried.
Hide attributes Show attributes
-
Always
user.Value is
user. -
Stable identifier.
-
The unique handle the profile resolves on at
/@{username}. Null for an account that has not finished signing up. -
The name shown next to their messages and bylines.
-
Profile picture. Commune falls back to a generated avatar when the person never set one, so this is rarely null in practice.
-
-
The opening message. HTML, since people format what they write. Treat it as untrusted markup and render it in a sandboxed context.
-
Attachments on the opening message.
Hide media attributes Show media attributes object
An image or file attached to a thread or a message.
-
Where the attachment is served from.
-
The attachment's media type when Commune recorded one, for example
image/png. Null for an attachment old enough that none was recorded. -
A smaller rendition, when one was generated.
-
-
Where a thread is placed.
publicputs it on the global Commune feed and makes it readable by anyone.subscriberskeeps it inside the newsletter.paidnarrows it further to the paying part of the audience. Set and changed by the newsletter's team.Values are
public,subscribers, orpaid. -
truewhen 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_threadistrue.nullotherwise. ARefunlessarticleis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
One article of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent. -
-
Undeleted replies in the thread, at any depth.
Minimum value is
0. -
How many times the thread was opened.
Minimum value is
0. -
When the thread was opened.
-
When the thread row last changed for any reason.
-
When the author last edited the opening message. Null when it was never edited, which is what drives the edited marker in the product.
-
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.
-
-
Engagement counts for an article, computed at read time. These are Commune side counts, not provider side email metrics: opens, clicks and deliveries are not here.
Additional properties are NOT allowed.
Hide stats attributes Show stats attributes object
-
How many people liked the article.
Minimum value is
0. -
Replies in the article's chat thread. Commune has no separate comments store: an article's discussion is a thread like any other, so this counts the undeleted replies hanging off it.
0when the article has no thread.Minimum value is
0. -
How many passages readers highlighted.
Minimum value is
0.
-
-
When the row was created in Commune.
-
When the article was last edited.
-
-
The marked text itself, as plain text.
Maximum length is
5000. -
Up to two hundred characters of the text immediately before the quote. Together with
suffixthis re anchors the highlight when the body changed and the offsets no longer line up. -
Up to two hundred characters of the text immediately after the quote.
-
Where the passage starts, as a character offset into the article's plain text. Always less than
end_offset.Minimum value is
0. -
Where the passage ends, as a character offset into the plain text.
Minimum value is
1. -
An opaque, stable per highlighter value, scoped to this one article. Group by it to tell one reader's marks apart from another's, and count distinct values for a distinct highlighter count. It cannot be resolved to a person and does not correlate across articles: Commune does not attribute a highlight to a named reader.
- message
object | null The chat message the reader wrote from this passage, when they wrote one.
nullotherwise. ARefunlessmessageis named in?expand=.One of: An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.Hide attributes Show attributes
-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
A reply inside a thread. Commune allows two levels: a reply to the thread, and a reply to that reply. A deleted message is omitted from every read rather than returned as a tombstone.
Additional properties are NOT allowed.
-
-
When the passage was marked.
-
-
When the reply was written.
-
When the row last changed for any reason.
-
When the author last edited the text or attachments. Not touched by reactions or other side effects, so it is a faithful edited marker.
-
The emoji reactions on this message, one entry per distinct emoji, most used first. Empty when there are none. Each entry carries
users, who left it, only whenreactionsis named in?expand=.Hide reactions attributes Show reactions attributes object
One emoji on a message, and how many people left it.
-
The emoji itself, as the character rather than a shortcode.
-
How many people left this emoji on the message.
Minimum value is
1. -
Who left it, in the order they did. Present only when
reactionsis named in?expand=.Hide users attributes Show users attributes object | null
An unexpanded relationship. Ask for the relationship in
?expand=to get the full object in its place.-
The type of the referenced resource.
-
The referenced resource's
id, in whatever form that resource's own schema declares. Most are UUIDs; aRefwhoseobjectisusercarries an account identifier, which is an opaque string and not a UUID. Compare it for equality and pass it back; do not parse it.
-
-
-
-
The request was malformed, and the same request will fail the same way until it is changed.
paramnames the parameter or header at fault when there is exactly one, andallowed_valueslists what it accepts when that is a finite set. The code isbad_requestfor every case below except the last.- A query parameter: one the operation does not have, a value
outside its set, range or format (an unparseable cursor, an unknown
expandpath orfieldsname, an identifier that is not a UUID), or a required one left out, such asqon a search ornewsletterwhen the credential reaches more than one. - The request body: not JSON, not the shape the operation reads,
a property it does not write, or a value of the wrong type, length
or format.
paramis absent here, since the body is not a parameter, and the message names the property. - The
Idempotency-Keyheader, on an operation that changes something: missing, or a value this API will not store. - An unrecognised
Commune-Version, which answers with its own code,invalid_version, because it is never fixed by changing the body.
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
- A query parameter: one the operation does not have, a value
outside its set, range or format (an unparseable cursor, an unknown
-
No credential was presented, or it is malformed, unknown, revoked or expired, or it is an access token minted for a different audience.
Every one of these answers identically, down to the wording and the headers, so a refusal never confirms that a string was once real.
Hide headers attribute Show headers attribute
-
The authentication scheme this API accepts, and where to find out how to get a credential for it. Always
Bearer realm="Commune API", resource_metadata="https://api.usecommune.com/.well-known/oauth-protected-resource".resource_metadatais the RFC 9728 pointer to this API's protected resource metadata, which names the authorization server an OAuth client should send its user to. A client holding an API key can ignore it. The header carries noerrorparameter, not evenerror="invalid_token", because it describes what this API accepts rather than what was wrong with the credential sent, and the reasons above are deliberately indistinguishable.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.
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
The credential is allowed to do this but the newsletter's plan does not include it.
Two surfaces can answer it: insights, the engagement and metrics operations, which are the only reads Commune reserves the right to meter, and writing, every operation that changes something.
Every other read stays free on every plan, so a credential refused at one of these can still read everything else. The body names the plan the newsletter is on and the plans that would work.
This status is predictable and should not be how you discover it.
GET /newsletters/{newsletter}/entitlementsanswers the same question in advance, carrying the same plan list this puts inallowed_valuesand the same sentence it puts inmessage. Read it once at the start of a run rather than finding out in the middle of one.Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
The credential is valid but is not allowed to do this. Two codes answer with this status, and
error.codesays which.insufficient_scope: it does not hold the permission. The operation needs, say,audience: readon the newsletter addressed, and this credential holds less than that there.allowed_valuescarries the permission that was needed, and the message says what the credential does hold on that newsletter, because a credential granted the wrong family and a credential belonging to somebody whose standing on the team has narrowed look identical without it. The answer can differ per newsletter: the same credential may be allowed here and refused on the next one it reaches.The same code answers an operation that needs the account permission from a credential that does not carry it. That permission is about the person a credential belongs to rather than about any newsletter, so nothing granted on a newsletter adds up to it. It is granted on the credential itself, when a key is minted or when an authorization asks for
account:read.And it answers a parameter the credential may send, but not with the value it sent: a filter a credential holding only
readpermissions may not use, or anexpandpath whose rows need a permission the operation does not.paramnames the parameter, andallowed_valuescarries what this credential may send instead, or is absent when it may send nothing there at all.forbidden: it may not act here at all. Either the credential does not reach the newsletter addressed, because it was never granted it or because the person it belongs to can no longer act on it, or it reaches no newsletter at all;paramisnewsletter, andGET /newsletterslists the ones it does reach. Or, onDELETE /api-keys/{key}, the credential named belongs to somebody else. Neither carriesallowed_values, because there is no value to send instead.Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
No such resource, or the key is not allowed to know that it exists. Commune answers
404rather than403where distinguishing the two would leak the existence of private content.Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
The request collided with something. On a write this is always the
Idempotency-Key, in one of two ways, and the message says which.Either the key was already used for a different request, which is refused rather than answered with the earlier request's result. Or an earlier request using the same key has not finished, or never reported an outcome, in which case this one was not run and the key becomes usable again shortly.
Nothing was changed by a request that answers this.
Hide headers attribute Show headers attribute
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
The request is well formed and every value in it is legal, and the state of what it addresses refuses it anyway. The message says what about that state is in the way.
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
Too many requests. Back off and retry after the interval named by the
Retry-Afterresponse header.One of the budgets in
RateLimit-Policyran out, and theRateLimit-*headers on this response say which and when it resets.Hide headers attribute Show headers attribute
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
-
Something failed inside Commune. The request may be retried.
Hide response attribute Show response attribute object
-
Additional properties are NOT allowed.
Hide error attributes Show error attributes object
-
The stable, machine readable reason a request failed. New codes may be added in a minor version, so treat an unrecognised code as a generic failure of its HTTP status class.
Two of these share a status with a neighbour and exist because what a caller does next is different.
invalid_versionis a400that is never fixed by changing the request body.not_commune_newsletteris a422that is never fixed by changing the request at all: it says the newsletter's articles are published somewhere else and mirrored into Commune afterwards, so Commune cannot write one. Its page athttps://usecommune.dev/errors/not_commune_newsletter, like every code's, is itsdocs_url, and it covers moving a newsletter onto Commune's own publishing, which is the only thing that resolves it.Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,not_commune_newsletter,rate_limited,internal_error, orservice_unavailable. -
A human readable sentence describing what went wrong. Written for a developer reading a log, not for an end user. Do not branch on it, branch on
code. -
The query, path or body parameter the error is attributed to, when the error is attributable to exactly one. Absent otherwise.
-
Everything
paramwould have accepted, when what it accepts is a finite set. Absent when it is not: a cursor, an identifier or a numeric range has nothing to enumerate, and an empty array would read as "nothing is allowed".It repeats what
messagesays in prose, so a caller can correct a request from this one response: the array is what a program branches on, the sentence is what a person or a model reads.On an unknown parameter name rather than an unknown value, this carries the parameter names the operation does accept, since that is the set the caller has to pick from.
On an
insufficient_scopefailure there is usually no parameter at fault andparamis absent, and this carries the one permission that was needed, written the way the permission table writes it, such ascontent: read. The exception is a credential that may call the operation but not with one value of a parameter, such as?expand=subscriberonlistNewsletterInsightswithoutaudience: read: thenparamnames the parameter and this carries the values this credential may send instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the documentation for this error code: always
https://usecommune.dev/errors/followed by the code, a page on what the code means, what usually causes it and how to fix it.
-
-
curl \
--request POST 'https://api.usecommune.com/threads/b3Xn8kTw/messages' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: 3f7c1a26-9b0e-4f5a-9a2c-2c8f1d6b4e77" \
--header "Commune-Version: 2026-08-26" \
--data '{
"content": "Good question. I will cover it next week."
}'
{
"content": "Good question. I will cover it next week."
}
{
"object": "message",
"id": "string",
"short_id": "string",
"thread": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"newsletter": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"author": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"parent": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"quoted": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"depth": 42,
"content": "string",
"media": [
{
"url": "https://example.com",
"type": "string",
"thumbnail": "https://example.com"
}
],
"highlight": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"created_at": "2026-05-04T09:42:00Z",
"updated_at": "2026-05-04T09:42:00Z",
"edited_at": "2026-05-04T09:42:00Z",
"reactions": [
{
"emoji": "🎉",
"count": 42,
"users": [
{
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
}
]
}
]
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
# Headers
WWW-Authenticate: string
# Payload
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
# Headers
Retry-After: 42
# Payload
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
# Headers
Retry-After: 42
# Payload
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}
{
"error": {
"code": "bad_request",
"message": "Newsletter not found.",
"param": "cursor",
"allowed_values": [
"subscribed",
"unsubscribed",
"bounced",
"complained",
"pending"
],
"request_id": "req_01j9c8h1q7m3n4p5r6s7t8u9v0",
"docs_url": "https://usecommune.dev/errors/not_found"
}
}