We're looking for contributors to help build open source software.Join usJoin

Showcases

Beacon: Consent as a Service

The automation system handled sending. It had no concept of what staff wanted to receive. Those are different jobs.

The automation system sent the emails. It did that well. What it couldn't do was track whether staff wanted to receive them. There was no permission state, no opt-out record, no way to say "this person asked not to get campaign emails but still wants system notifications." Every message went out the same way. You either sent to everyone or you managed exclusion lists by hand.

Sending and consent are different jobs. The automation system should not need to own both. Beacon is the part that was missing: a small, API-first service that holds one thing, who has consented to what, organized into named buckets. Everything else queries it before acting.

How it fits in

Automation system

n8n, Make, or similar

›

Beacon

check consent

›
Opted in: send
No record: skip
Opted out: skip

The sender calls Beacon before every dispatch. One API call, one answer. The consent logic stays in one place and the sending system stays focused on delivery.

Buckets and permission states

Consent in Beacon is organized into buckets: named groups like internal-announcements, it-notifications, or hr-updates. Each email address in a bucket can hold multiple named permission states. A staff member can be opted in to system alerts but opted out of campaign emails, and those states are independent. Creating a permission record also generates a signed token, a JWT that the staff member can use to manage their own preferences without authenticating.

POST /api/tokens/generate
X-Api-Key: <key>

[{
  "bucket": "internal-announcements",
  "email": "[email protected]",
  "permissions": {
    "campaigns": true,
    "system-alerts": true
  }
}]

The response includes a signed token. Embed that token as a URL in any outgoing email and the recipient can update their own preferences without a login or an account. The token is HMAC-signed and can be validated without a database lookup, unless you want the extra verification.

The self-service flow

1. Send

Email goes out with a /u/{token} link in the footer

2. Click

Staff member opens their preference page, no login needed

3. Update

They toggle permissions per category and save

4. Beacon knows

Next send checks consent. Their updated state is respected

Checking consent before sending

Before any dispatch, the sending system checks whether the recipient has the required permission in the relevant bucket. The response is a single status field.

POST /api/consent/check
X-Api-Key: <key>

{
  "bucket": "internal-announcements",
  "email": "[email protected]",
  "permission": "campaigns"
}

// Response
{ "status": "OptedIn" }

What changed

The automation system still sends, but it asks Beacon first. Staff can opt out through a link in the email footer, and those preferences are respected on the next send without anyone maintaining a list. The admin panel lists consent state per bucket; the override API covers cases where HR or IT need to update a state directly.

Source code and live demo

Full source on GitHub. A live instance is available at beacon-demo.melosso.com.