Docs
Campaigns

Change a campaign's basics or settings

PATCHhttps://api.norreach.app/v1/campaigns/{id}

name and brand_id change on drafts only (a live campaign is cloned to change). settings (a sparse override — only the keys you send change) can change on drafts, live and paused campaigns. Letting sends go out without approval (approve_before_send auto) or Nora answer replies on her own (reply_autonomously true) needs the nora:autonomy scope; asking for more approval never does.

campaigns:writeRole must allow: campaigns.editOperation id: update_campaign
PATCH/campaigns/{id}
curl -X PATCH "https://api.norreach.app/v1/campaigns/{id}" \
  -H "Authorization: Bearer $NORREACH_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "settings": {
    "approve_before_send": "manual"
  }
}'
Change a campaign's basics or settings
{
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "object": "campaign",
  "name": "Summer nurses — Stockholm",
  "status": "draft",
  "kind": "sequence",
  "channels": [
    "email",
    "sms"
  ],
  "step_count": 2,
  "brand_id": null,
  "schedule_at": null,
  "created_at": "2026-11-04T09:12:33.120Z",
  "steps": [
    {
      "channel": "email",
      "wait_hours": 0,
      "template": "Subject: Nurses for the summer\n\nHi {{first_name}}, …"
    },
    {
      "channel": "sms",
      "wait_hours": 48,
      "template": "Hi {{first_name}}, did you see my email?"
    }
  ],
  "rules": [
    {
      "name": "Stop on reply",
      "when": {
        "event": "replied"
      },
      "then": {
        "action": "pause"
      }
    }
  ],
  "settings": {
    "approve_before_send": "manual"
  },
  "stats": {
    "enrolled": 120,
    "in_progress": 80,
    "paused": 4,
    "completed": 20,
    "replied": 14,
    "meetings_booked": 2,
    "sent": 210,
    "delivered": 204,
    "opened": 96,
    "clicked": 12
  }
}

Authorizations

Authorizationstringheaderrequired

Bearer authentication: send Authorization: Bearer <key>, with an API key or an OAuth access token. The key needs the scope campaigns:write. API keys and scopes

Path parameters

idstring (uuid)pathrequired

An id (UUID).

Headers

Idempotency-Keystringheader

Any unique string (≤ 255). The same key with the same request returns the first answer for 24 hours.

Body

application/json

namestring
brand_idstring (uuid) | null
settingsobject

Campaign settings (a sparse override of the workspace's defaults).

Show child attributes
settings.approve_before_sendenum

manual = every send waits for a person's yes. Setting auto needs the nora:autonomy scope.

One of:automanual
settings.reply_autonomouslyboolean

Nora answers replies on her own. Setting true needs the nora:autonomy scope.

settings.unsubscribeany

Unsubscribe link settings.

settings.unsubscribe_modeany

How opting out works.

settings.unsubscribe_phraseany

The opt-out wording.

settings.reengageany

Re-engagement settings.

settings.follow_up_threadany

Send follow-ups in the same email thread.

settings.prioritizeany

new, followups or both.

settings.ooo_pauseany

Pause a contact who is out of office.

settings.sendingany

Sending window and pacing.

settings.reply_handlingany

What happens when a contact replies.

settings.leads_per_dayany

New contacts started per day.

settings.prospects_per_monthany

Prospects per month.

settings.pause_on_replyany

Stop the sequence for a contact who replies.

settings.exit_on_call_connectedany

Stop the sequence for a contact once an AI call connects.

settings.call_on_intentany

Place an AI call when a contact shows intent.

settings.deliverabilityany

Deliverability settings.

settings.exclusionsany

Who is skipped at enrollment (recency_days, per_company_cap).

settings.enforce_sending_windowany

Only send inside the sending window.

settings.messagingany

Message writing preferences.

settings.schedule_atstring (date-time)

A scheduled start (launching then waits until this time).

Response

200application/json— Change a campaign's basics or settings

idstring (uuid)required

An id (UUID).

object"campaign"required
namestringrequired
statusstringrequired

draft, active, paused, completed, archived or needs_review.

kindenumrequired
One of:broadcastsequencemultichannel
channelsstring[]required

The channel mix of the sequence, in order.

step_countintegerrequired
brand_idstring (uuid) | nullrequired
schedule_atstring | nullrequired
created_atstringrequired

RFC 3339 UTC timestamp with milliseconds.

stepsobject[]required

The sequence (the step shape above).

rulesobject[]required
settingsobjectrequired

The campaign's own settings override.

statsobjectrequired

The campaign's numbers right now.

Show child attributes
stats.enrolledintegerrequired
stats.in_progressintegerrequired
stats.pausedintegerrequired
stats.completedintegerrequired
stats.repliedintegerrequired
stats.meetings_bookedintegerrequired
stats.sentintegerrequired
stats.deliveredintegerrequired
stats.openedintegerrequired
stats.clickedintegerrequired

Errors

Errors are application/problem+json with a stable code.

StatusCodeMeaning
400bad_requestThe request couldn't be read.
400unknown_fieldThe request has a field this operation doesn't know.
401unauthorizedA valid API key is required.
403insufficient_scopeThis API key doesn't have the scope this operation needs.
403feature_not_enabledThe API isn't switched on for this workspace.
403role_forbiddenThe key's creator's role can't do this.
404not_foundThat doesn't exist.
409idempotency_in_progressA request with this Idempotency-Key is still running.
409conflictThat conflicts with the current state.
413too_largeThe request body is too large.
422validation_failedThe request has invalid fields.
422idempotency_mismatchThis Idempotency-Key was used with a different request.
429rate_limitedToo many requests. Slow down and try again.
500server_errorSomething went wrong on our side.
503unavailableThe API isn't available right now. Try again shortly.