setEmailPreferences

Public token (HMAC) callable

Update a guest's email preferences via the same HMAC token (CAN-SPAM / CASL / GDPR Art. 7(3) compliant).

METHOD POST
PATH /setEmailPreferences
AUTH Public token (HMAC)

The opt-out write-side of the unsubscribe flow. Accepts the same token used by getEmailPreferences plus a `preferences` patch of booleans. Merges into users/{uid}.emailPreferences. Transactional emails are legally required and cannot be turned off — any client-submitted `transactional: false` is silently ignored. Two rate limits stack: 20 calls/IP/hour AND 10 writes/token/24h, both fail-open.

AUTH NOTE

No Firebase Auth required. Gated on a short-lived HMAC-signed token that the platform embeds in the relevant link (unsubscribe email, etc.).

Request

FieldTypeRequiredDescription
token string yes Same HMAC token format as getEmailPreferences.
preferences.lifecycle boolean no Lifecycle drip subscription.
preferences.recap boolean no Event-recap email subscription.
preferences.marketing boolean no Product / marketing subscription.

EXAMPLE BODY

{
  "token": "eyJ1c2VySWQiOiJ1XzAxSFY5WFQiLCJleHAiOjE3MTk1MDA4NjAwMDAsInNjb3BlIjoiZW1haWwtcHJlZnMifQ.x7Hk9aBcDeFgHiJkLmNoPqRsTu0",
  "preferences": {
    "lifecycle": false,
    "marketing": false
  }
}

Response

FieldTypeAlways presentDescription
ok boolean yes Always true on successful write.
updated string yes ISO 8601 UTC timestamp of the write.

EXAMPLE BODY

{
  "ok": true,
  "updated": "2026-05-21T14:22:08.000Z"
}

curl

curl -X POST https://us-central1-freedomgrc-photowall.cloudfunctions.net/setEmailPreferences \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "token": "<your-prefs-token>",
      "preferences": { "lifecycle": false, "marketing": false }
    }
  }'

JavaScript

We don't ship a first-party JS SDK yet (it's on the roadmap). For callable endpoints, the Firebase Functions SDK is the recommended path — it handles ID-token attachment and payload framing. Plain fetch works too.

const response = await fetch(
  'https://us-central1-freedomgrc-photowall.cloudfunctions.net/setEmailPreferences',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      data: {
        token: prefsToken,
        preferences: { lifecycle: false, marketing: false },
      },
    }),
  },
);
const { result } = await response.json();
// result === { ok: true, updated: '...' }

Error cases

CodeWhen
invalid-argument Token missing/malformed, or preferences is not an object of booleans, or a non-toggleable key was sent.
permission-denied Token signature invalid, expired, or wrong scope.
internal Firestore write failed.

Need a different shape?

The API surface is small. Tell us what you need and we'll work backward from your integration.

Request an endpoint Back to API index