Subscribers

Update a subscriber

Sets whether this subscriber is on the list. Needs audience: write, and is a write.

status is the whole of what this writes, and only two of its five values can be sent. bounced and complained are verdicts a mailbox provider reached, so setting one would be asserting somebody else's answer on their behalf, and pending belongs to a confirmation flow nothing in this API starts. The address is not writable either: it is the subscription's identity, and on a subscriber with a Commune account behind them it lives on that account rather than here. Add the right address and delete the wrong one.

Both directions publish:

  • To unsubscribed: subscriber.unsubscribed with reason: removed, which is the reason that means the newsletter did it rather than the reader. The row survives, so bounce and complaint history is kept and GET goes on resolving them.
  • To subscribed: subscriber.created with resubscribed: true, exactly as a reader coming back publishes. Automations treat it as not a new subscriber, so nobody is welcomed again.

Setting the status it already has succeeds, changes nothing and publishes nothing. Setting subscribed on a complained subscriber is refused with 422: only the reader can undo a spam complaint, by subscribing again themselves.

Unlike Add a subscriber, this does not change source. A subscription imported from a provider and reactivated here is still an imported subscription, because what moved was one column of an existing row and not a new subscription being made.

patch/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

status'subscribed' | 'unsubscribed' required

The two states a caller may put a subscription in: on the list, or off it.

A narrower set than SubscriberStatus on purpose, and the three that are missing are missing for two different reasons. bounced and complained are verdicts a mailbox provider reached, so a caller setting one would be asserting somebody else's answer on their behalf; they arrive on their own, with the matching delivery.* event. pending belongs to a confirmation flow nothing in this API starts, so it would be a state nothing could ever move a subscriber out of.

Example request

{
  "status": "unsubscribed"
}

Response

The subscriber, as it now stands.

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.