Update Agent Config
Update agent configuration for an organization.
Expects the full AgentConfig from the frontend.
Path parameters
Request body
Whether the org runs a membership/service-plan program. When False, membership context (has_active_membership, membership_analysis) is withheld from every SMS-agent LLM stage and the answerability gate. Shared with the re-engagement pipeline's membership suppression. Also the backstop that strips membership classifications from open-estimate intents when False — such orgs create no real membership estimates, so anything membership-classified is a ServiceTitan warranty/service-agreement rider misread as membership.
Whether to inject the synthetic NEW-membership opportunity intent into current-objective candidates for eligible non-member customers. ORed with membership_renewal_pitch_enabled it also gates membership sell-signal generation. Injection only — real membership estimates flow as normal products regardless (offers_memberships owns the classification backstop). Replaces the hardcoded MEMBERSHIP_OPPORTUNITY_ORG_IDS / MEMBERSHIP_SELLING_ORG_IDS allowlists.
Whether to inject the synthetic membership-RENEWAL opportunity intent for members whose plan is expiring soon. ORed with new_membership_pitch_enabled for sell-signal generation.
Local-hour send time (0-23) for outbound reengagement messages.
Days a sales-classified job is deferred after completion before its first re-engagement touch. 0 (default) disables the deferment.
Time window (in seconds) to group consecutive customer messages. If customer sends multiple messages within this window, they will be processed together as a single conversation turn. Set to 0 to disable grouping. Max 300 seconds (5 minutes).
When enabled, the per-conversation agent toggle is automatically disabled whenever a real (non-AI) user sends a message in that conversation.
When True, campaign LLM auto-responds to inbound SMS immediately. When False (shadow mode), responses are logged to campaign_responder_shadow_events but NOT sent.
When True, the campaign brain may create real ServiceTitan jobs via book_appointment for any campaign, using campaigns.config.booking_defaults (business_unit_id + job_type_id) and a verified two-hour arrival window. When False (default), a customer who agrees to schedule is escalated to the office instead.
Org-wide ServiceTitan business unit for campaign bookings. Used when a campaign has no booking_defaults.business_unit_id, so manual campaigns can book without per-campaign setup.
Org-wide ServiceTitan job type for campaign bookings. Falls back the same way as campaign_booking_business_unit_id.
Org-wide ServiceTitan campaign that booked jobs attribute to. ServiceTitan makes campaignId mandatory on job creation, so without this (or a per-campaign override) a ready-to-book customer is escalated instead.
Display name of campaign_booking_st_campaign_id. Reports-lane orgs need it until a job has been booked against the campaign: the reports feed only learns names from Jobs rows, and Pilot picks the campaign by name.
ServiceTitan dispatch team ids whose technicians count as campaign booking capacity. When set, availability is reconstructed from the real board (appointments + assignments + non-job time off for these teams' techs over business hours) instead of the capacity API, which only reflects ST's capacity-planning module and reads as permanently full for tenants that do not maintain it.
When True, escalate_to_backoffice(resend_estimate|resend_invoice) auto-sends the document. Stage 2/3 are skipped and the SMS agent dispatches a send_job_email WorkflowRequest to Pilot over SQS (the ServiceTitan browser automation now runs in Pilot, not inline). The Pilot results worker sends the customer confirmation SMS on completion, or flips the conversation to require_action + agent disabled on failure (or if Pilot never answers within the deadline). resend_other does NOT auto-send and runs the normal CSR-escalation path. (Flag name retained for config compatibility; the mechanism is now Pilot, not inline Playwright.)
When True (default), conversion_assist(accept_full_estimate) uses the self-service path — the SMS points the customer to the accept link in the estimate email. When False, the org does NOT include a self-service accept link in estimate emails; the customer's SMS YES is treated as the commitment and the path flips to office_handoff (office confirms + starts scheduling, email notification fires, conversation goes to require_action). voice_card stays accept_full_estimate; Stage 3 renders a no-link sub-card.
When True, manual lost transitions may dismiss open ServiceTitan estimates and the SMS agent does so for chose_competitor or work_completed.
When True, every escalation notifies BOTH the office (email, normal subtype routing) and the conversation's assigned technician (push). Excludes escalate_to_technician tech_work_question/tech_said_question, which stay technician-only.
When True the org is switched to the followup agent v3: inbound SMS routes to the v3 queue (event_type inbound_sms_v3) instead of the v2 SMS agent, and the nightly reengagement v2 pipeline skips this org entirely (v3's own planner owns its proactive cadence). Cutover runbook: cancel the org's pending reengagement_v2 rows when flipping this on. Rollback is flipping it back — v2 resumes on its next nightly run.
When True, v2 keeps running unchanged and every inbound SMS event is ALSO mirrored to the v3 queue with shadow=true. v3 runs its full pipeline (state, brain, lint, action queue, dispatcher) but suppresses all external side effects — intended messages land in followup_agent_v3_decision_logs for the M2 parity diff. Ignored when followup_agent_v3_enabled is True.
v3 only. When True the compliance gate appends the carrier-approved opt-out line to the first proactive message of a cold thread. Default False: the visible 'Reply STOP' instruction is the loudest bot tell and v3 threads are one-to-one conversational messages; opt-outs in ANY wording are honored at the gate layer regardless of this flag.
v3 only. How fast this org's office can turn around a revised estimate (repair-only / good-better-best resize). Drives the agent's wording (same_day → 'this afternoon', within_48h → 'in the next day or two') and gates the rework play entirely when unsupported. Rework requests escalate with the dedicated estimate_rework subtype.
Master switch for the Aspire email-followup pipeline.
Outlook-native: the orchestrator drives first-touch cards + reply drafts + tags inside the rep's own Outlook mailbox.
Allow due Ongoing Aspire conversations to create Outlook review drafts.
Aspire DivisionNames ingested as followups.
Go-live backfill window for currently-Delivered opps.
Target local send hour for outbound touches.
[earliest, latest] local hour; slots outside roll forward.
Default review gap when an Ongoing thread goes quiet this long.
First review falls this many days after the proposal email's SentDate (or the delivered date when it was never sent).
Extra send-as addresses that count as the org's own senders (mailbox aliases not present in email_integrations).
Company domains whose senders count as the org's own side (e.g. send-as alias domains); never customer mail.
Response
Successful Response
Whether the org runs a membership/service-plan program. When False, membership context (has_active_membership, membership_analysis) is withheld from every SMS-agent LLM stage and the answerability gate. Shared with the re-engagement pipeline's membership suppression. Also the backstop that strips membership classifications from open-estimate intents when False — such orgs create no real membership estimates, so anything membership-classified is a ServiceTitan warranty/service-agreement rider misread as membership.
Whether to inject the synthetic NEW-membership opportunity intent into current-objective candidates for eligible non-member customers. ORed with membership_renewal_pitch_enabled it also gates membership sell-signal generation. Injection only — real membership estimates flow as normal products regardless (offers_memberships owns the classification backstop). Replaces the hardcoded MEMBERSHIP_OPPORTUNITY_ORG_IDS / MEMBERSHIP_SELLING_ORG_IDS allowlists.
Whether to inject the synthetic membership-RENEWAL opportunity intent for members whose plan is expiring soon. ORed with new_membership_pitch_enabled for sell-signal generation.
Local-hour send time (0-23) for outbound reengagement messages.
Days a sales-classified job is deferred after completion before its first re-engagement touch. 0 (default) disables the deferment.
Time window (in seconds) to group consecutive customer messages. If customer sends multiple messages within this window, they will be processed together as a single conversation turn. Set to 0 to disable grouping. Max 300 seconds (5 minutes).
When enabled, the per-conversation agent toggle is automatically disabled whenever a real (non-AI) user sends a message in that conversation.
When True, campaign LLM auto-responds to inbound SMS immediately. When False (shadow mode), responses are logged to campaign_responder_shadow_events but NOT sent.
When True, the campaign brain may create real ServiceTitan jobs via book_appointment for any campaign, using campaigns.config.booking_defaults (business_unit_id + job_type_id) and a verified two-hour arrival window. When False (default), a customer who agrees to schedule is escalated to the office instead.
Org-wide ServiceTitan business unit for campaign bookings. Used when a campaign has no booking_defaults.business_unit_id, so manual campaigns can book without per-campaign setup.
Org-wide ServiceTitan job type for campaign bookings. Falls back the same way as campaign_booking_business_unit_id.
Org-wide ServiceTitan campaign that booked jobs attribute to. ServiceTitan makes campaignId mandatory on job creation, so without this (or a per-campaign override) a ready-to-book customer is escalated instead.
Display name of campaign_booking_st_campaign_id. Reports-lane orgs need it until a job has been booked against the campaign: the reports feed only learns names from Jobs rows, and Pilot picks the campaign by name.
ServiceTitan dispatch team ids whose technicians count as campaign booking capacity. When set, availability is reconstructed from the real board (appointments + assignments + non-job time off for these teams' techs over business hours) instead of the capacity API, which only reflects ST's capacity-planning module and reads as permanently full for tenants that do not maintain it.
When True, escalate_to_backoffice(resend_estimate|resend_invoice) auto-sends the document. Stage 2/3 are skipped and the SMS agent dispatches a send_job_email WorkflowRequest to Pilot over SQS (the ServiceTitan browser automation now runs in Pilot, not inline). The Pilot results worker sends the customer confirmation SMS on completion, or flips the conversation to require_action + agent disabled on failure (or if Pilot never answers within the deadline). resend_other does NOT auto-send and runs the normal CSR-escalation path. (Flag name retained for config compatibility; the mechanism is now Pilot, not inline Playwright.)
When True (default), conversion_assist(accept_full_estimate) uses the self-service path — the SMS points the customer to the accept link in the estimate email. When False, the org does NOT include a self-service accept link in estimate emails; the customer's SMS YES is treated as the commitment and the path flips to office_handoff (office confirms + starts scheduling, email notification fires, conversation goes to require_action). voice_card stays accept_full_estimate; Stage 3 renders a no-link sub-card.
When True, manual lost transitions may dismiss open ServiceTitan estimates and the SMS agent does so for chose_competitor or work_completed.
When True, every escalation notifies BOTH the office (email, normal subtype routing) and the conversation's assigned technician (push). Excludes escalate_to_technician tech_work_question/tech_said_question, which stay technician-only.
When True the org is switched to the followup agent v3: inbound SMS routes to the v3 queue (event_type inbound_sms_v3) instead of the v2 SMS agent, and the nightly reengagement v2 pipeline skips this org entirely (v3's own planner owns its proactive cadence). Cutover runbook: cancel the org's pending reengagement_v2 rows when flipping this on. Rollback is flipping it back — v2 resumes on its next nightly run.
When True, v2 keeps running unchanged and every inbound SMS event is ALSO mirrored to the v3 queue with shadow=true. v3 runs its full pipeline (state, brain, lint, action queue, dispatcher) but suppresses all external side effects — intended messages land in followup_agent_v3_decision_logs for the M2 parity diff. Ignored when followup_agent_v3_enabled is True.
v3 only. When True the compliance gate appends the carrier-approved opt-out line to the first proactive message of a cold thread. Default False: the visible 'Reply STOP' instruction is the loudest bot tell and v3 threads are one-to-one conversational messages; opt-outs in ANY wording are honored at the gate layer regardless of this flag.
v3 only. How fast this org's office can turn around a revised estimate (repair-only / good-better-best resize). Drives the agent's wording (same_day → 'this afternoon', within_48h → 'in the next day or two') and gates the rework play entirely when unsupported. Rework requests escalate with the dedicated estimate_rework subtype.
Master switch for the Aspire email-followup pipeline.
Outlook-native: the orchestrator drives first-touch cards + reply drafts + tags inside the rep's own Outlook mailbox.
Allow due Ongoing Aspire conversations to create Outlook review drafts.
Aspire DivisionNames ingested as followups.
Go-live backfill window for currently-Delivered opps.
Target local send hour for outbound touches.
[earliest, latest] local hour; slots outside roll forward.
Default review gap when an Ongoing thread goes quiet this long.
First review falls this many days after the proposal email's SentDate (or the delivered date when it was never sent).
Extra send-as addresses that count as the org's own senders (mailbox aliases not present in email_integrations).
Company domains whose senders count as the org's own side (e.g. send-as alias domains); never customer mail.
Changes
Changed in 1 of the 4 revisions of this API.○2
- ○
added the new optional request property
new-optional-request-property
- ○
added the optional property
to the response with the statusresponse-optional-property-added
- ○