Lists the organization's web forms (HTML forms embedded on websites that email every submission and can feed the CRM), newest first, paginated by cursor (limit up to 200). enabled=true returns only published forms (accepting submissions), false only unpublished ones; the page is completed up to limit (reading up to 500 forms per call). Each row carries the notification recipients, allowed origins, anti-spam settings, CRM link, counters, created_by_name, field_count and auto_responder_enabled; the fields and the auto-responder come with web_forms.forms.get. Use web_forms.submissions.list for the responses. Requires view access to Web Forms.
Scope
web_forms:read
Permission
View the module
MCP tool
web_forms_forms_listOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.list".
Declared cost: up to 701 reads and 0 writes per call (they count against the daily quota).
Parameters
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.
enabledbooleanqueryoptional
true = only published forms; false = only unpublished ones. Filtered on the page read.
Returns one web form: its fields (name, label, type, required, crm_template), the notification email (from_name, to_emails, subject, conditional recipient_routing), allowed_origins, the anti-spam settings (honeypot_field_name, recaptcha_enabled, rate_limits), thank_you_url, the auto-responder, the CRM link (linked_source_id), its counters (stats) and who created it (created_by_id, created_by_name). A visitor's page submits with POST https://mb-suite.com/api/v1/public/forms/submit?formId=<id> and a JSON body {"formId": <id>, "<field name>": <value>, …}, sent from one of allowed_origins. Not found (web_form_not_found) if the id does not exist in this organization. Requires view access to Web Forms.
Scope
web_forms:read
Permission
View the module
MCP tool
web_forms_forms_getOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.get".
Declared cost: up to 2 reads and 0 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
Response
idstring
org_idstring
namestring
enabledboolean
fieldsarray<object>
honeypot_field_namestring
from_namestring
to_emailsarray<string>
subjectstring
allowed_originsarray<string>
rate_limitsobject
statsobject
created_atnumber
updated_atnumber
descriptionstring
ordernumber
from_emailstring
sender_idstring | null
reply_to_fieldstring | null
recipient_routingobject | null
turnstile_enabledboolean
turnstile_site_keystring | null
recaptcha_enabledboolean
recaptcha_min_scorenumber
thank_you_urlstring
email_brandingstring
crm_enabledboolean
linked_source_idstring | null
auto_responderobject | null
created_by_idstring
created_by_namestring | null
Display name of created_by_id (null if it is not a person of the organization).
Creates a web form: name, 1 to 40 fields (name, label, type text|email|phone|textarea|number, required), the internal recipients of the notification email (to_emails, up to 10), its sender name and subject ({{field_name}} placeholders allowed), the origins allowed to submit (allowed_origins, scheme://host without path) and optionally a thank-you URL, conditional routing of recipients, an auto-responder (needs a verified Branding domain and sender), rate limits and CRM availability. It is created unpublished by default (enabled=false): publish it with web_forms.forms.publish (or create it with enabled=true) and from then on it accepts submissions at POST https://mb-suite.com/api/v1/public/forms/submit and emails each one to to_emails. reCAPTCHA is off by default through the API; turn it on only if the page sends a g-recaptcha-response token. The CRM link is made from the CRM (a lead source of type MB Suite Form) or with web_forms.forms.link_crm, which can also create that source (create_source). Errors: branding_not_verified / sender_not_found (a sender_id or auto-responder sender not usable), routing_field_reserved. Returns the new form_id and the form. Requires edit access to Web Forms.
Instructions for agents
Tell the person the form_id, whether it is published (enabled) and how the page submits: POST https://mb-suite.com/api/v1/public/forms/submit?formId=<form_id> with {"formId", one key per field name}, from one of the allowed origins. Never invent recipients: use the ones the person gave.
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_createOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.create".
Declared cost: up to 0 reads and 1 writes per call (they count against the daily quota).
Parameters
namestringbodyrequired
Internal name of the form (visitors never see it).
fieldsarray<object>bodyrequired
The form's fields (1 to 40), in the order the page shows them.
from_namestringbodyrequired
Sender display name of the notification email.
to_emailsarray<string (email)>bodyrequired
Internal recipients of the notification email sent for every submission.
subjectstringbodyrequired
Subject of the notification email; {{field_name}} is replaced by the submitted value.
allowed_originsarray<string (uri)>bodyrequired
Origins allowed to submit (scheme://host[:port], no path), e.g. https://www.example.com.
descriptionstringbodyoptional
Internal description.
enabledbooleanbodyoptional
false (default) = draft; true = published (it accepts submissions right away and each one emails to_emails). Publish later with web_forms.forms.publish.
Default: false
honeypot_field_namestringbodyoptional
Name of the hidden anti-bot field; the page must render it empty and hidden. Keep the default unless the page already uses it.
Default: "_qzt_field"
sender_idstring | nullbodyoptional
Id of a Branding sender (verified email domain) for the notification email; null = form@mb-suite.com.
Default: null
reply_to_fieldstring | nullbodyoptional
Name of the email field whose value becomes the Reply-To of the notification.
Default: null
recipient_routingobject | nullbodyoptional
Conditional recipients: a field of the form picks who gets the notification; null or absent = always to_emails.
turnstile_enabledbooleanbodyoptional
Cloudflare Turnstile gate (needs turnstile_site_key and the widget on the page).
Default: false
turnstile_site_keystring | nullbodyoptional
The Turnstile site key of the page.
Default: null
recaptcha_enabledbooleanbodyoptional
reCAPTCHA Enterprise gate. Turn it on only if the page sends a g-recaptcha-response token (the snippet from the screen does): with it on, submissions without a token are silently dropped.
Default: false
recaptcha_min_scorenumberbodyoptional
Minimum reCAPTCHA score (0 to 1) to accept a submission; without it, the platform default.
thank_you_urlstringbodyoptional
Absolute http(s) URL the visitor is sent to after submitting; without it the page shows its inline success message.
Updates one or more settings of a web form (updates object): name, description, enabled, fields, honeypot_field_name, from_name, sender_id, to_emails, subject, reply_to_field, recipient_routing (null removes it), allowed_origins, recaptcha_enabled, recaptcha_min_score (null = global default), thank_you_url (null removes it), rate_limits, auto_responder, email_branding, crm_enabled. Only what is sent changes; fields replaces the whole list. crm_enabled cannot be turned off while the form is linked to a CRM lead source (crm_enabled_required_while_linked: unlink it first with web_forms.forms.unlink_crm). To only publish or unpublish prefer web_forms.forms.publish / unpublish. Returns the updated form. Requires edit access to Web Forms.
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_updateOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.update".
Publishes a web form (enabled=true): from now on the public endpoint accepts its submissions, emails them and, when linked, sends them to the CRM. Idempotent: on a form that is already published nothing changes (changed=false). Returns the form. Requires edit access to Web Forms.
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_publishOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.publish".
curl-X POST "https://api.mb-suite.com/v1/web-forms/{form_id}/publish" \
-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/web-forms/{form_id}/publish" \
-H"Authorization: Bearer $MB_TEST_KEY"
POST/v1/web-forms/{form_id}/unpublish
Unpublish a web form
web_forms.forms.unpublish
WriteIdempotentSince 2026-11-01
Unpublishes a web form (enabled=false): the public endpoint answers its submissions with a generic 404 and stores nothing, while the form, its responses and its CRM link are kept. Use it to pause a form instead of deleting it. Idempotent: on a form that is already unpublished nothing changes (changed=false). Requires edit access to Web Forms.
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_unpublishOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.unpublish".
Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
curl-X POST "https://api.mb-suite.com/v1/web-forms/{form_id}/unpublish" \
-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/web-forms/{form_id}/unpublish" \
-H"Authorization: Bearer $MB_TEST_KEY"
POST/v1/web-forms/{form_id}/duplicate
Duplicate a web form
web_forms.forms.duplicate
WriteSince 2026-11-01
Copies a web form with all its settings into a new one named '<name> (copy)' (the suffix in the caller's language: '(copia)', '(copy)' or '(cópia)'), unpublished, without the CRM link (a lead source points to a single form) and with its counters at zero; responses are not copied. Returns the new form_id and the form. Requires edit access to Web Forms.
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_duplicateOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.duplicate".
Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
curl-X POST "https://api.mb-suite.com/v1/web-forms/{form_id}/duplicate" \
-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/web-forms/{form_id}/duplicate" \
-H"Authorization: Bearer $MB_TEST_KEY"
DELETE/v1/web-forms/{form_id}
Delete a web form and its responses
web_forms.forms.delete
IrreversibleSince 2026-11-01
Deletes a web form together with ALL its responses, and removes its link with the CRM lead source (the source stays active; leads already created stay in the CRM). The form's configuration goes to the 30-day trash and owners and admins can restore it (it comes back unlinked from the CRM and with its counters at zero); the responses are deleted for good and do not come back: export them first with web_forms.submissions.list if they are needed. To pause a form use web_forms.forms.unpublish instead. Outside the screen it always requires a dry run (which says how many responses will be lost) and a confirm_token. Requires edit access to Web Forms.
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
web_forms:writeand “Allow deletions” (web_forms:delete in OAuth)
Permission
Edit in the module
MCP tool
web_forms_forms_deleteOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.delete".
Declared cost: up to 503 reads and 503 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
Response
oktrue
submissions_deletednumber
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.
Sends the form's notification email with dummy values to its configured recipients (to_emails, or the routing defaults), through Amazon SES, so the recipients and the look of the email can be checked. Stores nothing. Returns sent=false with the error (for example, no valid recipients) instead of failing; the attempt is audited either way. At most one test per form and person every 30 seconds (cooldown_active, 429). Sends a real email: run it only when the person asks to test the notification. Outside the app it always runs in two steps: dry_run=true says to whom it goes (and, for a test submission, whether it creates a CRM lead and where the auto-reply goes) with the same checks and a confirm_token (10 minutes); then call it again with the confirm_token. Requires edit access to Web Forms.
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
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_send_test_notificationOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.send_test_notification".
Declared cost: up to 1 reads and 0 writes per call (they count against the daily quota). Touches an external platform (ses): it counts against the external operations quota.
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
With a test API key the request always goes to your practice organization: example data you can reset.In the practice organization this operation is not simulated (it reaches another platform): it answers 409 sandbox_external_unavailable.
POST/v1/web-forms/{form_id}/test-submit
Send a test submission through the whole pipeline
web_forms.forms.test_submit
WriteSince 2026-11-01
Runs a test submission of the form with the given values ({name, value} pairs, one per field) through the real pipeline, skipping only the origin, rate-limit, honeypot and CAPTCHA checks: it validates the values against the form's fields (validation_failed with details.fields), stores a response marked as a test (origin __test__), sends the notification email to the form's recipients through Amazon SES, creates a REAL lead in the CRM when the form is linked to a lead source, and sends the auto-responder (if on) to the caller's own email with a [TEST] subject prefix. It does not fire web_forms.submission.received. At most one test per form and person every 30 seconds (cooldown_active). Returns what happened at each step. Run it only when the person asks to test the form. Outside the app it always runs in two steps: dry_run=true says to whom it goes (and, for a test submission, whether it creates a CRM lead and where the auto-reply goes) with the same checks and a confirm_token (10 minutes); then call it again with the confirm_token. Requires edit access to Web Forms.
Instructions for agents
Tell the person the test response is stored marked as a test and, when lead_created is true, that a real lead was created in the CRM (they may want to delete it).
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
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_test_submitOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.test_submit".
Declared cost: up to 3 reads and 4 writes per call (they count against the daily quota). Touches an external platform (ses): it counts against the external operations quota.
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
valuesarray<object>bodyrequired
The submitted values as {name, value} pairs, one per form field, exactly as a visitor's page would send them.
With a test API key the request always goes to your practice organization: example data you can reset.In the practice organization this operation is not simulated (it reaches another platform): it answers 409 sandbox_external_unavailable.
POST/v1/web-forms/{form_id}/crm-link
Link a web form to a CRM lead source, or create the source for it
web_forms.forms.link_crm
WriteIdempotentSince 2026-11-01
Takes a web form to the CRM: from then on every real submission also creates a lead in the CRM with the source's destination, pipeline, field mapping and deduplication, and the form is marked available to the CRM (crm_enabled). Two ways, one per call. With source_id: links an existing lead source of type mb_suite_form that is free (crm.lead_sources.list with type mb_suite_form); both sides are written in one transaction and the source is reactivated. With create_source: true: creates a new lead source of type mb_suite_form for this form and links it in the same transaction, as CRM → Settings → Sources → MB Suite Form does; new_source sets its name (default: the form's), destination (prospect by default, or deal), pipeline and stage (validated: a deal source needs its pipeline; without a stage, its first one) and deduplication (merge by default). Every field of the form is mapped to the CRM (email, phone, name, company, website and the like to their CRM fields, the rest to custom:<field name>, so no answer is lost); labels and AI scoring are left out (AI scoring costs AI credits per lead, so it starts off): change them with crm.lead_sources.update. Creating a source needs manage_sources in the CRM (CRM admins, owners and admins). The dry run (dry_run: true) runs the same checks without writing and says what it would create or link. Errors: lead_source_not_found, lead_source_type_invalid, web_form_already_linked (the form already has a source: unlink it first with web_forms.forms.unlink_crm; its source is in details.source_id), lead_source_already_linked, and the pipeline and stage ones (pipeline_required, pipeline_not_found, pipeline_archived, stage_not_in_pipeline). Linking the source it already has changes nothing (changed false); with create_source, a second call finds the form linked (web_form_already_linked) and never creates another source. It fires no webhook event: the leads the form creates later fire crm.lead.created or crm.deal.created. Returns form_id, the source_id linked (the new one with create_source) and changed. Writes in the CRM: requires edit access to Web Forms AND to the CRM (and the crm:write scope for a credential).
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_link_crmOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.link_crm".
Declared cost: up to 4 reads and 3 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).
source_idstringbodyoptional
An existing CRM lead source of type mb_suite_form that is not linked to another form (crm.lead_sources.list with type mb_suite_form). Omit it to create one with create_source.
create_sourcebooleanbodyoptional
true: creates a new CRM lead source of type mb_suite_form for this form and links it in the same step, as CRM → Settings → Sources → MB Suite Form does (its settings in new_source). Instead of source_id, never with it. Requires manage_sources in the CRM.
new_sourceobjectbodyoptional
Only with create_source: the new source's name, destination, pipeline and stage, and what to do with a person who already exists. Everything is optional.
Response
form_idstring
The form.
source_idstring
The CRM lead source the form is linked to: the one passed, or the one created with create_source (crm.lead_sources.get).
changedboolean
false when the form was already linked to that source (nothing was written).
curl-X POST "https://api.mb-suite.com/v1/web-forms/{form_id}/crm-link" \
-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/web-forms/{form_id}/crm-link" \
-H"Authorization: Bearer $MB_TEST_KEY"
POST/v1/web-forms/{form_id}/crm-unlink
Unlink a web form from its CRM lead source
web_forms.forms.unlink_crm
WriteIdempotentSince 2026-11-01
Removes the link between the form and its CRM lead source (both sides, in one transaction): new submissions stop creating CRM leads, while the source keeps its history and stays as it was (active or not), and leads already created are kept. Idempotent: a form without a link returns unlinked_source_id=null. Writes in the CRM: requires edit access to Web Forms AND to the CRM (and the crm:write scope for a credential).
Scope
web_forms:write
Permission
Edit in the module
MCP tool
web_forms_forms_unlink_crmOn the full surface; on the compact one, mb_execute_operation with id: "web_forms.forms.unlink_crm".
Declared cost: up to 3 reads and 2 writes per call (they count against the daily quota).
Parameters
form_idstringpathrequired
The form's id (from web_forms.forms.list, or the form_id that web_forms.forms.create returns).