Source: https://www.hype-stack.dev/docs/packs-templates/packs/pack-newsletter

# Newsletter

Newsletter subscriptions with public signup, one-click unsubscribe, a hosted archive, and an admin email studio that
writes, schedules, and sends releases through Resend. This is the `pack-newsletter` pack. The
[Indie Hacker](/docs/packs-templates/templates/indie-hacker) template is built on it.

## What you need

- **Resend**, with a verified sending domain. Uses the base template's `RESEND_API_KEY` and `RESEND_FROM_DOMAIN`.
- A **Resend webhook** so delivery, bounce, and complaint events flow back (below).
- Postgres, Valkey, and RustFS (images uploaded in the studio go to your bucket).

## What it depends on

- A **starter pack** for auth. Only the `auth` capability, so the free starter is enough: subscribers are public, not
  organization members.

## What you get

**Public side**

- `/newsletter`: a hosted archive of past releases with a signup panel.
- A compact signup component and a capture dock you can drop anywhere, including the landing page.
- One-click unsubscribe from every email, with undo, and a GDPR hard delete.
- An idempotent public subscribe API, rate limited by the base template's guards.

**Admin side**

- An email studio: block-based composer rendered to table HTML plus plain text, a template gallery, image uploads, and a
  custom-HTML mode.
- Releases home with drafts, scheduled sends, and sent history.
- An audience page with ranges over subscribers, and open and click tracking into your own database.
- Link tracking drill-down per release.

## Background job

Sending is not tied to a request. A `newsletter-dispatch` job runs every minute on the template's scheduler, picks up
releases whose `scheduledAt` is due, and fans them out to Resend in paced batches with a per-recipient unsubscribe link.
The send is a resumable ledger: a crashed dispatcher is re-adopted on the next tick and never double-sends. See
[Scheduled jobs](/docs/backend#scheduled-jobs).

## Webhook endpoint

Resend reports delivery events to:

```
POST /newsletter/webhooks/resend
```

In the Resend dashboard, add a webhook for that URL on your API origin, subscribe to `email.delivered`, `email.bounced`,
and `email.complained`, and copy its signing secret into `RESEND_WEBHOOK_SECRET`. Bounces and complaints suppress the
address automatically. Opens and clicks do not go through Resend: the pack tracks them itself, into your own tables.

## Environment variables

| Variable                      | Purpose                                                   |
| ----------------------------- | --------------------------------------------------------- |
| `RESEND_API_KEY`              | Base template. Sends the emails                           |
| `RESEND_FROM_DOMAIN`          | Base template. Verified sending domain                    |
| `RESEND_WEBHOOK_SECRET`       | Verifies delivery events on `/newsletter/webhooks/resend` |
| `NEWSLETTER_SEND_RATE`        | Emails per second (default 8)                             |
| `NEWSLETTER_SEND_CONCURRENCY` | Parallel sends (default 8)                                |

Keep the rate under your Resend plan's limit. The defaults are safe for the free tier.

## After installing

Five Prisma models arrive (subscribers, releases, deliveries, events, templates). Say yes when the CLI offers to run the
migration, or run `pnpm --filter @hype-stack/backend migration:create` afterwards.

## Related

- [Mailing](/docs/backend/mailing) for the Resend client the pack shares with auth and billing
- [Indie Hacker](/docs/packs-templates/templates/indie-hacker), the template built on this pack
