# Update contact email preferences by ID Updates one or more email preferences for a customer contact by their Featurebase ID. Important: This endpoint only supports customer contacts. Leads do not have a customer email preference surface in the public API. ### Path Parameters - id - The Featurebase contact ID (24-character ObjectId) ### Request Body - preferences - A partial map of preference keys to their desired stored status. Only the preferences included in the request are updated; any preferences omitted are left unchanged. At least one preference must be provided. ### Supported Preference Keys - all - Master delivery gate. When unsubscribed, the contact will not receive any emails regardless of the per-category values. Per-category values are still persisted, so flipping all back to subscribed restores the contact's previous granular preferences. - postUpdates - Status changes and updates on posts the contact interacts with. - postComments - New comments on posts the contact follows. - commentReplies - Replies to the contact's own comments. - changelog - New changelog releases. ### Per-key Values - subscribed - The contact will receive this email category (subject to the all gate). - unsubscribed - The contact will not receive this email category. ### Combining all with per-category keys You can send all together with any per-category keys in the same request. The full map is applied atomically as the contact's new stored state — there is no implicit reset of the other keys. This makes the endpoint safe for preference-center UIs that POST the entire form state on submit. The computed per-category result (after applying the all gate) is surfaced as effectiveStatus in the response, while status reflects the value actually stored for that key. ### Example Request (partial update) json { "preferences": { "postUpdates": "unsubscribed", "changelog": "subscribed" } } ### Example Request (full preference-center submit) json { "preferences": { "all": "subscribed", "postUpdates": "subscribed", "postComments": "unsubscribed", "commentReplies": "unsubscribed", "changelog": "unsubscribed" } } ### Example Response json { "object": "contact_email_preferences", "contactId": "676f0f6765bdaa7d7d760f88", "userId": "usr_12345", "email": "john@example.com", "preferences": { "all": { "status": "subscribed", "effectiveStatus": "subscribed" }, "postUpdates": { "status": "subscribed", "effectiveStatus": "subscribed" }, "postComments": { "status": "unsubscribed", "effectiveStatus": "unsubscribed" }, "commentReplies": { "status": "unsubscribed", "effectiveStatus": "unsubscribed" }, "changelog": { "status": "unsubscribed", "effectiveStatus": "unsubscribed" } } } Endpoint: PATCH /v2/contacts/{id}/email-preferences Version: 2026-01-01.nova Security: bearerAuth ## Header parameters: - `Featurebase-Version` (string) API version for this request. Defaults to your organization's configured API version if not specified. Example: "2026-01-01.nova" ## Path parameters: - `id` (string, required) Featurebase contact ID Example: "507f1f77bcf86cd799439011" ## Request fields (application/json): - `preferences` (object, required) - `preferences.all` (string) Master delivery gate. When unsubscribed, the contact receives no emails regardless of the per-category values. Per-category values are preserved. Enum: "subscribed", "unsubscribed" - `preferences.postUpdates` (string) Stored status for post status changes and updates on posts the contact follows. Enum: "subscribed", "unsubscribed" - `preferences.postComments` (string) Stored status for new comments on posts the contact follows. Enum: "subscribed", "unsubscribed" - `preferences.commentReplies` (string) Stored status for replies to the contact’s own comments. Enum: "subscribed", "unsubscribed" - `preferences.changelog` (string) Stored status for new changelog release notifications. Enum: "subscribed", "unsubscribed" ## Response 200 fields (application/json): - `object` (string, required) Object type identifier Enum: "contact_email_preferences" - `contactId` (string, required) Featurebase contact ID Example: "676f0f6765bdaa7d7d760f88" - `userId` (string,null) External user ID from your system, if available Example: "usr_12345" - `email` (string,null) Contact email address, if available Example: "john@example.com" - `preferences` (object, required) Email preference state for this contact, including both stored status and final effective status. - `preferences.all` (object, required) Global email preference state for all email notifications. - `preferences.all.status` (string, required) Stored preference status for this category Enum: "subscribed", "unsubscribed" - `preferences.all.effectiveStatus` (string, required) Final effective status after applying global preference overrides Enum: "subscribed", "unsubscribed" - `preferences.postUpdates` (object, required) Global email preference state for all email notifications. Example: {"status":"subscribed","effectiveStatus":"unsubscribed"} - `preferences.postComments` (object, required) Global email preference state for all email notifications. Example: {"status":"subscribed","effectiveStatus":"subscribed"} - `preferences.commentReplies` (object, required) Global email preference state for all email notifications. Example: {"status":"subscribed","effectiveStatus":"subscribed"} - `preferences.changelog` (object, required) Global email preference state for all email notifications. Example: {"status":"subscribed","effectiveStatus":"subscribed"} ## Response 400 fields (application/json): - `error` (object, required) - `error.type` (string, required) The type of error returned Enum: "invalid_request_error" - `error.code` (string, required) Machine-readable error code Enum: "invalid_id", "invalid_request" - `error.message` (string, required) Human-readable error message Example: "An error occurred" - `error.param` (string) The parameter that caused the error (if applicable) Example: "id" - `error.status` (number, required) HTTP status code Enum: 400 ## Response 403 fields (application/json): - `error` (object, required) - `error.type` (string, required) The type of error returned Enum: "authorization_error" - `error.code` (string, required) Machine-readable error code Enum: "forbidden" - `error.message` (string, required) Human-readable error message Example: "An error occurred" - `error.param` (string) The parameter that caused the error (if applicable) Example: "id" - `error.status` (number, required) HTTP status code Enum: 403 ## Response 404 fields (application/json): - `error` (object, required) - `error.type` (string, required) The type of error returned Enum: "invalid_request_error" - `error.code` (string, required) Machine-readable error code Enum: "contact_not_found" - `error.message` (string, required) Human-readable error message Example: "An error occurred" - `error.param` (string) The parameter that caused the error (if applicable) Example: "id" - `error.status` (number, required) HTTP status code Enum: 404