update_campaign
Modify email campaign settings like sequences, tracking, and sending limits with partial updates to optimize outreach performance.
Instructions
Update campaign settings (partial update).
Common updates:
name: Campaign display name
sequences: Email sequence steps
email_list: Sender account assignments
daily_limit: Max emails per day per account
email_gap: Minutes between sends
open_tracking, link_tracking: Tracking toggles
Only include fields you want to update.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Implementation Reference
- The core handler function that implements the update_campaign tool. It constructs a partial update body from the input parameters and sends a PATCH request to the Instantly API endpoint /campaigns/{campaign_id}.async def update_campaign(params: UpdateCampaignInput) -> str: """ Update campaign settings (partial update). Common updates: - name: Campaign display name - sequences: Email sequence steps - email_list: Sender account assignments - daily_limit: Max emails per day per account - email_gap: Minutes between sends - open_tracking, link_tracking: Tracking toggles Only include fields you want to update. """ client = get_client() body = {} # Add all optional fields if provided if params.name is not None: body["name"] = params.name if params.pl_value is not None: body["pl_value"] = params.pl_value if params.is_evergreen is not None: body["is_evergreen"] = params.is_evergreen if params.campaign_schedule is not None: body["campaign_schedule"] = params.campaign_schedule if params.sequences is not None: body["sequences"] = params.sequences if params.email_gap is not None: body["email_gap"] = params.email_gap if params.random_wait_max is not None: body["random_wait_max"] = params.random_wait_max if params.text_only is not None: body["text_only"] = params.text_only if params.email_list is not None: body["email_list"] = params.email_list if params.daily_limit is not None: body["daily_limit"] = params.daily_limit if params.stop_on_reply is not None: body["stop_on_reply"] = params.stop_on_reply if params.email_tag_list is not None: body["email_tag_list"] = params.email_tag_list if params.link_tracking is not None: body["link_tracking"] = params.link_tracking if params.open_tracking is not None: body["open_tracking"] = params.open_tracking if params.stop_on_auto_reply is not None: body["stop_on_auto_reply"] = params.stop_on_auto_reply if params.daily_max_leads is not None: body["daily_max_leads"] = params.daily_max_leads if params.prioritize_new_leads is not None: body["prioritize_new_leads"] = params.prioritize_new_leads if params.auto_variant_select is not None: body["auto_variant_select"] = params.auto_variant_select if params.match_lead_esp is not None: body["match_lead_esp"] = params.match_lead_esp if params.stop_for_company is not None: body["stop_for_company"] = params.stop_for_company if params.insert_unsubscribe_header is not None: body["insert_unsubscribe_header"] = params.insert_unsubscribe_header if params.allow_risky_contacts is not None: body["allow_risky_contacts"] = params.allow_risky_contacts if params.disable_bounce_protect is not None: body["disable_bounce_protect"] = params.disable_bounce_protect if params.cc_list is not None: body["cc_list"] = params.cc_list if params.bcc_list is not None: body["bcc_list"] = params.bcc_list result = await client.patch(f"/campaigns/{params.campaign_id}", json=body) return json.dumps(result, indent=2)
- Pydantic model defining the input schema for the update_campaign tool, including all optional fields for partial updates.class UpdateCampaignInput(BaseModel): """ Input for updating campaign settings (partial update). Common updates: name, sequences, tracking, limits, email_list. """ model_config = ConfigDict(str_strip_whitespace=True, extra="ignore") campaign_id: str = Field(..., description="Campaign to update") name: Optional[str] = Field(default=None) pl_value: Optional[float] = Field(default=None, description="Pipeline value") is_evergreen: Optional[bool] = Field(default=None) campaign_schedule: Optional[dict[str, Any]] = Field( default=None, description="Schedule configuration with 'schedules' array" ) sequences: Optional[list[dict[str, Any]]] = Field( default=None, description="Email sequence steps" ) email_gap: Optional[int] = Field(default=None, ge=1, le=1440) random_wait_max: Optional[int] = Field(default=None) text_only: Optional[bool] = Field(default=None) email_list: Optional[list[str]] = Field(default=None, description="Sender accounts") daily_limit: Optional[int] = Field(default=None, ge=1, le=50) stop_on_reply: Optional[bool] = Field(default=None) email_tag_list: Optional[list[str]] = Field(default=None) link_tracking: Optional[bool] = Field(default=None) open_tracking: Optional[bool] = Field(default=None) stop_on_auto_reply: Optional[bool] = Field(default=None) daily_max_leads: Optional[int] = Field(default=None) prioritize_new_leads: Optional[bool] = Field(default=None) auto_variant_select: Optional[dict[str, Any]] = Field(default=None) match_lead_esp: Optional[bool] = Field(default=None) stop_for_company: Optional[bool] = Field(default=None) insert_unsubscribe_header: Optional[bool] = Field(default=None) allow_risky_contacts: Optional[bool] = Field(default=None) disable_bounce_protect: Optional[bool] = Field(default=None) cc_list: Optional[list[str]] = Field(default=None) bcc_list: Optional[list[str]] = Field(default=None)
- src/instantly_mcp/tools/campaigns.py:517-526 (registration)List of campaign tools including update_campaign, which is imported and registered by the server via get_all_tools().CAMPAIGN_TOOLS = [ create_campaign, list_campaigns, get_campaign, update_campaign, activate_campaign, pause_campaign, delete_campaign, search_campaigns_by_contact, ]
- src/instantly_mcp/server.py:80-80 (registration)MCP annotation for the update_campaign tool specifying destructiveHint: False, applied during registration."update_campaign": {"destructiveHint": False},