Audience & broadcasts
Unsubscribes
How one-click unsubscribe headers, the hosted preferences page, topic opt-outs and global unsubscribes work together.
Every broadcast gives the recipient three ways to opt out: an Unsubscribe link in the footer, a hosted preferences page, and the one-click button that Gmail, Yahoo and other mail clients show. Sooner creates all three and applies the choice to the contact.
You do not build or host anything. This page explains what happens so you can design around it.
The unsubscribe link
Each recipient gets their own signed link, available in your content as {{{RESEND_UNSUBSCRIBE_URL}}}. The link identifies the contact and, when the broadcast has a topic, the topic. It cannot be guessed or edited. A link that has been changed returns a "This link isn't valid" page.
Sooner appends an Unsubscribe link and your postal address to every broadcast unless you place the variable yourself. See Broadcasts.
The preferences page
Opening the link shows a page that names the sender and the contact's address:
- If the project has topics, each topic is listed with its description and a checkbox that is ticked when the contact is subscribed. The contact can save their choices, or unsubscribe from all emails.
- If the project has no topics, the page has one button to unsubscribe from all emails.
What each button does:
| Button | Effect |
|---|---|
| Save preferences | Sets each topic to opt in or opt out according to the checkboxes. It also clears a global unsubscribe, so a contact who returns to the page and saves is subscribed again. |
| Unsubscribe from all emails | Sets the contact's global unsubscribed flag to true. |
The page uses no account or login. Anyone with the link can use it, which is why each link is specific to one contact.
One-click unsubscribe
Every broadcast email carries these headers, as required by RFC 8058 and by Gmail and Yahoo for bulk senders:
List-Unsubscribe: <https://.../unsubscribe/TOKEN>
List-Unsubscribe-Post: List-Unsubscribe=One-ClickWhen a recipient clicks the unsubscribe button in their mail client, the client sends a POST request to that link with no page shown. Sooner then applies the choice at once:
- If the link carries a topic, the contact is opted out of that topic only.
- If it carries no topic, the contact is globally unsubscribed.
Transactional emails that you send with a topic_id to a known contact carry the same headers. Emails without a topic_id do not.
Topic opt-out versus global unsubscribe
| Topic opt-out | Global unsubscribe | |
|---|---|---|
| Stored as | A subscription of opt_out on one topic | unsubscribed: true on the contact |
| Effect on broadcasts | Skipped for broadcasts with that topic | Skipped for every broadcast |
Effect on emails with topic_id | Not sent for that topic | Not sent for any topic |
Effect on emails without topic_id | None | None |
| Set by the contact through | The one-click button on a broadcast that has a topic, or the preferences page | The one-click button on a broadcast without a topic, or the preferences page |
| Set by you with | PATCH /contacts/{identifier}/topics | PATCH /contacts/{identifier} with unsubscribed |
Use topics when you send more than one kind of marketing email. A contact who dislikes your weekly digest can leave that topic and keep your product announcements, instead of leaving entirely.
What an unsubscribe does not do
- It does not delete the contact. The contact stays, with
unsubscribed: true, and still counts toward your contact limit. - It does not add the address to the suppression list. Suppressions are for addresses that bounce or complain, or that you block yourself, and apply to all email including transactional.
- It does not stop transactional email that has no
topic_id. - It does not currently trigger a
contact.updatedwebhook. Readunsubscribedfrom the contact if you need to sync it.
Respect for every send
The latest preferences apply to the very next send. Sooner rechecks each broadcast recipient immediately before sending, so a contact who unsubscribes during a long broadcast is not emailed afterward.
Resubscribing
Only add a contact back when the person has asked you to. To resubscribe someone, set unsubscribed to false:
curl -X PATCH https://api.sooner.dev/contacts/ada@example.com \
-H "Authorization: Bearer $SOONER_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "unsubscribed": false }'To opt them back in to a topic, set its subscription to opt_in with PATCH /contacts/{identifier}/topics.