Sending Preferences

Full request reference for the LiSTNR Preferences Webhook.


Endpoint

POST /update
EnvironmentURL
Dev<dev-url>/update
Production<prod-url>/update

Authentication

Every request requires two headers:

Authorization

Include the LiSTNR JWT obtained from the Token Provider as a Bearer credential.

Authorization: Bearer <access_token>

The token must have been issued with the write:preferences scope and the salesforce-preference-centre audience. A missing, expired, or invalid token returns 401 Unauthorized. A valid token without the required scope returns 403 Forbidden.

See Getting Started for how to obtain a token.

x-listnr-source

Identify the calling system with this header. The value must be exactly salesforce-preference-centre.

x-listnr-source: salesforce-preference-centre

A missing or incorrect value returns 400 Bad Request with code INVALID_SOURCE_HEADER.


Request body

Send a JSON array of one or more preference update items. The array must not be empty.

[
  {
    "emailSha": "<sha256-of-email>",
    "brand": "listnr",
    "preference": "NEWSLETTER",
    "status": "SUBSCRIBED",
    "timestamp": "2024-01-01T00:00:00.000Z",
    "source": "PREFERENCE_CENTRE",
    "reason": null
  }
]

Field reference

FieldTypeRequiredDescription
emailShastringyesSHA-256 hash of the user's email address (lowercase hex). Used to identify the user in Firestore.
brandstringyesThe brand the preference applies to (e.g. listnr).
preferenceenumyesThe preference channel. See Preference channels.
statusenumyesThe new subscription status. See Preference statuses.
timestampstringyesISO 8601 timestamp of when the preference change occurred.
sourcestringyesMust be PREFERENCE_CENTRE.
reasonobject | nullnoOptional unsubscribe reason. See Reason object.

Preference channels

ValueDescription
NEWSLETTEREmail newsletter subscription
PARTNERPartner marketing communications
COMPETITIONCompetition-related communications
BRANDBrand marketing communications

Preference statuses

ValueDescription
SUBSCRIBEDUser has opted in
UNSUBSCRIBEDUser has opted out

Reason object

Present only when status is UNSUBSCRIBED. May be null.

FieldTypeRequiredDescription
codestringyesNormalised unsubscribe reason code.
codeRawstringnoRaw code as received from the source system.
descriptionRawstringnoHuman-readable description from the source system.

Response

200 OK

Preferences were accepted and written to Firestore.

{
  "processedCount": 1
}

Error responses

StatusCodeCause
400INVALID_SOURCE_HEADERx-listnr-source header is missing or does not equal salesforce-preference-centre
400BODY_NOT_ARRAYRequest body is not a JSON array
400BODY_EMPTY_ARRAYRequest body is an empty array
400MISSING_EMAIL_SHAAn item is missing the emailSha field
400MISSING_BRANDAn item is missing the brand field
400INVALID_PREFERENCEAn item has an unrecognised preference value
400INVALID_STATUSAn item has an unrecognised status value
400MISSING_TIMESTAMPAn item is missing the timestamp field
400INVALID_SOURCEAn item's source field is not PREFERENCE_CENTRE
400MISSING_REASON_CODEA reason object is present but missing the code field
401Missing, expired, or invalid Bearer token
403Token is valid but does not carry the write:preferences scope