# List a newsletter's subscribers **GET /newsletters/{newsletter}/subscribers** The newsletter's subscribers, most recent first. Creator scope, and returns email addresses, so a key that can call this holds the newsletter's list. This is Commune's own record of the audience. For a newsletter that Commune sends natively it is the source of truth. For a newsletter connected to an outside provider it is a partial cache of that provider's list, filled in by imports and by people who joined through Commune, and it is not the newsletter's subscriber count of record. Ask the provider for that number, and do not present a count derived from this collection as a total. ## Servers - Production. There is no separate sandbox host. : https://api.usecommune.com (Production. There is no separate sandbox host. ) ## Authentication methods - Api key ## Parameters ### Headers - **Commune-Version** (string(date)) The contract version this request is written against, as a release date (`YYYY-MM-DD`). Omitting the header pins the request to the version that was current when the API key was issued, so an integration keeps working when a newer version ships. An unknown value answers `400` with `invalid_version`. ### Path parameters - **newsletter** (string) The newsletter's `id` (a UUID) or its `handle`. 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 - **cursor** (string) The `pagination.next_cursor` value 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. - **limit** (integer) 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_cursor` does. - **expand** (string) Comma separated list of relationship paths to inline in the response. Unexpanded relationships are returned as a reference object carrying only `id` and `object`. Each operation documents the paths it accepts, and an unknown path answers `400`. Nested paths use a dot, for example `article.newsletter`. One accepted path is not a relationship. `?expand=content` on `GET /articles/{article}` adds the Markdown rendition of the body beside the HTML one. It is the same trade the parameter always offers, a fuller response for a larger one, over a property that has more than one representation rather than over a reference. - **fields** (string) Comma separated allow list of top level properties to return on each object, so a client can trim a response it does not need in full. `id` and `object` are always returned. An unknown property name answers `400`. Properties omitted by an operation, such as `content` on any article list, cannot be brought back with `fields`. A trimmed body is a subset of the schema this operation declares, and a property that schema marks required is absent when it was not asked for. That is the point of the parameter, so a client that validates responses against the schema either sends no `fields` or relaxes `required`. - **status** (string) Return only subscribers in this state. Defaults to `subscribed`. Repeat the parameter to accept several. - **tag** (string(uuid)) Return only subscribers holding this tag, by tag `id`. - **source** (string) `commune` returns only the people who joined through Commune, `imported` only those that came from the newsletter's provider or a file. Omit for both. ## Responses ### 200 A page of subscribers, most recently added first. #### Body: application/json (object) - **object** (string) Always `list`, so a response is self describing. - **data** (array) This page of items, in the order the operation documents. - **pagination** (object) 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. ### 400 The request was malformed: an unknown query parameter, an unparseable cursor, an unknown `expand` path, or an unrecognised `Commune-Version`. #### Body: application/json (object) - **error** (object) ### 401 No API key was presented, or the key is unknown, revoked or expired. All four answer identically, down to the wording. Saying that a key was revoked rather than never issued confirms to whoever is holding the string that it was once real, which a legitimate caller does not need and a thief should not get. #### Headers - **WWW-Authenticate** (string) The authentication scheme this API accepts. Always `Bearer realm="Commune API"`; there is no second scheme and no query-parameter fallback, because a credential that can travel in a URL ends up in access logs and referer headers. #### Body: application/json (object) - **error** (object) ### 403 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. #### Body: application/json (object) - **error** (object) ### 404 No such resource, or the key is not allowed to know that it exists. Commune answers `404` rather than `403` where distinguishing the two would leak the existence of private content. #### Body: application/json (object) - **error** (object) ### 429 Too many requests. Back off and retry after the interval named by the `Retry-After` response header. #### Headers - **Retry-After** (integer) Seconds to wait before retrying. #### Body: application/json (object) - **error** (object) ### 500 Something failed inside Commune. The request may be retried. #### Body: application/json (object) - **error** (object) [Powered by Bump.sh](https://bump.sh)