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
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.
Full source on GitHub. A live instance is available at beacon-demo.melosso.com.