First step to send a file by WhatsApp through the API (there is no multipart upload): for an existing WhatsApp conversation of a CRM line, returns upload_url to PUT an image, video, audio or document (PDF, Word, plain text, Markdown) of up to 100 MB, its storage_path, the headers to send, expires_at (10 minutes to start the upload) and media_type. PUT the raw bytes to upload_url from a server with exactly those headers and exactly size bytes (the URL is bound to that size and content type), then call crm.whatsapp.send_media on the same conversation with that storage_path and media_type. Nothing is sent by this call. An image or a video can also come from the media library (its storage_path works in send_media). The size counts toward the organization's storage quota when the URL is issued. WhatsApp's own limits apply when sending (images 5 MB, video and audio 16 MB). Each call issues a new URL (not idempotent). Errors: conversation_not_found (no WhatsApp conversation of a CRM line with that id), invalid_input (also a conversation_id that is a reserved storage folder name: thumbnails, booking_avatar), filename_invalid, limit_reached (details.resource storage: the storage is full), crm_action_denied (send_whatsapp; a seller with a restricted scope only on conversations they own or lines they work). Needs full access to the CRM.
Instruções para agentes
This only uploads the file: nothing reaches the contact until crm.whatsapp.send_media runs with its storage_path.
Escopo
crm:write
Permissão
Editar no módulo
Tool do MCP
crm_whatsapp_uploads_createNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.uploads.create".
Custo declarado: até 152 leituras e 1 escritas por chamada (contam na cota diária).
Parâmetros
conversation_idstringrotaobrigatório
The WhatsApp conversation of a CRM line the attachment goes to (crm.conversations.list).
file_namestringcorpoobrigatório
The file's name (it goes, cleaned, into the storage key).
content_typeenumcorpoobrigatório
The file's type: the PUT must send exactly this Content-Type.
What went out by WhatsApp in a time window, line by line
crm.whatsapp.sent_by_line
LeituraIdempotenteDesde 2026-11-01
For each WhatsApp line of the CRM (its phone_number_id, display_phone and name), between since and until (epoch ms; until is exclusive and defaults to now; at most 31 days): recipients (distinct numbers that got an outbound message that did not fail), messages (outbound messages), failed, and failed_recipients (distinct numbers where every outbound message failed: recipients + failed_recipients is every number something was attempted to), whoever sent them: people, AI agents, sequences, booking notices or the phone app. With ai_agent_user_id (an AI agent: a key marked as an AI agent's or an AI Team position) or sent_by_id (a person sending from MB Suite), at most one, the same read also gives that author's share per line (author_recipients, author_messages) and author, its WhatsApp total across every CRM line and the conversations without a line (recipients, messages, failed), so the per-line cap and the agent's WhatsApp load come from one call; the house's daily cap per agent across every channel stays in crm.messages.count. A message counts on the line it went out by, which MB Suite records on every outbound WhatsApp message, otherwise on its conversation's line, so a number reached through a conversation without a line (imported from another system) and through the line's own conversation counts once. without_line keeps the messages with neither, sent through those conversations before every sender recorded its line, with their recipients by the phone's country (ISO code); a number can appear there and on a line. Lines of another module are left out, as everywhere in the CRM. It reads every outbound WhatsApp message of the window and its conversation, up to 2,000 messages: truncated: true means there were more and the numbers fall short (treat them as over a cap). Meant for per-line daily caps (for example 200 numbers per line per day). Requires view_all_performance.
Escopo
crm:read
Permissão
Ver o módulo · Ação do CRM: view_all_performance
Tool do MCP
crm_whatsapp_sent_by_lineNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.sent_by_line".
Custo declarado: até 4121 leituras e 0 escritas por chamada (contam na cota diária).
Parâmetros
sinceintegerqueryobrigatório
From, epoch ms (included).
untilintegerqueryopcional
Until, epoch ms (excluded; at most 31 days after since); without it, now.
ai_agent_user_idstringqueryopcional
Also count what this AI agent sent (the user of a key marked as an AI agent's, or an AI Team position's ai-… user): authorRecipients and authorMessages per line and the author total. At most one of ai_agent_user_id and sent_by_id.
sent_by_idstringqueryopcional
Also count what this person sent from MB Suite (the screen, MIA or a key without the AI-agent mark), like ai_agent_user_id.
Resposta
sincenumber
untilnumber
linesarray<object>
without_lineobject
Outbound messages with no line of their own whose conversation has none either: those sent by conversations imported from another system before MB Suite recorded on every message the line it went out by (since then each one counts on its line), and in the practice organization, which has no lines, the simulated ones. countries: their recipients by the phone's country (ISO code). A number here can also be on a line.
scannednumber
truncatedboolean
authorobject
Only with aiAgentUserId or sentById: that author's WhatsApp outbound messages in the window across every CRM line and the conversations without a line: distinct numbers reached (a number reached on two lines counts once), messages and failed. WhatsApp only: for the house's daily cap per agent across every channel use crm.messages.count.
Sends a free-text WhatsApp message in an existing conversation and records it (a closed or archived conversation goes back to the open inbox). It goes out from the conversation's own WhatsApp line: from_phone_number_id can only name that line (another one is 409 conversation_line_mismatch with details.conversation_line, because Meta counts the 24-hour window per number; to write to the contact from another line use crm.conversations.start or crm.whatsapp.send_template without conversation_id). A conversation without a line (imported from another system; the contact's replies never reach it) goes out from from_phone_number_id and takes that line from then on, so the replies land in it: 409 conversation_exists_on_line with details.conversation_id when that number already has its conversation on that line (write there instead), and when to is another number the conversation does not take the line. Without from_phone_number_id such a conversation goes out from the organization's first active WhatsApp line (for a seller with restricted scope, the first one they work) and keeps having no line. A line of another part of the product is 400 line_module_mismatch, and one not connected to the organization 404 external_account_not_linked. to defaults to the conversation's contact. WhatsApp only accepts free text within 24 hours of the contact's last message: check reply_window with crm.conversations.get and use crm.whatsapp.send_template when it is closed. To a person marked «Do not contact» or unsubscribed it still goes out (free text only reaches a contact who wrote in the last 24 hours, so it is a reply), and the response carries do_not_contact. If Meta rejects it, the failed message stays in the conversation and the error is external_rejected with Meta's code in details.provider_code (also in details.error_code); external_rate_limited when Meta is throttling the number, and external_outcome_unknown when Meta failed without a clear answer (the message may have gone out: check the conversation before sending it again). Requires send_whatsapp; a seller with restricted scope only writes in conversations they own or on lines they work, and in a conversation without a line they must also work the line it goes out from (crm_action_denied, send_whatsapp_line). With an API key marked as an AI agent's (an owner or admin sets it on the key; it is never chosen per call), the message is recorded as sent by AI, like the AI Setter's (crm.messages.list marks it as sent by AI, with the key's user as its AI agent), the AI badge in the inbox, and it counts as AI, not as a person, in reports and in caps (crm.messages.count with ai_agent_user_id). Its dry run runs the same checks as the send without calling Meta (the conversation, your scope, the recipient, the line) and warns about what Meta would refuse, such as a closed 24-hour window; the line's access to Meta is only checked when it is sent. In the practice organization (test keys) nothing reaches Meta: the message is recorded as sent in the conversation and the response carries simulated: true (from_phone_number_id is checked the same way, but a conversation without a line does not take it).
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo
Tool do MCP
crm_whatsapp_send_textNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.send_text".
Custo declarado: até 61 leituras e 7 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
conversation_idstringrotaobrigatório
The conversation: an id from crm.conversations.list.
textstringcorpoobrigatório
The message, as the contact will read it (up to 4,096 characters).
from_phone_number_idstringcorpoopcional
The WhatsApp line to send from (a phone number id of crm.lines.list). In a conversation that already has a line it must be that line (another one is 409 conversation_line_mismatch). In a conversation without a line (imported from another system) the message goes out from this line and the conversation takes it from then on, so the contact's replies land in it. Default: the conversation's line or, without one, the organization's first active WhatsApp line (for a seller with restricted scope, the first one she works).
tostringcorpoopcional
The contact's number with its country code (E.164, for example +5491155550000). Without it, the conversation's contact.
reply_to_external_idstringcorpoopcional
To quote a message (a reply in WhatsApp): its external_id from crm.messages.list. Without it, nothing is quoted.
reply_to_message_idstringcorpoopcional
The quoted message's id from crm.messages.list, so the conversation shows the quote.
reply_to_contentstringcorpoopcional
The quoted text the conversation shows (the first 500 characters of the quoted message's content).
reply_to_senderstringcorpoopcional
Who wrote the quoted message, as the conversation shows it (the contact's name, or the sender's).
Resposta
message_idstring
do_not_contactobject
Only when it went out to a person marked «Do not contact» or unsubscribed: who, why, and whether it answered what they wrote after being marked or a person of the team confirmed it.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação é simulada: nada é enviado e a resposta traz simulated: true.
Sends an approved WhatsApp template (HSM) by name and language code, with its body variables in order ({{1}}, {{2}}…; each one with type text and its value already written, a price or a date included); this is how a conversation is started or resumed outside the 24-hour window, and Meta bills it. With conversation_id it sends in that conversation; without it, it finds or creates the conversation for the number in to on the line from_phone_number_id (default: the organization's first active WhatsApp line). Without conversation_id, deal_id or prospect_id (one of them) links that conversation, new or existing, to that deal or prospect of the organization and to its person: person_id, if given, must be one of the deal's persons or the prospect's person (person_not_in_deal or invalid_input), otherwise the deal's primary person or the prospect's person is used, and to must be one of that person's phones (phone_not_of_person, also when the deal or prospect has no person); deal_not_found, prospect_not_found or person_not_found when it does not exist or the seller cannot see it, deal_merged or prospect_processed for a merged one, and crm_action_denied (edit_deal or edit_prospect) when a seller with restricted scope can see the deal or prospect but not work it (another seller's, one in a pipeline they only read, or a prospect the AI works). Only APPROVED templates from crm.whatsapp.templates.list can be sent. MB Suite cannot send a template with any non-TEXT header (IMAGE, VIDEO, DOCUMENT or LOCATION) nor one with variables in its header yet (it only sends the body's variables). When the synced copy has that template in that language, the send stops before Meta with nothing recorded (no conversation, no failed message): 400 template_media_header_unsupported (mb_template_media_header in details.error_code) or 400 template_header_variables_unsupported (mb_template_header_variables). When it does not (a template created or edited in Meta after the last sync), Meta rejects it (132012 or 132000) and the failed message stays in the conversation: run crm.whatsapp.templates.sync first. Failures keep the failed message and return Meta's code in details.provider_code (also in details.error_code): external_rejected, external_rate_limited when Meta is throttling, or external_outcome_unknown when Meta failed without a clear answer (check the conversation before sending it again). A template starts the contact, so a person marked «Do not contact» or unsubscribed (found by the conversation's persons, the deal's or prospect's person, person_id, and always by the number, in all its forms) does not get it: 409 do_not_contact before anything is recorded, with the number and why in details.recipients and whether it can be confirmed in details.overridable. Only a person of the team can confirm it, on a closed basis (do_not_contact_override: about their account, a charge or support, or because the person asked us to write), with a reason outside the app (3 to 500 characters; without it, 400 do_not_contact_reason_required); it is recorded in the audit log and on the message. An AI agent's API key cannot confirm it (403 do_not_contact_override_not_allowed, and its 409 says overridable false), and a MARKETING template (by the synced copy of the templates) never goes to them, not even confirmed or as a reply (409 with overridable false). When that person wrote in the last 24 hours and after being marked (in the conversation, or without conversation_id in the one that number already has on that line), it is a reply and goes out without confirmation. When it goes out to one of them, the response carries do_not_contact (the recipients, allowed_as: reply or override, and the basis when confirmed). Requires send_whatsapp. From a line that belongs to another part of the product (not the CRM) it needs that part's edit permission and its write scope instead of the CRM's, and the conversation it opens or reuses belongs to that part. From such a line nothing of the CRM is linked: deal_id, prospect_id and person_id are refused (400 invalid_input) and the deals, prospects and persons of the CRM are not touched. With conversation_id, the sending line must belong to the same part of the product as the conversation (400 line_module_mismatch). With an API key marked as an AI agent's (an owner or admin sets it on the key; it is never chosen per call), the message is recorded as sent by AI, like the AI Setter's (crm.messages.list marks it as sent by AI, with the key's user as its AI agent), the AI badge in the inbox, and it counts as AI, not as a person, in reports and in caps (crm.messages.count with ai_agent_user_id). Its dry run runs the same checks as the send without calling Meta (the recipient, the line, the deal or prospect, a template MB Suite cannot send) and warns when the synced copy does not have the template, has it not approved or with another number of variables. In the practice organization (test keys) nothing reaches Meta: the conversation (found or created for to) gets the message as [Template: name] and the response carries simulated: true.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo
Tool do MCP
crm_whatsapp_send_templateNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.send_template".
Custo declarado: até 67 leituras e 8 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
template_namestringcorpoobrigatório
An APPROVED template of that line's WhatsApp Business account: its name from crm.whatsapp.templates.list.
language_codestringcorpoobrigatório
The language of that template version (es, en_US, pt_BR…), as crm.whatsapp.templates.list returns it.
conversation_idstringcorpoopcional
The conversation: an id from crm.conversations.list. Without it, the conversation of to on that line is found or created.
from_phone_number_idstringcorpoopcional
The WhatsApp line it goes out from: a phone_number_id from crm.lines.list. Default: the conversation's line or, without a conversation, the organization's first active WhatsApp line.
tostringcorpoopcional
The contact's number with its country code (E.164, for example +5491155550000). Without it, the conversation's contact. Send to or conversation_id.
variablesarray<object>corpoopcional
The values of the template body's {{1}}, {{2}}… in order (as many as the template has).
contact_namestringcorpoopcional
The contact's name for a new conversation (it shows in the inbox until a person is linked).
person_idstringcorpoopcional
The person the message is for (crm.persons.list): the conversation is linked to them.
deal_idstringcorpoopcional
Without conversation_id: the deal (crm.deals.list) the conversation is tied to, with its person.
prospect_idstringcorpoopcional
Without conversation_id: the prospect (crm.prospects.list) the conversation is tied to, with its person.
do_not_contact_overrideobjectcorpoopcional
Only for a recipient marked «Do not contact» or unsubscribed (409 do_not_contact names them): a person of the team confirms the message, on one of two bases. An AI agent's API key cannot confirm it (403 do_not_contact_override_not_allowed) and a WhatsApp marketing template never goes to them. Without it nothing is sent to them; a reply to what they wrote after being marked needs no confirmation (each send says when).
Resposta
message_idstring
conversation_idstring
do_not_contactobject
Only when it went out to a person marked «Do not contact» or unsubscribed: who, why, and whether it answered what they wrote after being marked or a person of the team confirmed it.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação é simulada: nada é enviado e a resposta traz simulated: true.
Send an image, video, audio or document by WhatsApp
crm.whatsapp.send_media
EscritaDesde 2026-11-01
Sends a file in an existing WhatsApp conversation: storage_path is the key of a file already uploaded to this same conversation (crm.whatsapp.uploads.create, or the app's composer) or to this organization's media library (there is no multipart upload here); a file of another conversation is 400 media_not_of_conversation and a key outside the organization 400 media_outside_org. An external http(s) media_url is also accepted and Meta fetches it. Optional caption for image, video and document. A document reaches the contact with a name: file_name if given (with its extension, e.g. Propuesta.pdf), otherwise the uploaded file's name or the last part of the URL; the conversation shows it too. It goes out from the conversation's own WhatsApp line: from_phone_number_id can only name that line (another one is 409 conversation_line_mismatch with details.conversation_line, because Meta counts the 24-hour window per number; to write to the contact from another line use crm.conversations.start or crm.whatsapp.send_template without conversation_id). A conversation without a line (imported from another system; the contact's replies never reach it) goes out from from_phone_number_id and takes that line from then on, so the replies land in it: 409 conversation_exists_on_line with details.conversation_id when that number already has its conversation on that line (write there instead), and when to is another number the conversation does not take the line. Without from_phone_number_id such a conversation goes out from the organization's first active WhatsApp line (for a seller with restricted scope, the first one they work) and keeps having no line. A line of another part of the product is 400 line_module_mismatch, and one not connected to the organization 404 external_account_not_linked. Same 24-hour window and permissions as crm.whatsapp.send_text. To a person marked «Do not contact» or unsubscribed it still goes out (free text only reaches a contact who wrote in the last 24 hours, so it is a reply), and the response carries do_not_contact. With an API key marked as an AI agent's (an owner or admin sets it on the key; it is never chosen per call), the message is recorded as sent by AI, like the AI Setter's (crm.messages.list marks it as sent by AI, with the key's user as its AI agent), the AI badge in the inbox, and it counts as AI, not as a person, in reports and in caps (crm.messages.count with ai_agent_user_id). Its dry run runs the same checks as the send without calling Meta (the conversation, your scope, the recipient, the line) and warns about what Meta would refuse, such as a closed 24-hour window; the line's access to Meta is only checked when it is sent. In the practice organization (test keys) Meta never fetches the file: the message is recorded and the response carries simulated: true.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo
Tool do MCP
crm_whatsapp_send_mediaNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.send_media".
Custo declarado: até 61 leituras e 7 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
conversation_idstringrotaobrigatório
The conversation: an id from crm.conversations.list.
media_typeenumcorpoobrigatório
What is sent: image, video, document or audio.
Valores: image, video, document, audio
from_phone_number_idstringcorpoopcional
The WhatsApp line to send from (a phone number id of crm.lines.list). In a conversation that already has a line it must be that line (another one is 409 conversation_line_mismatch). In a conversation without a line (imported from another system) the message goes out from this line and the conversation takes it from then on, so the contact's replies land in it. Default: the conversation's line or, without one, the organization's first active WhatsApp line (for a seller with restricted scope, the first one she works).
tostringcorpoopcional
The contact's number with its country code (E.164, for example +5491155550000). Without it, the conversation's contact.
storage_pathstringcorpoopcional
The file already uploaded: the storage_path that crm.whatsapp.uploads.create returned (or a media library file of the organization). Send storage_path or media_url.
media_urlstring (uri)corpoopcional
A public http(s) link to the file, which Meta downloads. Send storage_path or media_url.
captionstringcorpoopcional
The text under an image, a video or a document.
file_namestringcorpoopcional
The name the contact sees for a document, with its extension (Propuesta.pdf). Without it, the name of the uploaded file (or the URL's) is used. Ignored for images, videos and audio.
Resposta
message_idstring
do_not_contactobject
Only when it went out to a person marked «Do not contact» or unsubscribed: who, why, and whether it answered what they wrote after being marked or a person of the team confirmed it.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação é simulada: nada é enviado e a resposta traz simulated: true.
Sends Meta the read receipt for an inbound message (message_external_id: the WhatsApp message id, external_id in crm.messages.list) and resets the conversation's unread counter. The counter is reset even if Meta does not accept the receipt. Idempotent. Requires send_whatsapp on CRM lines.
Escopo
crm:write
Permissão
Editar no módulo
Tool do MCP
crm_whatsapp_mark_readNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.mark_read".
Custo declarado: até 27 leituras e 1 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
conversation_idstringrotaobrigatório
The conversation: an id from crm.conversations.list.
message_external_idstringcorpoobrigatório
The contact's last message to mark as read: its external_id from crm.messages.list.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
GET/v1/crm/whatsapp/templates
List the WhatsApp templates of a line
crm.whatsapp.templates.list
LeituraIdempotenteDesde 2026-11-01
Lists the message templates synced for a line's WhatsApp Business account (by phone_number_id or waba_id; default: the organization's first CRM line): name, language, category, status (only APPROVED ones can be sent, and not those with any non-TEXT HEADER (IMAGE, VIDEO, DOCUMENT or LOCATION) or with {{n}} variables in a TEXT HEADER: MB Suite cannot send them yet), components with their {{n}} variables and, when mapped, the CRM field that fills each variable (variable_map). It reads the synced copy, not Meta: run crm.whatsapp.templates.sync to refresh it.
Escopo
crm:read
Permissão
Ver o módulo
Tool do MCP
crm_whatsapp_templates_listNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.list".
Custo declarado: até 22 leituras e 0 escritas por chamada (contam na cota diária).
Parâmetros
phone_number_idstringqueryopcional
The line whose WhatsApp Business account it works on: a phone_number_id from crm.lines.list. Default: the organization's first CRM line.
waba_idstringqueryopcional
Instead of a line, a WhatsApp Business account id (numeric) connected to the organization.
statusenumqueryopcional
Only the templates in this Meta status (APPROVED to send).
Refresh the WhatsApp templates of a line from Meta
crm.whatsapp.templates.sync
EscritaIdempotenteDesde 2026-11-01
Brings from Meta the templates of a line's WhatsApp Business account into the synced copy that crm.whatsapp.templates.list reads, and returns them. By default only the APPROVED ones are updated; include_all_statuses brings every status (pending, rejected with its reason, paused…) and drops deleted templates from the manual order and labels. Requires manage_sources.
Escopo
crm:write
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_syncNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.sync".
Custo declarado: até 28 leituras e 2 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
phone_number_idstringcorpoopcional
The line whose WhatsApp Business account it works on: a phone_number_id from crm.lines.list. Default: the organization's first CRM line.
include_all_statusesbooleancorpoopcional
Bring every template whatever its status (pending, rejected…), not only the approved ones.
curl-X POST "https://api.mb-suite.com/v1/crm/whatsapp/templates/sync" \
-H"Authorization: Bearer $MB_API_KEY"
Testar com a sua API key de teste
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
GET/v1/crm/whatsapp/templates/compare
Compare a line's WhatsApp templates in Meta with the synced copy, without writing
crm.whatsapp.templates.compare
LeituraIdempotenteDesde 2026-11-01
Compares, without writing anything, the templates Meta has right now for a line's WhatsApp Business account (phone_number_id; default: the organization's first CRM line) with the synced copy that crm.whatsapp.templates.list reads: what crm.whatsapp.templates.sync would change, and the live status of each template. added (in Meta and not in the copy, with their components), status_changed (from the copy's status to Meta's, with the rejection reason when Meta gives one), content_changed (another category or other components: an edit made in Meta; fields says which and template is Meta's version), quality_changed (another quality rating in Meta: from the copy's score to Meta's, GREEN, YELLOW, RED, UNKNOWN or null when a side has none; only the score is compared, not when Meta measured it), removed (only with include_all_statuses: in the copy and no longer in Meta, which a full sync drops) and unchanged (how many have the same status and content, whatever their quality); a template can be in several of these lists. Plus by_status (Meta's templates by status), fetched and synced_at (when the copy was last refreshed). By default only the APPROVED templates are compared, as the default sync does (one that stopped being approved is not reported: use include_all_statuses). It calls Meta once and counts against the organization's WhatsApp quota, but writes nothing. Meta returns one page (200 templates with include_all_statuses, 100 without) and MB Suite does not ask for the next one: truncated: true means this comparison, like a sync, only saw that page. Run crm.whatsapp.templates.sync to apply the changes. Requires manage_sources, like the sync. Errors: external_account_not_linked (404) when phone_number_id is not a line of the organization; integration_not_connected or integration_reconnect_required when WhatsApp is not connected or lost access to the line; external_rejected, external_rate_limited or external_unavailable when Meta fails. In the practice organization (test keys) it is 409 sandbox_external_unavailable.
Escopo
crm:read
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_compareNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.compare".
Custo declarado: até 28 leituras e 0 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
phone_number_idstringqueryopcional
The line whose WhatsApp Business account is compared (a phone number id of crm.lines.list). Default: the organization's first CRM line, as crm.whatsapp.templates.sync.
include_all_statusesbooleanqueryopcional
Compare every template whatever its status, as a full sync does: removed then lists the templates the copy has and Meta no longer returns. Default: only the APPROVED ones, as the default sync (a template that stopped being approved is not reported).
Resposta
waba_idstring
synced_atnumber | null
When the synced copy was last refreshed (epoch ms); null if it was never synced.
include_all_statusesboolean
fetchednumber
How many templates Meta returned.
truncatedboolean
Meta returned a full page (200 templates with include_all_statuses, 100 without) and MB Suite does not ask for the next one: the comparison, and a sync, only see that first page.
by_statusobject
How many of the templates Meta returned are in each status (APPROVED, PENDING, REJECTED, PAUSED…).
addedarray<object>
In Meta and not in the copy: a sync would add them.
status_changedarray<object>
In both, with another status in Meta (from: the copy, to: Meta); rejected_reason when Meta gives one.
content_changedarray<object>
In both, with another category or other components in Meta (an edit made in Meta): fields says which, and template is Meta's version.
quality_changedarray<object>
In both, with another quality rating in Meta (from: the copy's score, to: Meta's): GREEN, YELLOW, RED or UNKNOWN as Meta says it (Meta may add values), or null when that side has none. Only the score is compared, not when Meta measured it. A sync would bring Meta's into the copy.
removedarray<object>
Only with include_all_statuses: in the copy and no longer in Meta (deleted there): a full sync would drop them.
unchangednumber
How many have the same status and the same content in Meta and in the copy. The quality is compared apart: a template whose only change is its quality rating counts here and is listed in quality_changed.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
POST/v1/crm/whatsapp/templates
Submit a new WhatsApp template to Meta
crm.whatsapp.templates.create
EscritaDesde 2026-11-01
Submits a new template for Meta's review on a line's WhatsApp Business account: name (lowercase letters, digits and underscore), category (MARKETING, UTILITY or AUTHENTICATION), language (es, en_US, pt_BR…) and components: header (only a TEXT header without variables for now: any non-TEXT header (IMAGE, VIDEO, DOCUMENT or LOCATION) is refused before Meta with 400 template_media_header_unsupported and a header with {{n}} with 400 template_header_variables_unsupported, because MB Suite cannot send them yet), body with sequential {{1}}…{{n}} variables and their examples, footer and up to 3 buttons. variable_map optionally says what fills each body variable when the template is sent from MB Suite (a CRM field: contact_name, company, email, phone or assignee; or manual), as the app does when it creates one: it is MB Suite's own data (it does not go to Meta), it can only name variables the body has (400 invalid_input, checked before Meta) and is saved once Meta accepts the template (variable_map_saved: false if that last step failed; set it again with crm.whatsapp.templates.update). crm.whatsapp.templates.list shows it. It starts PENDING (review usually takes 1 to 24 hours) and can be sent once APPROVED. Requires manage_sources.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_createNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.create".
Custo declarado: até 26 leituras e 1 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
namestringcorpoobrigatório
The template's name: lowercase letters, digits and underscores (Meta keeps it; it cannot be renamed).
categoryenumcorpoobrigatório
MARKETING, UTILITY or AUTHENTICATION (Meta may change it when reviewing).
Valores: MARKETING, UTILITY, AUTHENTICATION
languagestringcorpoobrigatório
The language code: es, en_US, pt_BR…
componentsarray<object>corpoobrigatório
The parts, as Meta defines them: an optional HEADER (TEXT only), the BODY with its {{1}}, {{2}}… variables and an example, an optional FOOTER and BUTTONS.
phone_number_idstringcorpoopcional
The line whose WhatsApp Business account it works on: a phone_number_id from crm.lines.list. Default: the organization's first CRM line.
variable_mapobjectcorpoopcional
What fills each {{n}} of the body when the template is sent (MB Suite metadata; it does not go to Meta): {"1": {"kind": "field", "field": "contact_name"}, "2": {"kind": "manual"}}. field is contact_name, company, email, phone or assignee (the owner's name); manual (or no entry) is typed in when sending. Keys are the body's variables.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
PATCH/v1/crm/whatsapp/templates/{template_id}
Edit a WhatsApp template in place
crm.whatsapp.templates.update
EscritaDesde 2026-11-01
Replaces the components (and optionally the category) of a synced template, found by template_id (crm.whatsapp.templates.list); template_name is optional and, if sent, must be that template's name (a check that the id is the one you mean). Name and language cannot change (create a new template for that). The new components cannot have a non-TEXT header (IMAGE, VIDEO, DOCUMENT or LOCATION: 400 template_media_header_unsupported) nor variables in the header (400 template_header_variables_unsupported), both before Meta: a template that has one can be edited to remove it. Meta only edits APPROVED, REJECTED or PAUSED templates, at most once every 24 hours; an approved template goes back to review and its previous version keeps working until it is approved again. variable_map, if given, replaces what fills each body variable when sending from MB Suite (same shape and rules as in crm.whatsapp.templates.create; without it the current map stays), saved after Meta accepts the edit (variable_map_saved). Requires manage_sources.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_updateNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.update".
Custo declarado: até 47 leituras e 1 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
template_idstringrotaobrigatório
The template version to edit: its id from crm.whatsapp.templates.list (Meta edits by id; name and language do not change).
componentsarray<object>corpoobrigatório
The new parts, all of them (they replace the current ones), as in crm.whatsapp.templates.create.
phone_number_idstringcorpoopcional
The line whose WhatsApp Business account it works on: a phone_number_id from crm.lines.list. Default: the organization's first CRM line.
template_namestringcorpoopcional
Optional: the template's name, which is taken from template_id anyway. If sent, it must be that template's name (otherwise 400 invalid_input, param template_name), as a check that the id is the template you mean.
categoryenumcorpoopcional
A new category (MARKETING, UTILITY or AUTHENTICATION).
Valores: MARKETING, UTILITY, AUTHENTICATION
variable_mapobjectcorpoopcional
What fills each {{n}} of the body when the template is sent (MB Suite metadata; it does not go to Meta): {"1": {"kind": "field", "field": "contact_name"}, "2": {"kind": "manual"}}. field is contact_name, company, email, phone or assignee (the owner's name); manual (or no entry) is typed in when sending. Keys are the body's variables.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
Copy a WhatsApp template to another line's account
crm.whatsapp.templates.duplicate
EscritaDesde 2026-11-01
Copies a template from the WhatsApp Business account of one line (source_phone_number_id) to the account of another (target_phone_number_id) with the same name, language, category and components; the copy goes through Meta's review on the target account. Lines under the same account already share their templates. A template MB Suite cannot send is not copied, before creating anything in Meta: a non-TEXT header (IMAGE, VIDEO, DOCUMENT or LOCATION) is 400 template_media_header_unsupported and variables in the header 400 template_header_variables_unsupported. Requires manage_sources.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:write
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_duplicateNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.duplicate".
Custo declarado: até 16 leituras e 2 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
template_idstringrotaobrigatório
The template to copy: its id from crm.whatsapp.templates.list of the source line.
source_phone_number_idstringcorpoobrigatório
The line whose WhatsApp Business account has the template (crm.lines.list).
target_phone_number_idstringcorpoobrigatório
The line whose WhatsApp Business account gets the copy (crm.lines.list); Meta reviews it there.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
DELETE/v1/crm/whatsapp/templates/{template_name}
Delete a WhatsApp template in Meta
crm.whatsapp.templates.delete
IrreversívelDesde 2026-11-01
Deletes a template in Meta: one language version (hsm_id) or every language of that name. Meta's deletion is final: the trash keeps a copy of each deleted version (name, language, category and components) so it can be recreated, but it is not restored automatically (a new template goes through review again). Outside the screen it requires a dry run and a confirm_token. Requires manage_sources.
Pede confirmação: primeiro dry_run: true (prévia e confirm_token, válido por 10 minutos e por uma única execução), depois o mesmo corpo com confirm_token. Em algumas poucas, só com certos dados: a descrição diz quando. Por que e como: Prévia e confirmação.
Escopo
crm:writee «Permitir exclusões» (crm:delete no OAuth)
Permissão
Editar no módulo · Ação do CRM: manage_sources
Tool do MCP
crm_whatsapp_templates_deleteNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.templates.delete".
Custo declarado: até 48 leituras e 2 escritas por chamada (contam na cota diária). Usa uma plataforma externa (whatsapp): conta na cota de operações externas.
Parâmetros
template_namestringrotaobrigatório
The template's name (crm.whatsapp.templates.list).
phone_number_idstringcorpoopcional
The line whose WhatsApp Business account it works on: a phone_number_id from crm.lines.list. Default: the organization's first CRM line.
hsm_idstringcorpoopcional
Only that language version: its id from crm.whatsapp.templates.list. Without it, every language of that name is deleted.
Resposta
oktrue
trash_item_idstring
The trash item this deletion left: the item_id of platform.trash.restore (POST /trash/{item_id}/restore). Missing if nothing went to the trash.
trash_item_idsarray<string>
Only when the deletion left more than one copy: all of them, the first being trash_item_id.
trash_expires_atnumber
When the copy leaves the trash for good (epoch ms): 30 days after the deletion.
Com uma API key de teste o pedido vai sempre para a sua organização de prática: dados de exemplo que você pode reiniciar.Na prática esta operação não é simulada (usa outra plataforma): responde 409 sandbox_external_unavailable.
GET/v1/crm/whatsapp/lines/available
List the WhatsApp lines a lead source can use
crm.whatsapp.lines.available
LeituraIdempotenteDesde 2026-11-01
Lists the organization's CRM WhatsApp lines (the numbers connected in CRM → Settings → Lines; lines of other modules are left out) with waba_id, phone_number_id, display_phone, verified_name, quality_rating and already_added (the line already has an active lead source: a line takes only one). Lines without a source come first. Use phone_number_id as whatsapp_line_id in crm.lead_sources.create_whatsapp. Connecting a new number is done in the app (it needs Meta's authorization). Requires view access to the CRM.
Escopo
crm:read
Permissão
Ver o módulo
Tool do MCP
crm_whatsapp_lines_availableNa superfície completa; na compacta, mb_execute_operation com id: "crm.whatsapp.lines.available".
Custo declarado: até 60 leituras e 0 escritas por chamada (contam na cota diária).