CampaignsUpdate campaign

Update campaign

Update campaign name, sequence, schedule, settings, or mailbox assignments. Mailboxes can be reassigned using any combination of mailboxIds, mailboxEmails, mailboxTags, or mailboxProvider.

Variant identity. Variant stats are keyed on each variant's _id, so an edit keeps it:

  • A variant sent back with its _id (as returned by GET /v1/campaigns/{campaignId}) keeps it, even if it moved to another step of the same sequence. Sending back the variantId of an entry in deletedVariants restores that variant. Ids that do not belong to this sequence/subsequence (another campaign, another subsequence, malformed) are ignored.
  • A variant sent without _id keeps the _id of the existing variant with the same label in the same step. Steps are matched by step _id when sent, otherwise by content, otherwise by position among email steps — wait steps and order renumbering do not matter.
  • Anything else is a new variant with a new _id.
  • Variants missing from the new sequence are recorded in deletedVariants, so their stats stay labelled ("C · deleted") after the letter is reused. Removing variant C and adding a new C to the same step in one request is treated as an edit of C (same _id); to start a fresh C, remove it in one request and add it in a later one.
  • A kept variant keeps its optimizer state (enabled, status, pausedAt, pausedReason).
curl -X PATCH "https://api.sendkit.ai/v1/campaigns/example_string" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -d '{
  "name": "Q1 Outreach Campaign (Updated)",
  "schedule": {
    "startTime": "10:00",
    "endTime": "18:00",
    "skipNationalHolidays": false
  },
  "settings": {
    "stopOnAutoReply": false,
    "dailySendLimit": 100,
    "espMatchingMode": "auto",
    "segCheckMode": "skip_providers",
    "segSkipProviders": [
      "proofpoint",
      "mimecast",
      "barracuda"
    ],
    "webhook": {
      "enabled": true,
      "events": [
        "lead.replied",
        "email.opened"
      ]
    },
    "variantOptimization": {
      "enabled": true,
      "optimizationMetric": "openRate",
      "minimumSendsPerVariant": 100
    },
    "bounceMonitoring": {
      "advanced": true,
      "criticalBounceRate": 7
    }
  }
}'
{
  "success": true,
  "data": {
    "_id": "665a1b2c3d4e5f6a7b8c9d0e",
    "name": "Q1 Outreach Campaign (Updated)",
    "status": "draft",
    "sendingSchedule": {
      "timezone": "America/New_York",
      "startTime": "08:00",
      "endTime": "18:00",
      "workingDays": [
        1,
        2,
        3,
        4,
        5
      ]
    },
    "createdAt": "2025-06-10T10:30:00.000Z",
    "updatedAt": "2025-06-12T08:00:00.000Z"
  }
}
PATCH
/v1/campaigns/{campaignId}
PATCH
Base URLstring

Target server for requests. Edit to use your own host.

API Key (header: X-Api-Key)
X-Api-Keystring
Required

Platform API key (sk_user_...) or Workspace API key (sk_...)

Platform API key (sk_user_...) or Workspace API key (sk_...)
Content-Typestring
Required

The media type of the request body

Options: application/json
namestring

Campaign name

sequencearray

Replace the entire email sequence. Variants keep their _id (and stats) across the edit — see the endpoint description.

subsequencesarray

REPLACES the entire subsequences array on the campaign — to preserve existing subsequences across edits, fetch the campaign first, modify the array, and submit it back (each subsequence keeps its _id / id to retain identity and avoid orphaning leads enrolled in it). Same validation rules apply as on POST: max 15 active (non-archived) subsequences per campaign; at most one active subsequence may have trigger.type='reply'; active ai_tag-trigger values must be unique (case-insensitive); inner sequence may start with a wait (subseq-only relaxation); trigger is immutable once a subsequence has sent any emails — attempting to change it returns 400 TRIGGER_IMMUTABLE (archive and create a new one instead).

scheduleobject

Update sending schedule (merged into existing)

settingsobject

All settings are optional and merge into existing values

Request Preview
Response

Response will appear here after sending the request

Authentication

header
X-Api-Keystring
Required

API Key for authentication. Platform API key (sk_user_...) or Workspace API key (sk_...)

Path Parameters

Body

application/json
namestring

Campaign name

sequencearray

Replace the entire email sequence. Variants keep their _id (and stats) across the edit — see the endpoint description.

subsequencesarray

REPLACES the entire subsequences array on the campaign — to preserve existing subsequences across edits, fetch the campaign first, modify the array, and submit it back (each subsequence keeps its _id / id to retain identity and avoid orphaning leads enrolled in it). Same validation rules apply as on POST: max 15 active (non-archived) subsequences per campaign; at most one active subsequence may have trigger.type='reply'; active ai_tag-trigger values must be unique (case-insensitive); inner sequence may start with a wait (subseq-only relaxation); trigger is immutable once a subsequence has sent any emails — attempting to change it returns 400 TRIGGER_IMMUTABLE (archive and create a new one instead).

scheduleobject

Update sending schedule (merged into existing)

settingsobject

All settings are optional and merge into existing values

Responses

successboolean
dataobject