# Contacts Contacts are the customers and leads in your Featurebase organization. Use this endpoint to list and retrieve contact information. ## List contacts - [GET /v2/contacts](https://docs.featurebase.app/rest-api/contacts/listcontacts.md): Returns a list of contacts (customers and leads) in your organization using cursor-based pagination. ### Query Parameters - limit - Number of contacts to return (1-100, default 10) - cursor - Cursor from previous response for pagination - contactType - Filter by contact type: "customer" (default), "lead", or "all" ### Response Format Returns a list object with: - object - Always "list" - data - Array of contact objects - nextCursor - Cursor for the next page, or null if no more results ### Contact Object Each contact includes: - id - Unique contact identifier - userId - External user ID from SSO (if set) - email - Contact email address - name - Contact display name - profilePicture - Profile picture URL - type - Contact type ("customer" or "lead") - companies - Array of companies the contact belongs to - customFields - Custom field values - postsCreated - Number of posts created - commentsCreated - Number of comments created - lastActivity - Last activity timestamp ### Example json { "object": "list", "data": [ { "object": "contact", "id": "676f0f6765bdaa7d7d760f88", "email": "john@example.com", "name": "John Doe", "type": "customer", ... } ], "nextCursor": "eyJpZCI6IjUwN2YxZjc3YmNmODZjZDc5OTQzOTAxMSJ9" } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Create or update a contact - [POST /v2/contacts](https://docs.featurebase.app/rest-api/contacts/upsertcontact.md): Creates a new contact or updates an existing one. If a contact with the given email or userId already exists, it will be updated. Otherwise, a new contact will be created. At least one of email or userId must be provided for identification. ### Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | email | string | One of email/userId | Contact email address | | userId | string | One of email/userId | External user ID from your system | | name | string | No | Contact display name | | profilePicture | string | No | Profile picture URL | | companies | array | No | Companies the contact belongs to | | customFields | object | No | Custom field values | | subscribedToChangelog | boolean | No | Whether subscribed to changelog | | locale | string | No | Contact locale/language | | phone | string | No | Contact phone number | | roles | array | No | Role IDs to assign | | userHash | string | No | HMAC hash for identity verification | | createdAt | string | No | When the contact was created (ISO 8601) | ### Company Object Each company in the companies array can have: - id (required) - External company ID from your system - name (required) - Company name - monthlySpend - Monthly spend/revenue - customFields - Custom field values - industry - Industry - website - Company website URL - plan - Current plan/subscription - companySize - Number of employees - createdAt - When the company was created ### Response Returns the created or updated contact object. - 201 Created - A new contact was created - 200 OK - An existing contact was updated ### Example Request json { "email": "john@example.com", "name": "John Doe", "userId": "usr_12345", "companies": [ { "id": "company_123", "name": "Acme Inc", "monthlySpend": 500, "plan": "enterprise" } ], "customFields": { "plan": "pro", "signupSource": "website" }, "subscribedToChangelog": true } ### Example Response json { "object": "contact", "id": "676f0f6765bdaa7d7d760f88", "email": "john@example.com", "name": "John Doe", "userId": "usr_12345", "type": "customer", "companies": [...], "customFields": {...}, ... } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Get contact by ID - [GET /v2/contacts/{id}](https://docs.featurebase.app/rest-api/contacts/getcontactbyid.md): Retrieves a single contact by their Featurebase ID. Returns both customers and leads. ### Path Parameters - id - The Featurebase contact ID (24-character ObjectId) ### Response Format Returns a single contact object with: - object - Always "contact" - id - Unique contact identifier - userId - External user ID from SSO (if set) - email - Contact email address - name - Contact display name - profilePicture - Profile picture URL - type - Contact type ("customer" or "lead") - companies - Array of companies the contact belongs to - customFields - Custom field values - postsCreated - Number of posts created - commentsCreated - Number of comments created - lastActivity - Last activity timestamp ### Example json { "object": "contact", "id": "676f0f6765bdaa7d7d760f88", "email": "john@example.com", "name": "John Doe", "type": "customer", ... } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Delete contact by ID - [DELETE /v2/contacts/{id}](https://docs.featurebase.app/rest-api/contacts/deletecontactbyid.md): Permanently deletes a contact by their Featurebase ID. Supports deleting both customers and leads. ### Path Parameters - id - The Featurebase contact ID (24-character ObjectId) ### Deletion Behavior When a contact is deleted: - The contact record is permanently removed - Associated data cleanup is triggered asynchronously - Comments and posts created by the contact are handled according to retention policies ### Response Returns a deletion confirmation object: - id - The ID of the deleted contact - object - Always "contact" - deleted - Always true ### Example Response json { "id": "676f0f6765bdaa7d7d760f88", "object": "contact", "deleted": true } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Get contact by external user ID - [GET /v2/contacts/by-user-id/{userId}](https://docs.featurebase.app/rest-api/contacts/getcontactbyuserid.md): Retrieves a single contact by their external user ID (from your system via SSO). Important: This endpoint only returns customers (type: "customer"). Leads are not returned. ### Path Parameters - userId - The external user ID from your system (matched via SSO integration) ### Response Format Returns a single contact object with: - object - Always "contact" - id - Unique contact identifier - userId - External user ID from SSO - email - Contact email address - name - Contact display name - profilePicture - Profile picture URL - type - Always "customer" for this endpoint - companies - Array of companies the contact belongs to - customFields - Custom field values - postsCreated - Number of posts created - commentsCreated - Number of comments created - lastActivity - Last activity timestamp ### Example json { "object": "contact", "id": "676f0f6765bdaa7d7d760f88", "userId": "usr_12345", "email": "john@example.com", "name": "John Doe", "type": "customer", ... } ### Use Case This endpoint is useful when you need to look up a contact using your own system's user identifier, such as when displaying Featurebase data alongside your user's information in your own application. ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Delete contact by external user ID - [DELETE /v2/contacts/by-user-id/{userId}](https://docs.featurebase.app/rest-api/contacts/deletecontactbyuserid.md): Permanently deletes a contact by their external user ID. Important: This endpoint only deletes customers (type: "customer"). Leads cannot be deleted using this endpoint. ### Path Parameters - userId - The external user ID from your system ### Deletion Behavior When a contact is deleted: - The contact record is permanently removed - Associated data cleanup is triggered asynchronously - Comments and posts created by the contact are handled according to retention policies ### Response Returns a deletion confirmation object: - id - The ID of the deleted contact - object - Always "contact" - deleted - Always true ### Example Response json { "id": "676f0f6765bdaa7d7d760f88", "object": "contact", "deleted": true } ### Use Case Use this endpoint when you need to delete a contact using your own system's user identifier, such as when a user deletes their account in your application. ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Get contact email preferences by ID - [GET /v2/contacts/{id}/email-preferences](https://docs.featurebase.app/rest-api/contacts/getcontactemailpreferencesbyid.md): Retrieves the email preference state 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) ### Response Format Returns a contact email preferences object with: - object - Always "contact_email_preferences" - contactId - Featurebase contact ID - userId - External user ID, if available - email - Contact email address, if available - preferences - Current email preference state ### Preference Semantics Each preference includes: - status - The stored preference state for that category - effectiveStatus - The final state after applying the global all preference override ### Example Response json { "object": "contact_email_preferences", "contactId": "676f0f6765bdaa7d7d760f88", "userId": "usr_12345", "email": "john@example.com", "preferences": { "all": { "status": "unsubscribed", "effectiveStatus": "unsubscribed" }, "postUpdates": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "postComments": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "commentReplies": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "changelog": { "status": "subscribed", "effectiveStatus": "unsubscribed" } } } ## Update contact email preferences by ID - [PATCH /v2/contacts/{id}/email-preferences](https://docs.featurebase.app/rest-api/contacts/updatecontactemailpreferencesbyid.md): 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" } } } ## Get contact email preferences by external user ID - [GET /v2/contacts/by-user-id/{userId}/email-preferences](https://docs.featurebase.app/rest-api/contacts/getcontactemailpreferencesbyuserid.md): Retrieves the email preference state for a customer contact by their external user ID. This endpoint only supports customer contacts and mirrors the existing by-user-id lookup pattern used across the contact API. ### Path Parameters - userId - The external user ID from your system ### Example Response json { "object": "contact_email_preferences", "contactId": "676f0f6765bdaa7d7d760f88", "userId": "usr_12345", "email": "john@example.com", "preferences": { "all": { "status": "unsubscribed", "effectiveStatus": "unsubscribed" }, "postUpdates": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "postComments": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "commentReplies": { "status": "subscribed", "effectiveStatus": "unsubscribed" }, "changelog": { "status": "subscribed", "effectiveStatus": "unsubscribed" } } } ## Update contact email preferences by external user ID - [PATCH /v2/contacts/by-user-id/{userId}/email-preferences](https://docs.featurebase.app/rest-api/contacts/updatecontactemailpreferencesbyuserid.md): Updates one or more email preferences for a customer contact by their external user ID. This endpoint only supports customer contacts and mirrors the existing by-user-id lookup pattern used across the contact API. ### Path Parameters - userId - The external user ID from your system ### 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. See PATCH /v2/contacts/{id}/email-preferences for the full list of supported preference keys and per-key values, the all delivery-gate semantics, and details on combining all with per-category keys in a single request. ### 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" } } } ## Block a contact - [POST /v2/contacts/{id}/block](https://docs.featurebase.app/rest-api/contacts/blockcontactbyid.md): Blocks a contact by their Featurebase ID from the messenger/inbox. ### Path Parameters - id - The Featurebase internal ID of the contact (MongoDB ObjectId) ### Supported Contact Types This endpoint blocks both: - Customers - Users with registered accounts - Leads - Anonymous or unregistered visitors ### Blocking Behavior When a contact is blocked: - The contact cannot send new messages via messenger - Existing conversations are not deleted but no new messages can be added by the blocked user - The block can be removed by unblocking the contact ### Response Returns a block confirmation object: - id - The ID of the blocked contact - object - Always "contact" - blocked - Always true ### Example Response json { "id": "507f1f77bcf86cd799439011", "object": "contact", "blocked": true } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer. ## Unblock a contact - [POST /v2/contacts/{id}/unblock](https://docs.featurebase.app/rest-api/contacts/unblockcontactbyid.md): Unblocks a contact by their Featurebase ID from the messenger/inbox. ### Path Parameters - id - The Featurebase internal ID of the contact (MongoDB ObjectId) ### Supported Contact Types This endpoint unblocks both: - Customers - Users with registered accounts - Leads - Anonymous or unregistered visitors ### Unblocking Behavior When a contact is unblocked: - The contact can resume sending messages via messenger - Previously blocked conversations remain intact - The contact regains full messenger functionality ### Response Returns an unblock confirmation object: - id - The ID of the unblocked contact - object - Always "contact" - unblocked - Always true ### Example Response json { "id": "507f1f77bcf86cd799439011", "object": "contact", "unblocked": true } ### Version Availability This endpoint is only available in API version 2026-01-01.nova and newer.