Subscribers

Erase a subscriber

Erases this subscription. Needs audience: write, is a write, and requires a request body confirming the erasure.

This is an erasure, not an unsubscribe, and it cannot be undone. The subscriber record goes, and everything keyed on it goes with it: the tags they held, their per-article delivery rows, and any automation run that named them, along with the automation emails those runs sent. The newsletter's send totals are counters and do not move, but "did this person open that article" stops having an answer. It is the call for somebody exercising a right to erasure.

To stop mailing somebody, set their status instead (PATCH /subscribers/{subscriber} with {"status": "unsubscribed"}). That keeps the record, so a bounce or a complaint on the address is remembered and Commune does not mail it again by accident, and a reader who comes back reuses the same row. It is also reversible, and this is not.

The confirmation

Send {"confirm": "erase_subscriber_and_history"}. Without it, or with any other value, the request is refused 400 with param set to confirm and allowed_values holding the one accepted string, and nothing is erased: the subscriber, the tags they hold and their delivery history are all exactly as they were.

The refusal is not a formality to route around. It exists because this call and PATCH /subscribers/{subscriber} read alike and do not undo alike, so an integration reaching for "remove this subscriber" lands here by default and loses the record of everything that was ever sent to that person. If what you want is for the newsletter to stop reaching somebody, the status write is the call, and it is the one to reach for when you are not sure.

A change in the contract as of this version, with no compatibility fallback. A DELETE that sent no body succeeded before and is refused 400 now. An integration that erases subscribers has to send the confirmation; one that wanted an unsubscribe was reaching for the wrong call and the refusal names the right one.

Publishes subscriber.unsubscribed with reason: removed, before the row goes, and only when the subscriber was still subscribed. Deleting somebody who had already unsubscribed, bounced or complained publishes nothing: they did not stop being mailable, they already had. Reconcile a mirror of the list against GET /newsletters/{newsletter}/subscribers rather than against this topic alone.

Answers the subscriber as it last stood, so the response is a record of what was removed rather than an empty body. It is a receipt and not a lookup: a GET on the same id answers 404 from here on. The same address can be added again afterwards, as a new subscription with a new id and no history.

delete/subscribers/{subscriber}

Request

  • Base URL: https://api.usecommune.com
  • URL: https://api.usecommune.com/subscribers/{subscriber}
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://usecommune.com/api/oauth/authorize, token URL https://usecommune.com/api/oauth/token, scopes: audience:write)

Headers

Idempotency-Keystring required

A value of your choosing naming the change this request is making.

Send the same value again to retry the same request. Commune replays the answer the first attempt gave instead of making the change twice, and marks the replay with an Idempotent-Replay: true response header. Send a different value for a different change: a key reused for a request that differs in any way answers 409, because replaying an answer to a question you did not ask is a wrong answer you could not detect.

A UUID per change is the usual choice. Remembered for 24 hours, per credential, so two credentials choosing the same value never see each other's answers.

Required, not optional.

Request body

confirm'erase_subscriber_and_history' required

Always erase_subscriber_and_history, written out in full.

Anything else, including true and including an absent body, is refused with 400, param set to confirm and allowed_values holding the one value this accepts. Nothing is erased by a refused request.

Example request

{
  "confirm": "erase_subscriber_and_history"
}

Response

The subscriber that was erased, as it last stood.

object'subscriber' required

Always subscriber.

idstring uuid required

Stable identifier for this membership.

emailstring email required

Where the newsletter reaches this person. Returned on every subscriber, including one with a Commune account behind them.

For a subscriber with no account it is the address they subscribed with. For one with an account it is the address on that account, which is where the article is actually delivered. Never null.

This is the one place in the API an address appears. It is a property of the subscription rather than of the person, so it is never on a public profile, never on an expanded author, and never reachable from a credential granted another newsletter. Reading it needs audience: read, counts against the tighter audience rate limit budget, and is recorded in Commune's audit log with the credential and how many subscribers it read.

status'subscribed' | 'unsubscribed' | 'bounced' | 'complained' | 'pending' required

Where a subscription stands. Source of truth for a commune newsletter. For a newsletter connected to an outside provider it reflects what Commune last saw of the provider's state.

source'commune' | 'imported' | 'unknown'

How the subscription was made. commune when the subscription was made on Commune: the person pressed subscribe, finished signup or accepted an invitation, or the newsletter's own integration added them with POST /newsletters/{newsletter}/subscribers. imported when they arrived in an import of the newsletter's provider list or a file.

Not the same question as whether Commune grew the list. Somebody who subscribes through Commune to a newsletter whose provider already held their address is commune here, even though the creator's list did not get longer.

unknown for a subscription recorded before Commune kept this. It is stated rather than left out, so "Commune does not know" cannot be mistaken for imported.

created_atstring date-time required

When Commune first recorded the subscription.

synced_atstring date-time nullable

When this row was last reconciled with the newsletter's provider. Null for a commune newsletter, which has no provider to reconcile with.

Example response

{
  "newsletter": {
    "object": "newsletter",
    "id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
  },
  "user": {
    "object": "newsletter",
    "id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
  },
  "tags": [
    {
      "object": "newsletter",
      "id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.