REST endpoints for campaigns in ServFlo: 21 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication ); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id .
GET /organizations/{organizationId}/marketing/campaigns
Email and text broadcasts, newest first, with status and (once started) results. Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool campaigns_list (toolset marketing)
Name In Type Required Description statusquery enum No One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. businessUnitIdquery string No Only this business unit (GET /business-units), or "none" for records without one. Up to 100 characters. limitquery integer No 1–200. offsetquery integer No
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description totalinteger itemsarray of object items[].idstring items[].namestring items[].statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. items[].channelsarray of enum items[].audienceobject items[].segmentobject or null items[].segment.idstring items[].segment.namestring items[].businessUnitIdstring or null The business unit it is for; null = the whole business. items[].emailSubjectstring or null items[].emailPreheaderstring or null items[].emailBodystring or null items[].smsBodystring or null items[].scheduleModeenum One of NOW, AT, LOCAL_TIME. items[].scheduledAtstring (date-time) or null items[].localDatestring or null items[].localTimestring or null items[].attributionWindowDaysinteger items[].utmCampaignstring or null utm_campaign on its links (fixed when it starts). items[].trackLinksboolean items[].audienceCountinteger Customers in the frozen audience (when started). items[].snapshotCompleteboolean items[].startedAtstring (date-time) or null items[].completedAtstring (date-time) or null items[].pausedAtstring (date-time) or null items[].cancelledAtstring (date-time) or null items[].duplicatedFromIdstring or null items[].createdAtstring (date-time) items[].updatedAtstring (date-time) items[].problemsarray of string What is missing before it can be sent. items[].countsobject or null Results; null for a campaign never started. items[].counts.recipientsinteger Customer × channel rows in the frozen audience. items[].counts.pendinginteger Waiting for their send time. items[].counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. items[].counts.sentinteger Handed to the provider (or logged in test mode). items[].counts.deliveredinteger items[].counts.testModeinteger Logged in test mode (no provider): counted in sent. items[].counts.openedinteger Where the email provider reports opens. items[].counts.clickedinteger Where the email provider reports clicks. items[].counts.bouncedinteger items[].counts.failedinteger items[].counts.skippedinteger Refused by consent, suppression, missing address … items[].counts.cancelledinteger items[].counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. items[].counts.byChannelobject items[].counts.skippedReasonsarray of object
POST /organizations/{organizationId}/marketing/campaigns
Saves a DRAFT campaign (nothing is sent). Preview it with POST /marketing/campaigns/preview, test it with …/test, then send or schedule it with …/send. Always marketing: only customers who agreed to marketing get it.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_create (toolset marketing)
Field Type Required Description namestring Yes Up to 200 characters. channelsarray of enum Yes EMAIL and/or SMS. Each channel reaches the customers whose consent allows it. Up to 2 items. audienceobject Yes { kind: FILTERS, filters } (the audience builder), { kind: SEGMENT, segmentId } or { kind: MANUAL, customerIds }. emailSubjectstring or null No Up to 200 characters. emailPreheaderstring or null No The inbox preview line after the subject. Up to 200 characters. emailBodystring or null No Plain text or HTML with {{merge.fields}}; goes in the branded email with the unsubscribe footer. smsBodystring or null No With {{merge.fields}}; "Reply STOP to opt out." is added. Up to 1600 characters. scheduleModeenum No NOW when sent; AT scheduledAt; LOCAL_TIME: localDate at localTime in each recipient's timezone (from their state). One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null No localDatestring or null No localTimestring or null No attributionWindowDaysinteger No Days after it reaches someone during which their requests, bookings and payments count (default 30). 1–365. trackLinksboolean No Add UTM tags to links (default on). businessUnitIdstring or null No The business unit the campaign is for (GET /business-units), for reporting by unit; null = the whole business. Does not narrow the audience. Up to 100 characters.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","channels":["EMAIL"],"audience":{"kind":"FILTERS"}}'
201: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
GET /organizations/{organizationId}/marketing/campaigns/{campaignId}
One campaign: content, audience, schedule, status and results (sent, delivered, opened, clicked, bounced, unsubscribed, skipped with reasons). Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool campaigns_get (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
PATCH /organizations/{organizationId}/marketing/campaigns/{campaignId}
Changes the fields sent, on a DRAFT or SCHEDULED campaign (a scheduled one goes back to DRAFT and must be sent or scheduled again). 409 once sending: duplicate it instead.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_update (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description namestring No Up to 200 characters. channelsarray of enum No EMAIL and/or SMS. Each channel reaches the customers whose consent allows it. Up to 2 items. audienceobject No { kind: FILTERS, filters } (the audience builder), { kind: SEGMENT, segmentId } or { kind: MANUAL, customerIds }. emailSubjectstring or null No Up to 200 characters. emailPreheaderstring or null No The inbox preview line after the subject. Up to 200 characters. emailBodystring or null No Plain text or HTML with {{merge.fields}}; goes in the branded email with the unsubscribe footer. smsBodystring or null No With {{merge.fields}}; "Reply STOP to opt out." is added. Up to 1600 characters. scheduleModeenum No NOW when sent; AT scheduledAt; LOCAL_TIME: localDate at localTime in each recipient's timezone (from their state). One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null No localDatestring or null No localTimestring or null No attributionWindowDaysinteger No Days after it reaches someone during which their requests, bookings and payments count (default 30). 1–365. trackLinksboolean No Add UTM tags to links (default on). businessUnitIdstring or null No The business unit the campaign is for (GET /business-units), for reporting by unit; null = the whole business. Does not narrow the audience. Up to 100 characters.
curl -X PATCH "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","channels":["EMAIL"],"audience":{"kind":"FILTERS"}}'
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
DELETE /organizations/{organizationId}/marketing/campaigns/{campaignId}
Destructive: deletes a DRAFT or CANCELLED campaign (its messages stay in the message log). A sent campaign keeps its results and cannot be deleted (409).
Permission marketing.manage (Owner, Admin)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool campaigns_delete (toolset marketing)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description oktrue
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/duplicate
A new DRAFT with the same content, audience and settings ("Copy of …"). Nothing is sent.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_duplicate (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/duplicate" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
201: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
POST /organizations/{organizationId}/marketing/campaigns/preview
Renders the email (branded, with the unsubscribe footer) and the text (with the opt-out line) for a sample customer of the audience, with the audience's live count and reach by consent, and the text's segments and cost against this month's allowance. Nothing is sent or saved.
Permission marketing.read (Owner, Admin, Dispatcher)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_preview (toolset marketing)
Field Type Required Description namestring No Up to 200 characters. channelsarray of enum Yes EMAIL and/or SMS. Each channel reaches the customers whose consent allows it. Up to 2 items. audienceobject Yes { kind: FILTERS, filters } (the audience builder), { kind: SEGMENT, segmentId } or { kind: MANUAL, customerIds }. emailSubjectstring or null No Up to 200 characters. emailPreheaderstring or null No The inbox preview line after the subject. Up to 200 characters. emailBodystring or null No Plain text or HTML with {{merge.fields}}; goes in the branded email with the unsubscribe footer. smsBodystring or null No With {{merge.fields}}; "Reply STOP to opt out." is added. Up to 1600 characters. scheduleModeenum No NOW when sent; AT scheduledAt; LOCAL_TIME: localDate at localTime in each recipient's timezone (from their state). One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null No localDatestring or null No localTimestring or null No attributionWindowDaysinteger No Days after it reaches someone during which their requests, bookings and payments count (default 30). 1–365. trackLinksboolean No Add UTM tags to links (default on). businessUnitIdstring or null No The business unit the campaign is for (GET /business-units), for reporting by unit; null = the whole business. Does not narrow the audience. Up to 100 characters. campaignIdstring No The campaign being edited (its id goes in utm_content).
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/preview" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"channels":["EMAIL"],"audience":{"kind":"FILTERS"}}'
200: the answer's fields Field Type Description sampleCustomerobject or null sampleCustomer.idstring sampleCustomer.namestring emailobject or null email.subjectstring or null email.bodystring email.htmlstring or null email.unresolvedarray of string email.blockingarray of string smsobject or null sms.subjectstring or null sms.bodystring sms.htmlstring or null sms.unresolvedarray of string sms.blockingarray of string audienceobject audience.totalinteger Customers in the audience (archived and do-not-service never are). audience.checkedinteger Customers whose consent was checked one by one. audience.estimatedboolean Reach scaled from the first customers checked (very large audiences). audience.reachableobject audience.reachable.EMAILinteger audience.reachable.SMSinteger audience.reachable.anyinteger audience.unreachablearray of object audience.unreachable[].reasonstring audience.unreachable[].textstring audience.unreachable[].countinteger audience.samplearray of object audience.sample[].customerIdstring audience.sample[].namestring audience.sample[].emailobject audience.sample[].smsobject smsEstimateobject or null smsEstimate.segmentsPerTextinteger smsEstimate.encodingenum One of GSM-7, UCS-2. smsEstimate.charactersinteger smsEstimate.recipientsinteger smsEstimate.totalSegmentsinteger smsEstimate.allowanceRemaininginteger or null smsEstimate.overageSegmentsinteger smsEstimate.overageCentsinteger
POST /organizations/{organizationId}/marketing/audience/preview
The audience builder's live count: how many customers match (archived and do-not-service never do), how many consent lets you email or text for marketing, why the others cannot be reached, and a sample. Nothing is saved.
Permission marketing.read (Owner, Admin, Dispatcher)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_audience (toolset marketing)
Field Type Required Description audienceobject Yes { kind: FILTERS, filters } (the audience builder), { kind: SEGMENT, segmentId } or { kind: MANUAL, customerIds }. channelsarray of enum No EMAIL and/or SMS. Each channel reaches the customers whose consent allows it. Up to 2 items. Default ["EMAIL"]. sampleSizeinteger No 1–100.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/audience/preview" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"audience":{"kind":"FILTERS"}}'
200: the answer's fields Field Type Description totalinteger Customers in the audience (archived and do-not-service never are). checkedinteger Customers whose consent was checked one by one. estimatedboolean Reach scaled from the first customers checked (very large audiences). reachableobject reachable.EMAILinteger reachable.SMSinteger reachable.anyinteger unreachablearray of object unreachable[].reasonstring unreachable[].textstring unreachable[].countinteger samplearray of object sample[].customerIdstring sample[].namestring sample[].emailobject sample[].email.okboolean sample[].email.reasonstring or null sample[].smsobject sample[].sms.okboolean sample[].sms.reasonstring or null
POST /organizations/{organizationId}/marketing/campaigns/draft
Claude writes the email (subject, preheader, body) and the text from your goal, with merge fields, inventing no prices or offers you did not give. Uses AI credits (402 when none are left). source says AI or TEMPLATE (AI off). Nothing is saved: put the answer in the campaign.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_draft (toolset marketing)
Field Type Required Description goalstring Yes What the campaign is for: "Spring AC tune-up, $89 for members until May 31". Up to 1000 characters. channelsarray of enum Yes EMAIL and/or SMS. Each channel reaches the customers whose consent allows it. Up to 2 items. toneenum No One of friendly, professional, urgent.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/draft" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"goal":"string","channels":["EMAIL"]}'
200: the answer's fields Field Type Description emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null sourceenum One of AI, FAKE, TEMPLATE.
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/test
Sends the campaign marked "[Test]" to your own email (default: your account's) and/or phone, rendered for a sample customer of the audience. Logged as TEST; never counted in results; no customer gets it.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_test (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description emailempty string or string (email) or null No Where to send the test email; default your account's email. phonestring or null No Where to send the test text (the campaign must have one). Up to 40 characters. nowstring (date-time) No Tests only: act as of this moment (ISO 8601). Refused when NODE_ENV=production.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/test" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"email":"dana@example.com","phone":"+15555550123","now":"2026-11-03T15:00:00Z"}'
200: the answer's fields An array of objects:
Field Type Description idstring channelenum One of EMAIL, SMS. statusstring statusReasonstring or null toAddressstring or null subjectstring or null
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/send
Customer-visible: sends the DRAFT now, or schedules it (its scheduleMode). The audience is frozen; each customer gets it once per channel, only when marketing consent allows (opted in, not unsubscribed, not suppressed, OK to text for texts), with the unsubscribe footer or STOP line, held by quiet hours. Large audiences go out in pages. Preview and test it first.
Permission marketing.manage (Owner, Admin)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool campaigns_send (toolset marketing)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description nowstring (date-time) No Tests only: act as of this moment (ISO 8601). Refused when NODE_ENV=production.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/send" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"now":"2026-11-03T15:00:00Z"}'
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/pause
Stops a scheduled or sending campaign: nothing new is queued and messages held (quiet hours) are withdrawn. Messages already handed to the provider are not recalled. Resume with …/resume.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_pause (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description nowstring (date-time) No Tests only: act as of this moment (ISO 8601). Refused when NODE_ENV=production.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/pause" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"now":"2026-11-03T15:00:00Z"}'
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/resume
Customer-visible: a paused campaign continues where it stopped; nobody gets it twice.
Permission marketing.manage (Owner, Admin)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool campaigns_resume (toolset marketing)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description nowstring (date-time) No Tests only: act as of this moment (ISO 8601). Refused when NODE_ENV=production.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/resume" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"now":"2026-11-03T15:00:00Z"}'
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
POST /organizations/{organizationId}/marketing/campaigns/{campaignId}/cancel
Ends a scheduled, sending or paused campaign for good: the rest of the audience never gets it. Results so far are kept.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool campaigns_cancel (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
Field Type Required Description nowstring (date-time) No Tests only: act as of this moment (ISO 8601). Refused when NODE_ENV=production.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/cancel" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"now":"2026-11-03T15:00:00Z"}'
200: the answer's fields Field Type Description idstring namestring statusenum One of DRAFT, SCHEDULED, SENDING, PAUSED, SENT, CANCELLED. channelsarray of enum audienceobject segmentobject or null segment.idstring segment.namestring businessUnitIdstring or null The business unit it is for; null = the whole business. emailSubjectstring or null emailPreheaderstring or null emailBodystring or null smsBodystring or null scheduleModeenum One of NOW, AT, LOCAL_TIME. scheduledAtstring (date-time) or null localDatestring or null localTimestring or null attributionWindowDaysinteger utmCampaignstring or null utm_campaign on its links (fixed when it starts). trackLinksboolean audienceCountinteger Customers in the frozen audience (when started). snapshotCompleteboolean startedAtstring (date-time) or null completedAtstring (date-time) or null pausedAtstring (date-time) or null cancelledAtstring (date-time) or null duplicatedFromIdstring or null createdAtstring (date-time) updatedAtstring (date-time) problemsarray of string What is missing before it can be sent. countsobject or null Results; null for a campaign never started. counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger
GET /organizations/{organizationId}/marketing/campaigns/{campaignId}/recipients
Who is in the frozen audience, per channel: when it goes, what became of it (queued, skipped with the reason, sent, opened, clicked). Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool campaigns_recipients (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns. statusquery enum No One of PENDING, QUEUED, SKIPPED, FAILED, CANCELLED. channelquery enum No One of EMAIL, SMS. limitquery integer No 1–200. offsetquery integer No
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/recipients" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description totalinteger itemsarray of object items[].idstring items[].customerIdstring items[].customerNamestring items[].channelenum One of EMAIL, SMS. items[].statusstring items[].reasonstring or null items[].sendAtstring (date-time) items[].timeZonestring or null items[].messageIdstring or null items[].messageStatusstring or null items[].sentAtstring (date-time) or null items[].openedAtstring (date-time) or null items[].clickedAtstring (date-time) or null
GET /organizations/{organizationId}/marketing/campaigns/{campaignId}/results
Delivery and engagement counts, plus attribution: requests, bookings, approved quotes and paid invoices (with revenue) by recipients within the attribution window after it reached them, and requests carrying its UTM tags. Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool campaigns_results (toolset marketing)
Name In Type Required Description campaignIdpath string Yes A campaign id, from GET /marketing/campaigns.
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/campaigns/{campaignId}/results" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description countsobject counts.recipientsinteger Customer × channel rows in the frozen audience. counts.pendinginteger Waiting for their send time. counts.queuedinteger Queued or held by quiet hours, not handed to the provider yet. counts.sentinteger Handed to the provider (or logged in test mode). counts.deliveredinteger counts.testModeinteger Logged in test mode (no provider): counted in sent. counts.openedinteger Where the email provider reports opens. counts.clickedinteger Where the email provider reports clicks. counts.bouncedinteger counts.failedinteger counts.skippedinteger Refused by consent, suppression, missing address … counts.cancelledinteger counts.unsubscribedinteger Opted out of marketing (link, STOP, complaint) after it reached them. counts.byChannelobject counts.byChannel.EMAILobject counts.byChannel.SMSobject counts.skippedReasonsarray of object counts.skippedReasons[].reasonstring counts.skippedReasons[].countinteger attributionobject attribution.windowDaysinteger attribution.utmCampaignstring or null attribution.reachedinteger Customers it reached (sent, delivered or logged in test mode). attribution.requestsinteger attribution.bookingsinteger Jobs created for recipients in the window. attribution.quotesApprovedinteger attribution.invoicesPaidinteger attribution.revenueCentsinteger Total of the invoices recipients paid in the window.
GET /organizations/{organizationId}/marketing/segments
Saved audiences (named sets of audience-builder filters) for campaigns, by name. Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool segments_list (toolset marketing)
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/segments" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields An array of objects:
Field Type Description idstring namestring descriptionstring or null filtersobject filters.tagsAnyarray of string Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum Up to 2 items. filters.zipsarray of string Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string Up to 100 items. filters.lastServiceWithinDaysinteger Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger 0–100000000. filters.lifetimeValueMaxCentsinteger 0–100000000. filters.behavioursarray of string Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string Up to 30 items. filters.equipmentMinAgeYearsinteger 0–100. filters.leadSourceIdsarray of string Up to 50 items. createdAtstring (date-time) updatedAtstring (date-time)
POST /organizations/{organizationId}/marketing/segments
Saves audience filters under a name, for campaigns (the filters are applied when a campaign starts, so the segment stays current).
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool segments_create (toolset marketing)
Field Type Required Description namestring Yes Up to 120 characters. descriptionstring or null No Up to 500 characters. filtersobject Yes The audience builder's filters: tags, customer type, ZIPs and cities, last service, membership, lifetime value, Customer 360 behaviours and predictions (service due, likely replacement, at risk), equipment type and age, lead sources. filters.tagsAnyarray of string No Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string No Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum No Up to 2 items. filters.zipsarray of string No Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string No Up to 100 items. filters.lastServiceWithinDaysinteger No Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum No Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger No 0–100000000. filters.lifetimeValueMaxCentsinteger No 0–100000000. filters.behavioursarray of string No Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger No Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum No Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean No Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string No Up to 30 items. filters.equipmentMinAgeYearsinteger No 0–100. filters.leadSourceIdsarray of string No Up to 50 items.
curl -X POST "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/segments" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","filters":{"tagsAny":["string"],"tagsNone":["string"],"customerTypes":["RESIDENTIAL"]}}'
201: the answer's fields Field Type Description idstring namestring descriptionstring or null filtersobject filters.tagsAnyarray of string Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum Up to 2 items. filters.zipsarray of string Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string Up to 100 items. filters.lastServiceWithinDaysinteger Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger 0–100000000. filters.lifetimeValueMaxCentsinteger 0–100000000. filters.behavioursarray of string Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string Up to 30 items. filters.equipmentMinAgeYearsinteger 0–100. filters.leadSourceIdsarray of string Up to 50 items. createdAtstring (date-time) updatedAtstring (date-time)
GET /organizations/{organizationId}/marketing/segments/{segmentId}
One saved audience: its name, description and audience-builder filters. Read-only.
Permission marketing.read (Owner, Admin, Dispatcher)Risk read, OAuth scope servflo.read. Read: reads only.MCP tool segments_get (toolset marketing)
Name In Type Required Description segmentIdpath string Yes A saved segment id, from GET /marketing/segments.
curl "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/segments/{segmentId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description idstring namestring descriptionstring or null filtersobject filters.tagsAnyarray of string Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum Up to 2 items. filters.zipsarray of string Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string Up to 100 items. filters.lastServiceWithinDaysinteger Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger 0–100000000. filters.lifetimeValueMaxCentsinteger 0–100000000. filters.behavioursarray of string Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string Up to 30 items. filters.equipmentMinAgeYearsinteger 0–100. filters.leadSourceIdsarray of string Up to 50 items. createdAtstring (date-time) updatedAtstring (date-time)
PATCH /organizations/{organizationId}/marketing/segments/{segmentId}
Replaces its name, description and filters.
Permission marketing.manage (Owner, Admin)Risk write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.MCP tool segments_update (toolset marketing)
Name In Type Required Description segmentIdpath string Yes A saved segment id, from GET /marketing/segments.
Field Type Required Description namestring Yes Up to 120 characters. descriptionstring or null No Up to 500 characters. filtersobject Yes The audience builder's filters: tags, customer type, ZIPs and cities, last service, membership, lifetime value, Customer 360 behaviours and predictions (service due, likely replacement, at risk), equipment type and age, lead sources. filters.tagsAnyarray of string No Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string No Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum No Up to 2 items. filters.zipsarray of string No Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string No Up to 100 items. filters.lastServiceWithinDaysinteger No Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum No Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger No 0–100000000. filters.lifetimeValueMaxCentsinteger No 0–100000000. filters.behavioursarray of string No Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger No Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum No Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean No Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string No Up to 30 items. filters.equipmentMinAgeYearsinteger No 0–100. filters.leadSourceIdsarray of string No Up to 50 items.
curl -X PATCH "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/segments/{segmentId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY " \
-H "Content-Type: application/json" \
-d '{"name":"Dana Whitfield","filters":{"tagsAny":["string"],"tagsNone":["string"],"customerTypes":["RESIDENTIAL"]}}'
200: the answer's fields Field Type Description idstring namestring descriptionstring or null filtersobject filters.tagsAnyarray of string Customers with at least one of these tags. Up to 50 items. filters.tagsNonearray of string Leave out customers with any of these tags. Up to 50 items. filters.customerTypesarray of enum Up to 2 items. filters.zipsarray of string Service area: a property (or the billing address) in one of these ZIP codes. Up to 500 items. filters.citiesarray of string Up to 100 items. filters.lastServiceWithinDaysinteger Had a completed visit in the last N days. 1–3650. filters.lastServiceOlderThanDaysinteger No completed visit in the last N days (includes customers never serviced). 1–3650. filters.membershipenum Active: an active membership; NONE: never had one; LAPSED: had one, none active now. One of ACTIVE, NONE, LAPSED.filters.lifetimeValueMinCentsinteger 0–100000000. filters.lifetimeValueMaxCentsinteger 0–100000000. filters.behavioursarray of string Customer 360 behaviours, all of them (BOOKS_ONLINE, PAYS_ON_TIME, MEMBER …). Up to 20 items. filters.serviceDueWithinDaysinteger Customer 360: next service predicted due within N days (overdue included). 0–365. filters.likelyReplacementenum Customer 360: equipment replacement likelihood at least this level. One of HIGH, MEDIUM. filters.atRiskboolean Customer 360: health AT_RISK or a HIGH lapse risk. filters.equipmentTypesarray of string Up to 30 items. filters.equipmentMinAgeYearsinteger 0–100. filters.leadSourceIdsarray of string Up to 50 items. createdAtstring (date-time) updatedAtstring (date-time)
DELETE /organizations/{organizationId}/marketing/segments/{segmentId}
Destructive: deletes a saved audience. 409 while a running campaign uses it.
Permission marketing.manage (Owner, Admin)Risk sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.MCP tool segments_delete (toolset marketing)Approval Over MCP, this tool always waits for your approval in ServFlo. See Approvals .
Name In Type Required Description segmentIdpath string Yes A saved segment id, from GET /marketing/segments.
curl -X DELETE "https://app.servflo.ai/api/organizations/ $ORGANIZATION_ID /marketing/segments/{segmentId}" \
-H "Authorization: Bearer $SERVFLO_API_KEY "
200: the answer's fields Field Type Description oktrue