Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

Email Preferences

Token-based email preference center — allow subscribers to manage their email preferences without login

The preferences API lets your subscribers update their own email preferences without logging in. Access is controlled by a signed token embedded in every unsubscribe and preference link MisarMail generates.

This is a token-based API — no API key or session cookie is required. The subscriber authenticates via a short-lived signed JWT included in outbound email links.

How the token works

Every email sent through MisarMail includes a unique, subscriber-specific signed JWT in the unsubscribe link:

https://mail.misar.io/preferences?token=eyJhbGciOiJIUzI1NiJ9...

The token encodes the subscriber's contact ID and expires after 7 days. An expired or tampered token returns 401.

Get preferences

GET/mail/api/preferences

Returns the subscriber's current category preferences and email frequency.

Query parameters

tokenstringqueryrequired

The signed JWT from the preference link.

Response fields

successboolean

true when the request succeeded.

emailstring

The subscriber's email, masked for privacy (u***@example.com).

preferencesobject

Current category preferences and frequency. If the subscriber has never visited the preference center before, all categories default to true and frequency defaults to "immediate".

{
  "success": true,
  "email": "u***@example.com",
  "preferences": {
    "marketing": true,
    "productUpdates": true,
    "newsletters": false,
    "transactional": true,
    "frequency": "weekly"
  }
}

The email field is masked for privacy — subscribers see enough to confirm it is their address.

Update preferences

PUT/mail/api/preferences

Update the subscriber's category preferences and email frequency.

Request body

tokenstringbodyrequired

The signed JWT from the preference link.

preferences.marketingbooleanbody

Marketing and promotional emails.

preferences.productUpdatesbooleanbody

Product news and feature announcements.

preferences.newslettersbooleanbody

Newsletter subscriptions.

preferences.frequencystringbody

immediate | daily | weekly | monthly | never.

Response fields

successboolean

true when preferences were updated.

messagestring

Human-readable confirmation message.

preferencesobject

The updated preferences, including the read-only transactional flag.

{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "preferences": {
    "marketing": false,
    "newsletters": false,
    "frequency": "weekly"
  }
}
{
  "success": true,
  "message": "Preferences updated",
  "preferences": {
    "marketing": false,
    "productUpdates": true,
    "newsletters": false,
    "transactional": true,
    "frequency": "weekly"
  }
}

transactional emails (password reset, receipts, security alerts) cannot be disabled. The field is read-only and always returned as true.

Generate a preference token

POST/mail/v1/contacts/:id/preference-token

If you are building a custom preference center, generate a token via the contacts API and redirect the user to your own page. Requires an API key. Pass the returned token to your preference center page, then call PUT /api/preferences with it directly.

Path parameters

idstringpathrequired

ID of the contact to generate a preference token for.

Response fields

tokenstring

The signed JWT to embed in your custom preference link.

expires_atstring

ISO-8601 expiry time of the token.

curl -X POST https://api.misar.io/mail/v1/contacts/em_abc123/preference-token \
  -H "Authorization: Bearer msk_..."
{ "token": "eyJhbGciOiJIUzI1NiJ9...", "expires_at": "2025-06-21T10:00:00Z" }

Embedding a preferences link

MisarMail automatically adds unsubscribe and preference links when you send campaigns. For custom HTML emails, inject the link using the {{preferences_url}} merge tag:

<a href="{{preferences_url}}">Manage email preferences</a>

Security

  • Email addresses are masked in GET responses (u***@example.com) to prevent email harvesting via leaked tokens
  • Tokens are signed with HMAC-SHA256 and include an expiry — they cannot be forged or extended
  • The endpoint is rate limited by IP to prevent token enumeration attacks
  • Invalid or expired tokens return 401 Unauthorized with no further detail

Example

# Get preferences
curl "https://api.misar.io/mail/api/preferences?token=eyJhbGciOiJIUzI1NiJ9..."

# Update preferences
curl -X PUT https://api.misar.io/mail/api/preferences \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbGciOiJIUzI1NiJ9...",
    "preferences": { "marketing": false, "frequency": "weekly" }
  }'
// Typically called from your preference center page
const token = new URLSearchParams(window.location.search).get('token');

// Fetch current preferences
const res = await fetch(`/api/preferences?token=${token}`);
const { preferences } = await res.json();

// Save changes
await fetch('/api/preferences', {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ token, preferences: { marketing: false } }),
});