List the messages of all of a person's conversations
crm.persons.messages.list
ReadIdempotentSince 2026-11-01
Lists the messages of every inbox conversation linked to a person (WhatsApp on any line and Instagram, Messenger or TikTok direct messages), newest first, in one call instead of one crm.messages.list per conversation, paginated by cursor (limit up to 200). Each message comes as in crm.messages.list (conversation_id, direction, content (the text), media, template, delivery status, who sent it, external_id), with attachments as links signed for one hour (media_urls_expire_at) and without the raw platform payload. Filters: since and until (epoch ms, both exclusive), channel (only the person's conversations of that channel) and direction (inbound: what the contacts wrote; outbound: what the house sent), the last one applied to the page that was read, so a page can bring fewer than limit while has_more is true (follow next_cursor). It reads the person's 30 conversations with the most recent activity: with more, conversations_truncated is true and the older conversations are left out (read them with crm.conversations.list with person_id and crm.messages.list). The same conversations crm.conversations.list shows are included: conversations on a line that belongs to another part of the product never are, and a seller with restricted scope only gets the conversations they own or those on lines they work. Not found (person_not_found) if the person does not exist or the seller cannot see them. Requires view_inbox. With TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:read
Permission
View the module · CRM action: view_inbox
MCP tool
crm_persons_messages_listOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.messages.list".
Declared cost: up to 260 reads and 0 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
limitintegerqueryoptional
How many items this page brings at most (see the maximum and the default in the schema).
Default: 50
cursorstringqueryoptional
The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.
sinceintegerqueryoptional
Only messages created after this time (epoch ms, exclusive): to poll, the createdAt of the last message you handled.
untilintegerqueryoptional
Only messages created before this time (epoch ms, exclusive).
Only what the contacts wrote (inbound) or what the house sent (outbound); applied to the page that was read, so a page can bring fewer than limit while has_more is true.
Values: inbound, outbound
Response
dataarray<object>
has_moreboolean
next_cursorstring
conversations_truncatedboolean
Present (true) when the person has more than 30 conversations: only the messages of the 30 with the most recent activity were read.
Lists persons (contacts) most recently updated first, paginated by cursor; company_id keeps only the persons linked to that company. Each person carries their contactability: do_not_contact, unsubscribed_at, bounced_at, whatsapp_unreachable, and the name of their primary company as stored on their record (company_name). Archived persons are left out unless include_archived is true; merged-away duplicates never appear. A seller with restricted scope only gets their own, the free ones and those of their deals. Both filters apply to the page read, so a page can bring fewer than limit while has_more is true: follow next_cursor until has_more is false. Use crm.persons.lookup to find one by email or phone. With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_listOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.list".
Declared cost: up to 201 reads and 0 writes per call (they count against the daily quota).
Parameters
limitintegerqueryoptional
How many items this page brings at most (default 20, up to 200).
Default: 20
cursorstringqueryoptional
The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.
company_idstringqueryoptional
Only the persons linked to this company (as their primary company or another one).
include_archivedbooleanqueryoptional
Include archived records (left out by default; merged-away duplicates never come).
Returns a person with their emails, phones, companies (company_name: their primary company's name as stored on their record), owner, labels and custom fields, and whether they can be contacted: do_not_contact, unsubscribed_at (emails), bounced_at and whatsapp_unreachable (their number has no WhatsApp). Not found if the id does not exist or the seller's scope hides them. With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_getOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.get".
Declared cost: up to 2 reads and 0 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
Response
idstring
org_idstring
first_namestring
full_namestring
created_atnumber
updated_atnumber
last_namestring | null
emailstring | null
The primary email (one of emails).
emailsarray<string>
phonestring | null
The primary phone, E.164 when it could be read (one of phones).
phonesarray<string>
job_titlestring | null
countrystring | null
ISO-2 country; local phone numbers are read with it.
websitestring | null
linked_in_urlstring | null
avatar_urlstring | null
company_idsarray<string>
Every company of the person (primary_company_id is one of them).
primary_company_idstring | null
company_namestring | null
Name of the person's primary company as stored on their record: copied when a company becomes their primary one (or written directly); renaming the company later does not update it (read the company for its current name).
owner_idstring | null
The owner: a member's user id (members.members.list), or an AI position's ai-… id.
owner_namestring | null
The name of the owner, resolved when the record is read.
label_idsarray<string>
custom_fieldsobject
do_not_contactboolean
unsubscribed_atnumber | null
When the person unsubscribed from emails (epoch ms); sequences and campaigns leave them out.
bounced_atnumber | null
When an email to the person bounced (epoch ms).
whatsapp_unreachableboolean | null
true when WhatsApp reported that their number has no WhatsApp or cannot receive messages (learned from a failed send).
whatsapp_unreachable_atnumber | null
When whatsapp_unreachable was set, epoch ms.
source_channelstring | null
Where the person came from: meta, google, whatsapp, web, manual, csv…
origin_channelsarray<string> | null
The lead channels (as in source_channel) of platforms with their own terms whose data the person carries: added when a form or a message from one of them creates or completes the person, never removed.
attributionobject | null
first_seen_atnumber | null
When the person first entered the CRM, epoch ms.
last_seen_atnumber | null
When the person last came in through an intake (a form, a message, a booking), epoch ms.
last_activity_atnumber | null
Last activity linked to the person, epoch ms.
chat_data_suggestionsarray<object> | null
Phones, emails and sites found in the person's chats and not decided yet: accept or dismiss each with crm.persons.chat_data.update.
is_archivedboolean
archived_atnumber | null
merged_into_idstring | null
Set on a duplicate absorbed by a merge: the person that kept it (lists never return these).
created_by_idstring | null
Who created the person: a member's user id (members.members.list), or an AI position's ai-… id.
created_by_namestring | null
The name of who created the person, resolved when the record is read.
Returns the person, their primary company and their deals in one call: what you need to talk about them. deals are the deals where the person is linked or is the main contact (up to 50 of each), open, won and lost, not archived, open first and then the most recently moved. Not found if the person does not exist or is out of scope. With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_contextOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.context".
Declared cost: up to 23 reads and 0 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
Finds the person that has the given email (any of their emails) or phone (normalized to E.164): person is the first one that is not a merged-away duplicate, by email first and then by phone, or null when there is no match or the seller's scope hides them. matches lists every record that has that email or that phone, not just one: the merged-away duplicates too (merged: true and merged_into_id, the record that remains), archived ones, and for the phone also the records that store it in another of its forms (the Argentine 9, the Mexican 1), each with matched_by (email, phone); up to 25 per value, only those the caller can see. phones (up to 30; by REST ?phones=a,b) looks up many numbers in one call: by_phone has one entry per number, in the order asked, with the number as asked, its E.164 form (normalized: null when it cannot be read as a phone with a country code, and then it is not looked up), person_id (the same rule as person) and its matches; person and matches stay those of email and phone. Use it before creating a person to avoid duplicates, and to find sibling records of a number before writing to it. With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_lookupOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.lookup".
Declared cost: up to 802 reads and 0 writes per call (they count against the daily quota).
Parameters
emailstring (email)queryoptional
An email to look for (any of a person's emails, case does not matter).
phonestringqueryoptional
A phone to look for, with its country code or local with country.
phonesarray<string>queryoptional
Up to 30 phones looked up in one call (by REST: ?phones=a,b or the key repeated). Each one gets its own entry in byPhone, in the order asked; person and matches stay those of email and phone.
countrystringqueryoptional
ISO-2 country (AR, MX…) to read phones written without their country code (011 4000-0002 with AR is +541140000002). Without it, only phones with their country code (+54 11 4000-0002, 0054…) are looked up.
Find prior deals and prospects that look like this contact
crm.persons.similar
ReadIdempotentSince 2026-11-01
Given a person and/or company (or a prospect, looked up by its person and company), returns the prior deals and prospects that look related: same person, a duplicate person with the same email or phone, the same company or another company on the same web domain. strong matches first. Use it before creating a deal or prospect to avoid working a contact twice.
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_similarOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.similar".
Declared cost: up to 40 reads and 0 writes per call (they count against the daily quota).
Parameters
person_idstringqueryoptional
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
company_idstringqueryoptional
The company, by id (crm.companies.list or crm.search).
Creates a person (contact) with name, emails, phones, job title, links, country, an optional company (becomes their primary company), owner, labels and custom fields; created: true. If a person already has the primary email (any of their emails), nothing is written: their id comes back with created: false and matched_by: email (a merged-away duplicate never comes back, the record that remains does; archived persons count). A seller with restricted scope who cannot see that person gets 409 person_exists_not_visible instead: their id never comes back and nothing is written. It does not deduplicate by phone: use crm.persons.lookup first. company_name is only the text shown on the record: it does not link a company (use company_id, from crm.companies.list or crm.companies.create, for that). Labels must be person labels (crm.labels.list with entity person: label_not_found otherwise), custom fields must exist for persons with a value of their type (custom_field_unknown, custom_field_invalid), the owner must be a member or an AI position (owner_not_member), and outside the screen every phone must be readable (with its country code or with country: invalid_phone otherwise). A new person fires the person_created sequence trigger, unless skip_automations is true (the audit log says what was skipped); the crm.person.created webhook fires either way. Requires create_person.
Scope
crm:write
Permission
Edit in the module · CRM action: create_person
MCP tool
crm_persons_createOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.create".
Declared cost: up to 7 reads and 1 writes per call (they count against the daily quota).
Parameters
first_namestringbodyrequired
First name, as written.
last_namestringbodyoptional
Last name.
emailstring (email)bodyoptional
The primary email (it is also added to emails).
emailsarray<string>bodyoptional
Every email of the person (the primary one included).
phonestringbodyoptional
The primary phone, with its country code (+54 11 4000-0002) or local with country; it is also added to phones.
phonesarray<string>bodyoptional
Every phone of the person, each with its country code or local with country (outside the screen, one that cannot be read is invalid_phone).
job_titlestringbodyoptional
Their job title.
linked_in_urlstring (uri)bodyoptional
Their LinkedIn profile URL.
websitestring (uri)bodyoptional
Their personal website URL.
countrystringbodyoptional
ISO-2 country (AR, MX…): local phone numbers are read with it.
company_idstringbodyoptional
The company (crm.companies.list or crm.companies.create): it becomes their primary company.
company_namestringbodyoptional
Only the text shown as their company: it does not link a company (use company_id).
owner_idstringbodyoptional
The owner: a member's user id or an AI position's ai-… id.
label_idsarray<string>bodyoptional
Person labels (crm.labels.list with entity person).
custom_fieldsobjectbodyoptional
Custom fields: slug (crm.custom_fields.list with entity person) → value of the field's type.
skip_automationsbooleanbodyoptional
true: the new person does not enter the sequences that start when a contact is created (the person_created trigger). Recorded in the audit log (skip_automations, automationsSkipped). The crm.person.created webhook still fires, and deduplication by email works as always.
Response
person_idstring
createdboolean
true when the person is new; false when one with that email already existed (person_id is hers and nothing was written).
matched_byenum
Why an existing person came back (only with created: false).
Sets do_not_contact on a person: send value or do_not_contact (the same flag, by the name it has on the person) with true to mark them, or with false to clear it and let them be contacted again. MB Suite stops starting the contact with a person marked «Do not contact»: sequences leave them out, the AI Setter does not write first (it still answers what they write), the voice agent does not call them, and a manual email, a WhatsApp template or an SMS to them is refused (409 do_not_contact) unless a person of the team confirms it on a closed basis (about their account, a charge or support, or because they asked us to write); a WhatsApp marketing template never goes to them. A reply to what they wrote after being marked still goes out, and so does WhatsApp free text (Meta only delivers it within 24 hours of their message). reason (optional, up to 500 characters) says why and is kept in the audit log of the change (the record has no field for it). Idempotent: if nothing changes, nothing is logged (changed: false). Requires edit_person.
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_set_do_not_contactOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.set_do_not_contact".
Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
valuebooleanbodyoptional
true marks the person as do-not-contact; false clears it. Same as do_not_contact.
do_not_contactbooleanbodyoptional
The same flag with the name it has on the person (do_not_contact): send this or value.
reasonstringbodyoptional
Why (the lead asked not to be called, a wrong number…). It is kept in the audit log of the change; the person's record has no field for it.
Response
changedboolean
false when the person already was that way: nothing was written.
curl-X POST "https://api.mb-suite.com/v1/crm/persons/{person_id}/do-not-contact" \
-H"Authorization: Bearer $MB_API_KEY"
Try it with your test API key
With a test API key the request always goes to your practice organization: example data you can reset.
curl-X POST "https://api.mb-suite.com/v1/crm/persons/{person_id}/do-not-contact" \
-H"Authorization: Bearer $MB_TEST_KEY"
PATCH/v1/crm/persons/{person_id}
Update a person
crm.persons.update
WriteSince 2026-11-01
Updates one or more fields of a person: names, emails (the full list replaces; a single email is added), phones, job title, links, country, companies and primary company, owner, labels, custom fields, do-not-contact. A renamed person propagates their name to their deals and activities. Labels, custom fields, owner and phones are checked as in crm.persons.create. Returns the person as saved. Requires edit_person (a seller edits their own, the free ones and those of their deals). With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_updateOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.update".
Deletes a person. They go to the 30-day trash (restoring re-links them to the deals and lists they were removed from); their deals lose the link (the next person becomes primary) and their activities and conversations are kept. Prefer crm.persons.archive to just hide them. Requires delete_person.
With an API key, this DELETE runs directly: the record stays 30 days in the trash and the response carries its trash_item_id. With an OAuth token, and through the MCP, it needs dry_run → confirm_token.
Scope
crm:writeand “Allow deletions” (crm:delete in OAuth)
Permission
Edit in the module · CRM action: delete_person
MCP tool
crm_persons_deleteOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.delete".
Archives (archived: true) or restores (false) a person; archived persons leave the lists but keep everything. Idempotent: changed is false when they already were that way. Returns the person as they are now. Requires edit_person. With Google Ads, LinkedIn or TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted, and their records or fields are left out of the response (the permissions guide lists what each platform allows).
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_archiveOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.archive".
Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
Adds a company to the person's companies; if they had none it becomes their primary company. Already linked: nothing is written (changed: false). Requires edit_person.
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_companies_addOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.companies.add".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
company_idstringbodyrequired
The company, by id (crm.companies.list or crm.search).
Response
oktrue
changedboolean
false when the link was already that way: nothing was written.
Removes a company from the person's companies; if it was their primary company, the next one takes over. Not linked: nothing is written (changed: false). Requires edit_person.
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_companies_removeOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.companies.remove".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
company_idstringbodyrequired
The company, by id (crm.companies.list or crm.search).
Response
oktrue
changedboolean
false when the link was already that way: nothing was written.
Makes a company the person's primary one (adding it to their companies if needed); their denormalized company name follows. Already the primary one: nothing is written (changed: false). Requires edit_person.
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_set_primary_companyOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.set_primary_company".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list, crm.persons.lookup or crm.search).
company_idstringbodyrequired
The company, by id (crm.companies.list or crm.search).
Response
oktrue
changedboolean
false when the link was already that way: nothing was written.
Resolves one suggestion that the person wrote in a chat (a phone, an email, a website): accept writes it to their record (a phone may need a country), dismiss hides it. The key and message_id come from the person's chat_data_suggestions. Requires edit_person.
Scope
crm:write
Permission
Edit in the module
MCP tool
crm_persons_chat_data_updateOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.chat_data.update".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person, by id (crm.persons.list).
keystringbodyrequired
The suggestion's key, from the person's chatDataSuggestions.
message_idstringbodyrequired
The message the suggestion was found in, from chatDataSuggestions.
decisionenumbodyrequired
accept writes it to the person; dismiss hides it.
Values: accept, dismiss
countrystringbodyoptional
For a phone without its country code: the ISO-2 country to read it with.
Deletes up to 500 persons; each goes to the 30-day trash (restorable one by one) and leaves their deals and lists. deleted counts the persons that existed; the other ids come back in not_found. Requires bulk_delete_persons (Manager-tier). Outside the screen it requires a dry run and a confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
crm:writeand “Allow deletions” (crm:delete in OAuth)
Permission
Edit in the module · CRM action: bulk_delete_persons
MCP tool
crm_persons_bulk_deleteOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.bulk.delete".
Adds and/or removes labels (ids from crm.labels.list with entity person) on up to 500 persons; fires the label_added sequence trigger for the labels that are really new. A label that is not a person label of the organization is label_not_found (with details.unknown_ids). Persons that already have exactly those labels are left as they are (unchanged) and ids that do not exist are skipped (not_found). The dry run reads the same persons and names those that would change. Requires bulk_update_persons. Outside the screen it requires a dry run and a confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
crm:write
Permission
Edit in the module · CRM action: bulk_update_persons
MCP tool
crm_persons_bulk_update_labelsOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.bulk.update_labels".
Declared cost: up to 540 reads and 500 writes per call (they count against the daily quota).
Parameters
person_idsarray<string>bodyrequired
The persons (up to 500), by id (crm.persons.list).
to_addarray<string>bodyoptional
Label ids to add (crm.labels.list with entity person), up to 20; send to_add, to_remove or both.
to_removearray<string>bodyoptional
Label ids to remove (crm.labels.list with entity person), up to 20; send to_add, to_remove or both.
Response
updatednumber
How many persons changed.
unchangednumber
How many persons already were that way: not written.
not_foundarray<string>
The ids that do not exist in the organization (or are merged-away duplicates): skipped.
Sets (or clears with null) the owner of up to 500 persons: a member's user id (members.members.list) or an AI position's ai-… id (owner_not_member otherwise). Persons that already have that owner are left as they are (unchanged) and ids that do not exist are skipped (not_found). The dry run reads the same persons and names those that would change. Requires bulk_update_persons. Outside the screen it requires a dry run and a confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
crm:write
Permission
Edit in the module · CRM action: bulk_update_persons
MCP tool
crm_persons_bulk_update_ownerOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.bulk.update_owner".
Declared cost: up to 501 reads and 500 writes per call (they count against the daily quota).
Parameters
person_idsarray<string>bodyrequired
The persons (up to 500), by id (crm.persons.list).
owner_idstring | nullbodyrequired
The new owner (a member's user id or an AI position's ai-… id); null leaves them without one.
Response
updatednumber
How many persons changed.
unchangednumber
How many persons already were that way: not written.
not_foundarray<string>
The ids that do not exist in the organization (or are merged-away duplicates): skipped.
Makes a company the primary one of up to 500 persons (adding it to their companies), or clears the primary company with null without removing any. Persons that already have that primary company are left as they are (unchanged) and ids that do not exist are skipped (not_found). The dry run reads the same persons and names those that would change. Requires bulk_update_persons. Outside the screen it requires a dry run and a confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
crm:write
Permission
Edit in the module · CRM action: bulk_update_persons
MCP tool
crm_persons_bulk_update_companyOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.bulk.update_company".
Declared cost: up to 501 reads and 500 writes per call (they count against the daily quota).
Parameters
person_idsarray<string>bodyrequired
The persons (up to 500), by id (crm.persons.list).
company_idstring | nullbodyrequired
The company that becomes their primary one (crm.companies.list); null clears the primary company without removing any.
company_namestring | nullbodyoptional
The company's name as shown on their records (by default, the company's).
Response
updatednumber
How many persons changed.
unchangednumber
How many persons already were that way: not written.
not_foundarray<string>
The ids that do not exist in the organization (or are merged-away duplicates): skipped.
Sets do_not_contact on up to 500 persons (send value or do_not_contact, true or false), as crm.persons.set_do_not_contact does on one. MB Suite stops starting the contact with a person marked «Do not contact»: sequences leave them out, the AI Setter does not write first (it still answers what they write), the voice agent does not call them, and a manual email, a WhatsApp template or an SMS to them is refused (409 do_not_contact) unless a person of the team confirms it on a closed basis (about their account, a charge or support, or because they asked us to write); a WhatsApp marketing template never goes to them. A reply to what they wrote after being marked still goes out, and so does WhatsApp free text (Meta only delivers it within 24 hours of their message). Persons that already are that way are left as they are (unchanged) and ids that do not exist are skipped (not_found). The dry run reads the same persons and names those that would change. Requires bulk_update_persons. Outside the screen it requires a dry run and a confirm_token.
Needs confirmation: first dry_run: true (preview and confirm_token, valid 10 minutes and for one run), then the same body with confirm_token. In a few operations only with certain data: the description says when. Why and how: Dry run and confirm_token.
Scope
crm:write
Permission
Edit in the module · CRM action: bulk_update_persons
MCP tool
crm_persons_bulk_set_do_not_contactOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.bulk.set_do_not_contact".
Declared cost: up to 500 reads and 500 writes per call (they count against the daily quota).
Parameters
person_idsarray<string>bodyrequired
The persons (up to 500), by id (crm.persons.list).
valuebooleanbodyoptional
true marks the persons as do-not-contact; false clears it. Same as do_not_contact.
do_not_contactbooleanbodyoptional
The same flag with the name it has on the person (do_not_contact): send this or value.
Response
updatednumber
How many persons changed.
unchangednumber
How many persons already were that way: not written.
not_foundarray<string>
The ids that do not exist in the organization (or are merged-away duplicates): skipped.
Lists the sequence enrollments of one person across every sequence, newest first, paginated by cursor (limit up to 200), with the same fields as crm.sequences.enrollments.list (sequence_id, status, current step, pause and exit reasons, counters, last_history). Use it to know which sequences are writing to a contact before enrolling them in another one. Not found (person_not_found) if the person does not exist or a seller with restricted scope cannot see them. Requires view access to the CRM.
Scope
crm:read
Permission
View the module
MCP tool
crm_persons_enrollments_listOn the full surface; on the compact one, mb_execute_operation with id: "crm.persons.enrollments.list".
Declared cost: up to 203 reads and 0 writes per call (they count against the daily quota).
Parameters
person_idstringpathrequired
The person: an id from crm.persons.list.
limitintegerqueryoptional
How many items this page brings at most (see the maximum and the default in the schema).
Default: 50
cursorstringqueryoptional
The next_cursor of the previous page, exactly as it came (only for the same list and filters); without it, the first page.