One snapshot of a newsletter over a window: how the audience moved, what was published, how much the community talked, and how the email performed. It answers the question a dashboard opens with, in one call rather than six.
Every number is scoped to the window. Pick the window with period, or
state it exactly with since and until.
Read audience and publishing carefully before charting them.
Commune's record of a newsletter's subscribers is complete only for a
newsletter Commune sends natively. For one connected to an outside
provider it is a partial cache of that provider's list, which is why the
field is called known_subscribers and not subscriber_count. Do not
present it as the newsletter's audience size, and ask the provider for
that number instead. publishing.sent counts the issues Commune has a
record of and is never a count of emails delivered, which lives in
delivery.
Headers
-
The contract version this request is written against, as a release date (
YYYY-MM-DD). Omitting the header pins the request to the version that was current when the API key was issued, so an integration keeps working when a newer version ships. An unknown value answers400withinvalid_version.
Path parameters
-
The newsletter's
id(a UUID) or itshandle. A handle is unique across Commune and is the identifier its public web profile uses, so it is the one to hardcode in an integration.
Query parameters
-
Comma separated list of relationship paths to inline in the response. Unexpanded relationships are returned as a reference object carrying only
idandobject. Each operation documents the paths it accepts, and an unknown path answers400. Nested paths use a dot, for examplearticle.newsletter.One accepted path is not a relationship.
?expand=contentonGET /articles/{article}adds the Markdown rendition of the body beside the HTML one. It is the same trade the parameter always offers, a fuller response for a larger one, over a property that has more than one representation rather than over a reference. -
Comma separated allow list of top level properties to return on each object, so a client can trim a response it does not need in full.
idandobjectare always returned. An unknown property name answers400. Properties omitted by an operation, such ascontenton any article list, cannot be brought back withfields.A trimmed body is a subset of the schema this operation declares, and a property that schema marks required is absent when it was not asked for. That is the point of the parameter, so a client that validates responses against the schema either sends no
fieldsor relaxesrequired. -
A named window, counted back from today in UTC. Defaults to
30d. Ignored whensinceis given, so a request never has to reconcile two conflicting windows.Values are
7d,14d,30d,90d,6m,1y, orall. Default value is30d. -
Start of the window, inclusive, as a date or an RFC 3339 timestamp. Giving this overrides
period. Asincelater thanuntilanswers400. Anything that is neither of those two shapes answers400as well, rather than being guessed at: a lenient parser would read8/1/2026as a date and give two callers different windows for the same string.Maximum length is
40. -
End of the window, exclusive, as a date or an RFC 3339 timestamp. Defaults to now. Only meaningful alongside
since.Maximum length is
40.
Responses
-
The newsletter's numbers for the resolved window.
Hide response attributes Show response attributes object
-
Always
newsletter_stats.Value is
newsletter_stats. newsletter
object | null Required The newsletter these numbers describe. 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.
nativemeans 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
native,beehiiv,buttondown,ghost,kit,mailchimp,mailerlite,rss, orsubstack. -
Square avatar for the newsletter.
-
Wide cover image shown at the top of the profile.
-
The creator's brand colour as a CSS hex triplet, used to tint the profile. Null when they never picked one.
-
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 issues 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. Read only here: the API does not create threads.
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. This is the entire shape Commune will ever return for someone who is not the key holder. Email address, theme, notification preferences, push subscriptions, read state and saved articles are deliberately absent.
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 issue 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 issue. newsletter
object | null Required The newsletter this issue 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 issue. 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 issue.
-
The issue's canonical URL on the newsletter's own provider, for an imported article. Null for a natively published one.
-
Where an issue is in its life. Only
sentis ever visible to a public key. An imported article is alwayssent, since Commune sees it after the provider delivered it.Values are
draft,scheduled,sending,sent,failed, orarchived. -
truewhen the issue came in from the newsletter's provider,falsewhen it was written and sent natively in Commune. -
When the issue 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.
-
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. This is the entire shape Commune will ever return for someone who is not the key holder. Email address, theme, notification preferences, push subscriptions, read state and saved articles are deliberately absent.
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 issue opened, where its discussion lives.
nullwhen the newsletter does not open a thread per issue. 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. This is the entire shape Commune will ever return for someone who is not the key holder. Email address, theme, notification preferences, push subscriptions, read state and saved articles are deliberately absent.
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 older attachment that predates the field. -
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 issue of a newsletter, without its body. Every collection of articles returns this shape.
GET /articles/{article}returnsArticleWithContent, which is this pluscontent.-
-
Whether the team pinned this thread to the top of the community.
-
Whether the team closed the thread to new replies.
-
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 issue was last edited.
-
-
When the newsletter was connected to or created on Commune.
-
When the profile last changed.
-
-
Start of the resolved window, inclusive. Echoed because
period,sinceanduntilcan each decide it. -
End of the resolved window, exclusive.
-
How the list moved. Every count here comes from Commune's own subscriber records, which are the source of truth only for a newsletter Commune sends natively.
Additional properties are NOT allowed.
Hide audience attributes Show audience attributes object
-
How many subscribers Commune has a record of at
period_end. Not the newsletter's subscriber count. For a newsletter connected to an outside provider, Commune's records are a partial cache of that provider's list, filled in by imports and by people who joined through Commune, so this is a floor and not a total. Ask the provider for the real number.Minimum value is
0. -
Subscribers gained minus subscribers lost inside the window, against the same partial record. Negative when the list shrank.
-
How the known subscribers split across the subscription states at
period_end. The keys are theSubscriberStatusvalues.Additional properties are NOT allowed.
Hide by_status attributes Show by_status attributes object
-
Mailable.
Minimum value is
0. -
Opted out, and kept so the history survives.
Minimum value is
0. -
Undeliverable, and suppressed by the send pipeline.
Minimum value is
0. -
Reported the email as spam, and suppressed.
Minimum value is
0. -
Recorded but not yet confirmed as mailable.
Minimum value is
0.
-
-
-
Cadence. These are counts of issues, never counts of emails.
Additional properties are NOT allowed.
Hide publishing attributes Show publishing attributes object
-
Issues that went out inside the window and that Commune has a record of. Commune's article table is filtered rather than exhaustive, so this must never be presented as the number of emails the newsletter sent. That number lives on a send.
Minimum value is
0. -
Issues queued to go out after
period_end. A forward looking count, so it does not move when the window does.Minimum value is
0.
-
-
What happened in the newsletter's community inside the window. All four are Commune side counts with no email equivalent.
Additional properties are NOT allowed.
Hide community attributes Show community attributes object
-
Conversations started, including the ones Commune opens under a published article.
Minimum value is
0. -
Replies posted inside those conversations. An article's comments are replies in its thread, so they are counted here.
Minimum value is
0. -
Passages readers marked inside an article.
Minimum value is
0. -
Emoji reactions added to a message.
Minimum value is
0.
-
-
How the email performed across the issues sent inside the window.
nullfor a newsletter Commune does not send, because the provider that sent the mail holds those numbers and does not hand them over per issue.Additional properties are NOT allowed.
Hide delivery attributes Show delivery attributes object | null
-
Opens over deliveries, as a fraction between
0and1.nullwhen nothing was delivered in the window, which is not the same as a rate of zero. Open tracking is unreliable by nature: a mail client that prefetches images inflates it and one that blocks them suppresses it.Minimum value is
0, maximum value is1. -
Recipients who clicked at least one link, over deliveries, as a fraction between
0and1.nullwhen nothing was delivered in the window.Minimum value is
0, maximum value is1.
-
-
-
The request was malformed: an unknown query parameter, an unparseable cursor, an unknown
expandpath, or an unrecognisedCommune-Version.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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
-
No API key was presented, or the key is unknown, revoked or expired.
All four answer identically, down to the wording. Saying that a key was revoked rather than never issued confirms to whoever is holding the string that it was once real, which a legitimate caller does not need and a thief should not get.
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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
-
The key is valid but is not allowed to read this. Either it carries public scope and the operation needs creator scope, or it is bound to a different newsletter than the one addressed.
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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
-
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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
-
Too many requests. Back off and retry after the interval named by the
Retry-Afterresponse header.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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
-
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.
Values are
bad_request,invalid_version,unauthorized,forbidden,insufficient_scope,payment_required,not_found,conflict,unprocessable,rate_limited, orinternal_error. -
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 is deliberately redundant with
message, which names the same values in prose. The array is what a program branches on and the sentence is what a model reads, and a caller correcting a request has to be able to do it from this one response without opening a reference page.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 no parameter at fault andparamis absent, and this carries the scopes that would have been accepted instead. -
Identifier for this request, echoed in the
Commune-Request-Idresponse header. Quote it in support requests. -
Link to the reference page for this error code.
-
-
curl "https://api.usecommune.com/newsletters/the-weekly/stats?period=90d" \
-H "Authorization: Bearer $COMMUNE_API_KEY" \
-H "Commune-Version: 2026-08-26"
curl \
--request GET 'https://api.usecommune.com/newsletters/9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e/stats' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Commune-Version: 2026-08-26"
{
"object": "newsletter_stats",
"newsletter": {
"object": "newsletter",
"id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
},
"period_start": "2026-05-04T09:42:00Z",
"period_end": "2026-05-04T09:42:00Z",
"audience": {
"known_subscribers": 42,
"net_change": 42,
"by_status": {
"subscribed": 42,
"unsubscribed": 42,
"bounced": 42,
"complained": 42,
"pending": 42
}
},
"publishing": {
"sent": 42,
"scheduled": 42
},
"community": {
"threads": 42,
"messages": 42,
"highlights": 42,
"reactions": 42
},
"delivery": {
"open_rate": 42.0,
"click_rate": 42.0
}
}
{
"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.com/docs/api/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.com/docs/api/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.com/docs/api/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.com/docs/api/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.com/docs/api/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.com/docs/api/errors#not_found"
}
}