# Retrieve a subscriber **GET /subscribers/{subscriber}** Read one subscriber by `id`. Creator scope, and only within a newsletter the key is bound to: the same person subscribing to two newsletters is two subscribers, and one creator never sees the other's row. ## 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 - **subscriber** (string(uuid)) The subscriber's `id`. This identifies one person's membership of one newsletter, not the person, and a subscriber has no short id. ### Query parameters - **expand** (string) Comma separated list of relationship paths to inline in the response. Unexpanded relationships are returned as a reference object carrying only `id` and `object`. Each operation documents the paths it accepts, and an unknown path answers `400`. Nested paths use a dot, for example `article.newsletter`. One accepted path is not a relationship. `?expand=content` on `GET /articles/{article}` adds the Markdown rendition of the body beside the HTML one. It is the same trade the parameter always offers, a fuller response for a larger one, over a property that has more than one representation rather than over a reference. - **fields** (string) Comma separated allow list of top level properties to return on each object, so a client can trim a response it does not need in full. `id` and `object` are always returned. An unknown property name answers `400`. Properties omitted by an operation, such as `content` on any article list, cannot be brought back with `fields`. A trimmed body is a subset of the schema this operation declares, and a property that schema marks required is absent when it was not asked for. That is the point of the parameter, so a client that validates responses against the schema either sends no `fields` or relaxes `required`. ## Responses ### 200 The subscriber. #### Body: application/json (object) - **object** (string) Always `subscriber`. - **id** (string(uuid)) Stable identifier for this membership. - **newsletter** (object | null) The newsletter subscribed to. A `Ref` unless `newsletter` is named in `?expand=`. - **user** (object | null) The Commune account behind the subscription, or `null` for someone who joined by email without one. A `Ref` unless `user` is named in `?expand=`. - **email** (string(email)) Where the newsletter reaches this person. Returned on every subscriber row, including one that has a Commune account behind it, because reconciling a list against the provider that holds it is the job this collection exists for and the people who joined through Commune are exactly the ones that provider has never heard of. For a row with no account the address is the one the person subscribed with. For a row with an account it is the address on that account, which is where the issue is actually delivered. Never null: a subscription is either an address or an account, and an account always carries one. This is the one place in the API an address appears. It is a property of the subscription and not of the person, so it is never on a public profile, never on an expanded author, and never reachable from a key bound to another newsletter. Reading it needs creator scope, counts against a tighter rate limit budget than everything else, and writes a row to Commune's audit log naming the key and how many subscribers it read. - **status** (string) Where a subscription stands. Source of truth for a newsletter Commune sends natively. For a newsletter connected to an outside provider it reflects what Commune last saw of the provider's state. - **source** (string) `commune` when the person subscribed through Commune, `imported` when they came from the newsletter's provider or a file. - **tags** (array[object]) The audience tags this subscriber holds, which is what decides which tag scoped issues reach them. Each entry is a `Ref` unless `tags` is named in `?expand=`. - **created_at** (string(date-time)) When Commune first recorded the subscription. - **synced_at** (string(date-time) | null) When this row was last reconciled with the newsletter's provider. Null for a native newsletter, which has no provider to reconcile with. ### 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)