Menu

API reference · CRM

Lead sources

crm · lead_sources · 14 operations

GET/v1/crm/lead-sources

List lead sources

crm.lead_sources.list

ReadIdempotentSince 2026-11-01

Lists the org's lead sources (Meta, Google, TikTok, LinkedIn, WhatsApp, generic webhooks, forms, bookings, DMs, manual, the API source), newest first, with their destination, routing defaults, field mapping, AI scoring, health, stats and the account or line each one is bound to; filters by type and active_only; paginated by cursor (limit up to 200, default 50). The webhook URL comes only for generic sources. The secret never comes in the list: crm.lead_sources.get brings it, only for who can manage sources and never through the MCP. 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_lead_sources_listOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.list".

Declared cost: up to 1001 reads and 0 writes per call (they count against the daily quota).

Parameters

typeenumqueryoptional

Only sources of this type.

Values: meta, google, tiktok, linkedin, whatsapp, generic, csv, manual, mb_suite_form, booking, instagram_dm, facebook_dm, tiktok_dm

active_onlybooleanqueryoptional

Only active sources (paused ones are left out).

limitintegerqueryoptional

Sources per call, 1 to 200 (default 50), newest first.

Default: 50

cursorstringqueryoptional

next_cursor of the previous page.

Response

dataarray<object>
has_moreboolean
next_cursorstring

Errors

Example

curl "https://api.mb-suite.com/v1/crm/lead-sources" \
  -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 "https://api.mb-suite.com/v1/crm/lead-sources" \
  -H "Authorization: Bearer $MB_TEST_KEY"
GET/v1/crm/lead-sources/{source_id}

Get one lead source

crm.lead_sources.get

ReadIdempotentSince 2026-11-01

Returns a lead source with its destination (prospect or deal), default pipeline, stage and labels, currency, field mapping, dedup strategy, AI scoring, health, stats and the account or line it is bound to. The webhook URL comes only for a generic source; the secret only for who can manage sources and never through the MCP. Not found for deleted sources. 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 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_lead_sources_getOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.get".

Declared cost: up to 2 reads and 0 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

Response

idstring
namestring
typestring

One of: meta, google, tiktok, linkedin, whatsapp, generic, csv, manual, mb_suite_form, booking, instagram_dm, facebook_dm, tiktok_dm.

is_activeboolean

false when paused (pause_reason integration_disconnected: the system paused it).

webhook_urlstring

Only a generic source receives leads at its URL; empty for the rest.

destinationenum

Values: deal, prospect

deduplicationenum

Values: merge, create_activity, notify, skip

created_atnumber
updated_atnumber
is_systemboolean

The system sources Manual and API: they cannot be deleted or paused.

ordernumber | null
pause_reasonstring | null
paused_atnumber | null
webhook_secretstring

Only for who can manage sources, never through the MCP.

field_mappingarray<object>
default_pipeline_idstring | null

Pipeline of its deals (crm.pipelines.list).

default_stage_idstring | null
default_label_idsarray<string> | null
default_currencystring | null
returning_contact_is_new_businessboolean | null
no_rule_notify_user_idsarray<string> | null

Who is notified of leads no assignment rule gives an owner (empty: the account owner).

ai_qualificationobject | null

AI scoring of each new lead (it consumes AI credits).

statsobject | null
healthobject | null

healthy, degraded, broken, silent or unknown, and when it was last checked.

metaobject | null
googleobject | null
tiktokobject | null
linkedinobject | null
whatsapp_line_idstring | null

The WhatsApp line (crm.lines.list).

whatsappobject | null
mb_suite_formobject | null
bookingobject | null
social_dmobject | null
created_by_idstring | null

Errors

Example

curl "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -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 "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/crm/lead-sources

Create a generic or manual lead source

crm.lead_sources.create

WriteSince 2026-11-01

Creates a lead source of type generic (an inbound webhook: Make, Zapier, ManyChat, a site form or any system POSTs JSON to its webhook_url, signed with its secret) or manual (a bucket for leads loaded by hand or with crm.leads.ingest and its source_id). Sets where leads go (prospect inbox or a pipeline deal), the field mapping from each incoming JSON field to a CRM field (person.email, person.phone, person.firstName, person.lastName, company.website, deal.title, deal.value, cf:<custom field slug>, custom:<key>), the default pipeline, stage, labels and currency, the dedup strategy and AI scoring. A generic source must map at least one field to person.email or person.phone. The pipeline, stage, labels and mapped fields must exist (a deal source needs its pipeline; without a stage, its first one). AI scoring of each lead consumes AI credits and stays off unless ai_qualification.enabled is sent true. Sources on a WhatsApp line, on Social Inbox accounts (DMs) or on a booking page are created with crm.lead_sources.create_whatsapp, create_social_dm and create_booking; the source of an MB Suite web form with web_forms.forms.link_crm and create_source (it creates it and links the form); Meta, Google, TikTok and LinkedIn sources by their own integration in the app. Returns the webhook URL and the secret of a generic source (the secret only outside the MCP: through the MCP it comes back empty and the person reads or regenerates it in the app, CRM → Settings → Lead sources); a manual source has neither. Requires manage_sources.

Instructions for agents

Give the person the webhook_url and the webhook_secret now: the sending system must POST the lead as JSON to webhook_url with the header X-Webhook-Signature set to the hex HMAC-SHA256 of the raw body, keyed with the secret. If webhook_secret comes back empty you are on the MCP: tell the person to copy the secret from the source's page in the app (it is never sent through a chat). A manual source has no webhook: its leads come with crm.leads.ingest and its source_id.

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_createOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.create".

Declared cost: up to 0 reads and 2 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

The source's name, up to 200 characters.

destinationenumbodyrequired

Where each lead goes: prospect (the prospects inbox) or deal (a deal in default_pipeline_id).

Values: deal, prospect

typeenumbodyrequired

generic (a webhook: the sending system POSTs leads to webhook_url, signed with webhook_secret) or manual (leads you load with crm.leads.ingest or the app). WhatsApp, social DM and booking sources have their own create operations; an MB Suite web form gets its source with web_forms.forms.link_crm and create_source; ad platforms are connected in the app.

Values: generic, manual

is_activebooleanbodyoptional

Whether it receives leads from now on (default true).

Default: true

field_mappingarray<object>bodyoptional

How each incoming field maps to a CRM field, up to 50; a generic source maps at least one to person.email or person.phone.

Default: []

default_pipeline_idstringbodyoptional

Pipeline where the source's deals are created (crm.pipelines.list); required when destination is deal.

default_stage_idstringbodyoptional

Stage of that pipeline for new deals (crm.pipelines.get); default: its first stage.

default_label_idsarray<string>bodyoptional

Labels put on each new deal or prospect, up to 20: ids from crm.labels.list with the entity of the destination (deal or prospect).

Default: []

default_currencystringbodyoptional

Currency of the deals when the lead brings none (ISO 4217; default USD).

deduplicationenumbodyoptional

What happens when the person already exists: merge (update them and add the lead), create_activity (only log it), notify (log it and notify the owner) or skip (discard it).

Values: merge, create_activity, notify, skip · Default: "merge"

ai_qualificationobjectbodyoptional

AI scoring of the source's leads.

Default: {"enabled":false}

Response

idstring
source_idstring

The same id (every creation of a source returns both).

webhook_urlstring

Where the sending system POSTs the leads; only a generic source has one (empty for manual).

webhook_secretstring

Signs the POSTs; empty through the MCP and for sources without a webhook.

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "destination": "deal",
  "type": "generic"
}'

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/lead-sources" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "destination": "deal",
  "type": "generic"
}'
PATCH/v1/crm/lead-sources/{source_id}

Update a lead source

crm.lead_sources.update

WriteSince 2026-11-01

Updates a lead source's name, active flag, destination (prospect or deal), field mapping, default pipeline and stage, default labels, currency, dedup strategy (merge, create_activity, notify, skip) or AI scoring flag, inside updates; what is not sent is kept. The routing that results is validated like at creation (pipeline, stage of that pipeline, labels of the destination, mapped fields). The system sources (Manual, API) only accept the routing defaults and AI scoring. A generic source must keep a field mapped to person.email or person.phone. It does not change which page, ad account, forms or booking a source is bound to: that is done from its integration in the app; a DM source is edited whole with crm.lead_sources.update_social_dm. Requires manage_sources. With Google Ads or LinkedIn, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted (the permissions guide lists what each platform allows).

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_updateOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.update".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

updatesobjectbodyrequired

The fields to change; what is not sent is kept.

Response

oktrue

Errors

Example

curl -X PATCH "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "updates": {}
}'

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 PATCH "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "updates": {}
}'
DELETE/v1/crm/lead-sources/{source_id}

Delete a lead source

crm.lead_sources.delete

IrreversibleSince 2026-11-01

Deletes a lead source: it stops receiving leads at once, and the prospects, deals and conversations that came through it keep naming it. If it is the last source bound to a Meta page (in any organization) or to a TikTok advertiser, that page or advertiser is also unsubscribed from the platform's lead webhook. Deleting a WhatsApp source frees its line for a new source; the line itself keeps working (Messages, the Setter and the other modules that use it). The source goes to the 30-day trash. The system sources (Manual, API) cannot be deleted. Requires manage_sources. With TikTok, their terms limit it through the API and the MCP: what they do not allow answers 403 platform_terms_restricted (the permissions guide lists what each platform allows).

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:write and “Allow deletions” (crm:delete in OAuth)
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_deleteOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.delete".

Declared cost: up to 60 reads and 2 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

Response

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.

Errors

Example

curl -X DELETE "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -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 DELETE "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/crm/lead-sources/{source_id}/pause

Pause a lead source

crm.lead_sources.pause

WriteIdempotentSince 2026-11-01

Pauses a lead source: new leads stop entering (platform webhooks keep arriving and are discarded; the connection is not touched, so reactivating needs no reconnection). Pausing a source the system paused because its integration was disconnected turns it into a manual pause. The system sources (Manual, API) cannot be paused. Idempotent. Requires manage_sources.

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_pauseOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.pause".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

Response

oktrue

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/pause" \
  -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/lead-sources/{source_id}/pause" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/crm/lead-sources/{source_id}/reactivate

Reactivate a paused lead source

crm.lead_sources.reactivate

WriteIdempotentSince 2026-11-01

Reactivates a paused lead source so new leads enter again. If the system had paused it because its integration was disconnected, reactivating also recovers in the background the Meta or TikTok leads that arrived during the pause (Google and LinkedIn catch up on their next poll); those recovered leads enter like any other. A WhatsApp line has one active source: reactivating a WhatsApp source whose line got another active source meanwhile fails with 409 lead_source_exists. Idempotent. Requires manage_sources. 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 (the permissions guide lists what each platform allows).

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_reactivateOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.reactivate".

Declared cost: up to 3 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

Response

oktrue

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/reactivate" \
  -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/lead-sources/{source_id}/reactivate" \
  -H "Authorization: Bearer $MB_TEST_KEY"
POST/v1/crm/lead-sources/{source_id}/no-rule-recipients

Set who is notified of unassigned leads from a source

crm.lead_sources.update_no_rule_recipients

WriteIdempotentSince 2026-11-01

Chooses who gets the 'Lead received' notice (bell and email) for leads of this source that no assignment rule gives an owner: up to 10 people with access to the organization, never AI agents. An empty list goes back to the default, the account owner. Works on every source, including the system Manual source. Idempotent. Requires manage_sources.

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_update_no_rule_recipientsOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.update_no_rule_recipients".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

user_idsarray<string>bodyrequired

Up to 10 people with access to the organization (user ids from members.members.list or crm.team.list, never AI agents); empty goes back to the account owner.

Response

oktrue

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/no-rule-recipients" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "user_ids": [
    "USER_ID"
  ]
}'

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/lead-sources/{source_id}/no-rule-recipients" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "user_ids": [
    "USER_ID"
  ]
}'
POST/v1/crm/lead-sources/{source_id}/returning-contact

Set whether a returning contact opens new business

crm.lead_sources.update_returning_contact

WriteIdempotentSince 2026-11-01

Turns on or off 'every returning contact is new business' for a source: when on, a contact with closed history (a won or lost deal, an archived prospect) who comes back through this source opens a new prospect instead of returning to the closed record; open records are reused as always. Off is the default behavior. Works on every source, including the system Manual source. Idempotent. Requires manage_sources.

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_update_returning_contactOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.update_returning_contact".

Declared cost: up to 1 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The lead source's id, from crm.lead_sources.list.

enabledbooleanbodyrequired

true: a returning contact with closed history opens a new prospect.

Response

oktrue

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/returning-contact" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "enabled": true
}'

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/lead-sources/{source_id}/returning-contact" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "enabled": true
}'
POST/v1/crm/lead-sources/bulk/ai-qualification

Turn AI scoring on or off for several lead sources

crm.lead_sources.bulk.update_ai_qualification

WriteBulk · up to 100IdempotentSince 2026-11-01

Turns automatic AI scoring on or off for up to 100 lead sources at once: with it off, the AI qualification of new and re-scored leads skips those sources (the manual Recalculate button still works). Works on system sources too. Ids that are not sources of the organization are skipped and returned in not_found_ids. Outside the app it runs as a dry run first and needs the confirm_token. Requires manage_sources.

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: manage_sources
MCP tool
crm_lead_sources_bulk_update_ai_qualificationOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.bulk.update_ai_qualification".

Declared cost: up to 100 reads and 100 writes per call (they count against the daily quota).

Parameters

source_idsarray<string>bodyrequired

Up to 100 source ids from crm.lead_sources.list.

enabledbooleanbodyrequired

true turns AI scoring on (it consumes AI credits per lead), false off.

Response

updatednumber
not_found_idsarray<string>

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/bulk/ai-qualification" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "source_ids": [
    "SOURCE_ID"
  ],
  "enabled": true,
  "dry_run": true
}'

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/lead-sources/bulk/ai-qualification" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "source_ids": [
    "SOURCE_ID"
  ],
  "enabled": true,
  "dry_run": true
}'
POST/v1/crm/lead-sources/whatsapp

Create a WhatsApp lead source on a connected line

crm.lead_sources.create_whatsapp

WriteSince 2026-11-01

Creates the lead source of a WhatsApp line that is already connected (from crm.whatsapp.lines.available): every new chat on that number enters the CRM as a lead with the source's destination (prospect inbox or a pipeline deal), default pipeline, stage and labels, dedup strategy (merge, create_activity, notify, skip) and AI scoring. The pipeline, stage and labels must exist (a deal source needs its pipeline; without a stage, its first one). AI scoring of each lead consumes AI credits and stays off unless ai_qualification.enabled is sent true. It does not touch Meta: the line already brings its WhatsApp Business account and its webhook. Only CRM lines (409 whatsapp_line_not_crm), subscribed ones (409 whatsapp_line_not_subscribed) and one active source per line (409 lead_source_exists, details.lead_source_id). 404 external_account_not_linked when the line does not exist here. Delete it with crm.lead_sources.delete (the line keeps working for Messages, the Setter and the other modules that use it). Requires manage_sources.

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_create_whatsappOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.create_whatsapp".

Declared cost: up to 2 reads and 1 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

The source's name, up to 200 characters.

whatsapp_line_idstringbodyrequired

The WhatsApp line (its phone number id), from crm.whatsapp.lines.available: it must be a CRM line already connected and without another active source.

destinationenumbodyrequired

Where each lead goes: prospect (the prospects inbox) or deal (a deal in default_pipeline_id).

Values: deal, prospect

deduplicationenumbodyoptional

What happens when the person already exists: merge (update them and add the lead), create_activity (only log it), notify (log it and notify the owner) or skip (discard it).

Values: merge, create_activity, notify, skip · Default: "merge"

default_pipeline_idstringbodyoptional

Pipeline where the source's deals are created (crm.pipelines.list); required when destination is deal.

default_stage_idstringbodyoptional

Stage of that pipeline for new deals (crm.pipelines.get); default: its first stage.

default_label_idsarray<string>bodyoptional

Labels put on each new deal or prospect, up to 20: ids from crm.labels.list with the entity of the destination (deal or prospect).

Default: []

ai_qualificationobjectbodyoptional

AI scoring of the source's leads.

Default: {"enabled":false}

Response

idstring
source_idstring

The same id (every creation of a source returns both).

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/whatsapp" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "whatsapp_line_id": "WHATSAPP_LINE_ID",
  "destination": "deal"
}'

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/lead-sources/whatsapp" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "whatsapp_line_id": "WHATSAPP_LINE_ID",
  "destination": "deal"
}'
POST/v1/crm/lead-sources/social-dm

Create a lead source from social DMs

crm.lead_sources.create_social_dm

WriteSince 2026-11-01

Creates a lead source fed by direct messages of Social Inbox accounts of one platform (instagram, facebook for Messenger, tiktok): with dm_ingest_mode all, every new DM conversation from now on enters the CRM as a lead; with rules_only, only the ones the Social Inbox rules send. The lead follows the source's destination (prospect inbox or a pipeline deal), default pipeline and stage, dedup strategy and AI scoring (it consumes AI credits per lead). The pipeline, stage and labels must exist (a deal source needs its pipeline; without a stage, its first one). account_ids are the Social Inbox accounts of that platform (404 external_account_not_linked, details.platform, when one is not connected there). Requires manage_sources and edit access to the Social Inbox (and, with a key or an app, the social_inbox:write scope too).

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_create_social_dmOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.create_social_dm".

Declared cost: up to 6 reads and 1 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

The source's name (only spaces: the default name of the platform's DM source).

account_idsarray<string>bodyrequired

The Social Inbox accounts of that platform whose DMs feed the source (connected in the Social Inbox).

dm_ingest_modeenumbodyrequired

all: every new DM conversation enters as a lead (from the moment it is turned on); rules_only: only the ones the Social Inbox rules send.

Values: all, rules_only

destinationenumbodyrequired

Where each lead goes: prospect (the prospects inbox) or deal (a deal in default_pipeline_id).

Values: deal, prospect

deduplicationenumbodyrequired

What happens when the person already exists: merge (update them and add the lead), create_activity (only log it), notify (log it and notify the owner) or skip (discard it).

Values: merge, create_activity, notify, skip

ai_qualificationobjectbodyrequired

AI scoring of the source's leads.

platformenumbodyrequired

instagram, facebook (Messenger) or tiktok.

Values: instagram, facebook, tiktok

default_pipeline_idstringbodyoptional

Pipeline where the source's deals are created (crm.pipelines.list); required when destination is deal.

default_stage_idstringbodyoptional

Stage of that pipeline for new deals (crm.pipelines.get); default: its first stage.

Response

idstring
source_idstring

The same id (every creation of a source returns both).

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/social-dm" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "account_ids": [
    "ACCOUNT_ID"
  ],
  "dm_ingest_mode": "all",
  "destination": "deal",
  "deduplication": "merge",
  "ai_qualification": {},
  "platform": "instagram"
}'

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/lead-sources/social-dm" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "account_ids": [
    "ACCOUNT_ID"
  ],
  "dm_ingest_mode": "all",
  "destination": "deal",
  "deduplication": "merge",
  "ai_qualification": {},
  "platform": "instagram"
}'
PATCH/v1/crm/lead-sources/{source_id}/social-dm

Update a social DM lead source

crm.lead_sources.update_social_dm

WriteIdempotentSince 2026-11-01

Updates a DM lead source: its Social Inbox accounts, ingest mode, destination, default pipeline and stage, dedup strategy and AI scoring (send them all, as the source's dialog does). The pipeline, stage and labels must exist (a deal source needs its pipeline; without a stage, its first one). The platform does not change. Switching to dm_ingest_mode all for the first time sets the point from which conversations enter; later changes never re-import older ones. The system DM sources keep their name. 404 lead_source_not_found for a source that is not a DM source of this organization. Requires manage_sources and edit access to the Social Inbox (and, with a key or an app, the social_inbox:write scope too).

Scope
crm:write
Permission
Edit in the module · CRM action: manage_sources
MCP tool
crm_lead_sources_update_social_dmOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.update_social_dm".

Declared cost: up to 7 reads and 1 writes per call (they count against the daily quota).

Parameters

source_idstringpathrequired

The DM lead source's id, from crm.lead_sources.list (types instagram_dm, facebook_dm, tiktok_dm).

namestringbodyrequired

The source's name (only spaces: the default name of the platform's DM source).

account_idsarray<string>bodyrequired

The Social Inbox accounts of that platform whose DMs feed the source (connected in the Social Inbox).

dm_ingest_modeenumbodyrequired

all: every new DM conversation enters as a lead (from the moment it is turned on); rules_only: only the ones the Social Inbox rules send.

Values: all, rules_only

destinationenumbodyrequired

Where each lead goes: prospect (the prospects inbox) or deal (a deal in default_pipeline_id).

Values: deal, prospect

deduplicationenumbodyrequired

What happens when the person already exists: merge (update them and add the lead), create_activity (only log it), notify (log it and notify the owner) or skip (discard it).

Values: merge, create_activity, notify, skip

ai_qualificationobjectbodyrequired

AI scoring of the source's leads.

default_pipeline_idstringbodyoptional

Pipeline where the source's deals are created (crm.pipelines.list); required when destination is deal.

default_stage_idstringbodyoptional

Stage of that pipeline for new deals (crm.pipelines.get); default: its first stage.

Response

oktrue

Errors

Example

curl -X PATCH "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/social-dm" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "NAME",
  "account_ids": [
    "ACCOUNT_ID"
  ],
  "dm_ingest_mode": "all",
  "destination": "deal",
  "deduplication": "merge",
  "ai_qualification": {}
}'

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 PATCH "https://api.mb-suite.com/v1/crm/lead-sources/{source_id}/social-dm" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "NAME",
  "account_ids": [
    "ACCOUNT_ID"
  ],
  "dm_ingest_mode": "all",
  "destination": "deal",
  "deduplication": "merge",
  "ai_qualification": {}
}'
POST/v1/crm/lead-sources/booking

Create a lead source from a person's bookings

crm.lead_sources.create_booking

WriteSince 2026-11-01

Creates the lead source of a person's public booking page: each confirmed booking of that person (of one event type, event_type_id, or of all of them with all_event_types, also the ones published later) enters the CRM as a lead with the source's destination, default pipeline, stage and labels, field mapping of the booking form, dedup strategy and AI scoring; with use_assignment_rules the assignment rules choose the owner, otherwise it goes to that person. The pipeline, stage and labels must exist (a deal source needs its pipeline; without a stage, its first one). AI scoring of each lead consumes AI credits and stays off unless ai_qualification.enabled is sent true. Returns the id as source_id and id. One active source per event type and one all-event-types source per person (409 lead_source_exists). Errors: 400 event_type_required, 404 vendor_not_found (vendor_user_id is not a person of this organization), 404 event_type_not_found, 400 event_type_not_of_vendor. Requires full access to the CRM (manage_sources is not needed: a seller sets up the source of their own booking page).

Scope
crm:write
Permission
Edit in the module
MCP tool
crm_lead_sources_create_bookingOn the full surface; on the compact one, mb_execute_operation with id: "crm.lead_sources.create_booking".

Declared cost: up to 52 reads and 1 writes per call (they count against the daily quota).

Parameters

namestringbodyrequired

The source's name, up to 200 characters.

vendor_user_idstringbodyrequired

The person whose booking page this source binds (a member of the organization: crm.booking.settings.list).

destinationenumbodyrequired

Where each lead goes: prospect (the prospects inbox) or deal (a deal in default_pipeline_id).

Values: deal, prospect

event_type_idstringbodyoptional

One of that person's event types (crm.booking.event_types.list); omit it and send all_event_types true to cover all of them, also future ones.

all_event_typesbooleanbodyoptional

true: every event type of the person, also the ones published later (then omit event_type_id).

Default: false

use_assignment_rulesbooleanbodyoptional

true: the lead is assigned by the assignment rules; false: to the person whose booking it is.

Default: false

deduplicationenumbodyoptional

What happens when the person already exists: merge (update them and add the lead), create_activity (only log it), notify (log it and notify the owner) or skip (discard it).

Values: merge, create_activity, notify, skip · Default: "merge"

default_pipeline_idstringbodyoptional

Pipeline where the source's deals are created (crm.pipelines.list); required when destination is deal.

default_stage_idstringbodyoptional

Stage of that pipeline for new deals (crm.pipelines.get); default: its first stage.

default_label_idsarray<string>bodyoptional

Labels put on each new deal or prospect, up to 20: ids from crm.labels.list with the entity of the destination (deal or prospect).

Default: []

field_mappingarray<object>bodyoptional

How each question of the booking form maps to a CRM field (external_field = the question key; crm_field as in crm.lead_sources.create).

Default: []

ai_qualificationobjectbodyoptional

AI scoring of the source's leads.

Default: {"enabled":false}

Response

source_idstring
idstring

The same id (every creation of a source returns both).

Errors

Example

curl -X POST "https://api.mb-suite.com/v1/crm/lead-sources/booking" \
  -H "Authorization: Bearer $MB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "vendor_user_id": "VENDOR_USER_ID",
  "destination": "deal"
}'

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/lead-sources/booking" \
  -H "Authorization: Bearer $MB_TEST_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "NAME",
  "vendor_user_id": "VENDOR_USER_ID",
  "destination": "deal"
}'