List a newsletter's automations Run in API Explorer
The newsletter's automations, most recently written first. Needs
sending: read.
Archived ones are left out unless ?status=archived asks for them.
Deleting an automation archives it rather than removing it, because the
runs underneath it are the record of what was emailed to whom, so
without that default the answer to "what automations do I have" would be
a history.
Each row is an AutomationSummary, which is the automation without its
graph. A send_email step holds a whole email body, so a page of
automations with their graphs inlined would be a newsletter's worth of
prose; step_count is enough to tell an empty draft from a built
sequence, and GET /automations/{automation} has the graph.
Headers
-
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 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
-
The
pagination.next_cursorvalue from the previous page. Omit it to read the first page. A cursor is opaque, is only valid for the same operation with the same filters, and is not a durable identifier.Maximum length is
512. -
How many items to return in this page. This is a page size, not an offset. Fewer items than requested may come back and that does not mean the collection is exhausted, only an absent
next_cursordoes.Minimum value is
1, maximum value is100. Default value is20. -
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. -
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. -
Return only automations in this state. Defaults to every state but
archived. Repeat the parameter to accept several.Values are
draft,active,paused, orarchived.
Responses
-
A page of the newsletter's automations, most recently written first.
Hide response attributes Show response attributes object
-
Always
list, so a response is self describing.Value is
list. -
Cursor pagination state. Commune never exposes an offset or a page number: a collection is a moving window, and an offset silently skips or repeats items when the window shifts between two requests.
Additional properties are NOT allowed.
Hide pagination attributes Show pagination attributes object
-
This page of the newsletter's automations, most recently written first, each without its graph. Read one automation to get the steps, the conditions and the emails it sends.
Hide data attributes Show data attributes object
An automation without its graph, which is what a page of them carries.
A
send_emailstep holds a whole email body, so a page of automations with their graphs inlined would be a newsletter's worth of prose in the answer to "what automations do I have".step_countis enough to tell an empty draft from a built sequence;GET /automations/{automation}has the graph.objectdiffers fromAutomation's, so a row always says which shape it is. One discriminator for both, withstepssometimes absent, would make "this automation has no steps" and "this is the short form" the same response.-
Always
automation_summary.Value is
automation_summary. - newsletter
object | null Required The newsletter this automation 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,mailcheap,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. Set and changed by the newsletter's team.A third value,
paid, was in this enum until 2026-10-10. It was never produced by anything and no thread ever carried it, so it was removed rather than left as a state consumers had to handle. See Removals under Versioning.Values are
publicorsubscribers. -
truewhen this thread is a private room: it was scoped to one or more of the newsletter's subscriber segments, and only the people holding one of those segments and the newsletter's team can read it or its replies. Evaluated live, so losing the segment takes the conversation away on the next request.A private thread is never on the global feed, so
visibilityissubscriberswhenever this istrue. Scoping apublicthread to a room moves it tosubscribersin the same write.Always present. It says that the conversation is private without saying to whom, which is why every credential that can read the thread gets it while
audience_tag_idsis narrower. -
Which segments the thread is private to, by tag
id, ornullwhen it is not private. The semantics are OR: holding any one of them is enough.Present only for a credential holding
audience: readon this newsletter. A thread iscontent, and the words in it come back to any credential the thread's own gate admits; which segments it was addressed to is theaudiencefamily's fact, priced ataudience: readeverywhere else a credential can ask for it (GET /newsletters/{newsletter}/tags,GET /tags/{tag}). So a credential without that family seesaudience_scopedand not this property, and cannot read a creator's segmentation off a conversation. Absent andnullare different answers: absent is "this credential may not read it",nullis "there is none".Every id here is a tag with
is_roomset, because that is the only kind a thread can be scoped to. A tag that was since retired or un-roomed stays in the list and goes on deciding who may read the thread, exactly as it goes on deciding the audience of an article it was addressed to. -
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.
-
-
Where an automation is in its life.
draftis where every automation starts and the only status a create can produce.activeis the one status that sends: the engine's ingest and its claim on due work both filter on it, so nothing an automation holds reaches anybody until somebody turns it on.pausedholds every waiting run exactly where it is. A run three days into a sequence stays on that step and resumes from it when the automation is turned on again, so a pause is instant and total rather than a drain.archivedis whatDELETEleaves behind. It is not sending and it is not coming back: the runs it was in the middle of are ended, because a run holding its place on a graph nobody will activate again is a subscriber stuck part way through forever. The automation and its history stay readable, which is the reason it is archived rather than deleted.Values are
draft,active,paused, orarchived. -
The event that starts a run.
Every topic Commune publishes is a trigger, including the ones that are not about a subscriber. An automation on
article.publishedcan hold conditions and waits; it cannot send an email or move a tag, because there is nobody for those to act on, and saving one that tries is refused rather than left to fail once per event forever.GET /automation-triggerssays, per topic, which properties its events carry and whether it is about a subscriber. That is what a condition can ask about.Values are
article.liked,article.published,article.read,article.scheduled,automation.run.completed,automation.run.exited,automation.run.started,billing.subscription.updated,delivery.bounced,delivery.clicked,delivery.complained,delivery.delivered,delivery.opened,domain.verified,highlight.created,import.completed,message.created,send.completed,send.failed,sender.verified,subscriber.created,subscriber.status_changed,subscriber.tagged,subscriber.unsubscribed,thread.created, orthread.published. -
How many steps the graph has.
Minimum value is
0.
-
-
-
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 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.
-
-
-
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 GET 'https://api.usecommune.com/newsletters/9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e/automations' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Commune-Version: 2026-08-26"
{
"object": "list",
"data": [
{
"object": "automation_summary",
"id": "9c1e4b7a-2d35-4f61-8a90-1b2c3d4e5f60",
"newsletter": {
"object": "newsletter",
"id": "7d3f1c02-58a1-4a4e-9a0b-2f6d1c9e4411"
},
"name": "Welcome sequence",
"status": "active",
"trigger": "subscriber.created",
"trigger_filter": null,
"reentry": false,
"step_count": 3,
"created_at": "2026-10-01T09:00:00Z",
"updated_at": "2026-10-02T11:15:00Z",
"activated_at": "2026-10-02T11:16:00Z"
},
{
"object": "automation_summary",
"id": "1a2b3c4d-5e6f-4071-8293-a4b5c6d7e8f9",
"newsletter": {
"object": "newsletter",
"id": "7d3f1c02-58a1-4a4e-9a0b-2f6d1c9e4411"
},
"name": "Win-back",
"status": "draft",
"trigger": "subscriber.unsubscribed",
"trigger_filter": null,
"reentry": true,
"step_count": 0,
"created_at": "2026-10-05T14:30:00Z",
"updated_at": "2026-10-05T14:30:00Z",
"activated_at": null
}
],
"pagination": {
"has_more": false,
"next_cursor": null
}
}
{
"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"
}
}
# 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"
}
}