---
title: "Create a campaign"
method: POST
path: "/v1/campaigns"
tags: ["Campaigns"]
---

# Create a campaign

`POST /v1/campaigns`

## Request

- Base URL: `https://api.volanea.com`
- URL: `https://api.volanea.com/v1/campaigns`
- Auth: HTTP bearer

Created in `draft`. Audience is everyone (`all`), a segment (`segment` + `segmentId`), or ad-hoc conditions (`filter`).

## Request body

- object
  - `name` string, required
  - `subject` string, required
  - `previewText` string, nullable: Preheader — the preview line after the subject in the inbox. Supports `{{variable}}` placeholders.
  - `body` string, required: HTML with `{{variable}}` placeholders.
  - `bodyBlocks` union: Optional design the visual editor compiled `body` from — a JSON string of the GrapesJS project (or a legacy block array/object). Stored verbatim and never sent.
    - string
    - object
  - `fromEmail` string, email, required
  - `fromName` string
  - `replyTo` string, email, nullable: Sets the Reply-To header on every send.
  - `audience` 'all' | 'segment' | 'filter'
  - `segmentId` string: Required when `audience` is `"segment"`.
  - `filter` SegmentConditions: Nested condition tree evaluated against contacts, their custom `data`, and their activity.
    - `logic` 'and' | 'or', required
    - `groups` object[], required
      - `filters` object[], required
        - `field` string, required: `email`, `subscribed`, `locale`, `createdAt`, `data.<key>`, `event.<name>`, `email.opened`, …
        - `operator` string, required: `equals`, `notEquals`, `contains`, `notContains`, `greaterThan`, `lessThan`, `exists`, `notExists`, `within`, `notWithin`, `triggered`, `notTriggered`, …
        - `value` union
          - string
          - number
          - boolean
        - `days` integer: Time window (days) for activity operators.
  - `abSubjectB` string: Subject-line B for an A/B experiment; the winner is auto-sent to the remainder.
  - `abSamplePct` integer: Percent of the audience used for the A/B sample (default 20).

## Response `201`

Created.

- Campaign
  - `campaignId` string, required
  - `projectId` string
  - `name` string, required
  - `subject` string, required
  - `previewText` string, nullable: Preheader — the preview line inboxes show after the subject. Injected as a hidden block at the top of the body at send time.
  - `body` string, required
  - `bodyBlocks` union: The visual editor's design `body` was compiled from — a JSON string of the GrapesJS project (or a legacy block array/object), stored so the editor can reopen it. Ignored when sending — only `body` is delivered.
    - string
    - object
  - `fromName` string, nullable
  - `fromEmail` string, email, required
  - `replyTo` string, email, nullable: Becomes the Reply-To header when set.
  - `status` 'draft' | 'scheduled' | 'sending' | 'sent' | 'cancelled', required
  - `audience` 'all' | 'segment' | 'filter', required
  - `segmentId` string, nullable
  - `filter` SegmentConditions: Nested condition tree evaluated against contacts, their custom `data`, and their activity.
    - `logic` 'and' | 'or', required
    - `groups` object[], required
      - `filters` object[], required
        - `field` string, required: `email`, `subscribed`, `locale`, `createdAt`, `data.<key>`, `event.<name>`, `email.opened`, …
        - `operator` string, required: `equals`, `notEquals`, `contains`, `notContains`, `greaterThan`, `lessThan`, `exists`, `notExists`, `within`, `notWithin`, `triggered`, `notTriggered`, …
        - `value` union
          - string
          - number
          - boolean
        - `days` integer: Time window (days) for activity operators.
  - `abSubjectB` string, nullable
  - `abSamplePct` integer, nullable
  - `abDecideAt` string, date-time, nullable
  - `abWinner` 'a' | 'b' | 'null', nullable
  - `scheduledFor` string, date-time, nullable
  - `sentAt` string, date-time, nullable
  - `totalRecipients` integer
  - `delivered` integer
  - `opened` integer
  - `clicked` integer
  - `bounced` integer
  - `complained` integer
  - `unsubscribed` integer
  - `createdAt` string, date-time, required

## Other responses

- `401`: Missing or invalid API key.
- `404`: Not found.
- `422`: Request validation failed (code `validation_error`, 422).

---

[API](https://skmtc.dev/volanea/apis/volanea-api.md) · [All operations](https://skmtc.dev/volanea/apis/volanea-api/llms.txt) · [OpenAPI document](https://skmtc.dev/volanea/apis/volanea-api/revisions/9e187ae84fda?raw)
