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

# Create Campaign

`POST /v1/campaigns`

Create a new email campaign from a generated email. Use emailId for the exact generated email, especially series slots. Requires API key with campaign:write.

## Request body

- CreateCampaignRequest
  - `projectId` string, required — Project ID
  - `name` string, required — Campaign name
  - `conversationId` string, required — Conversation ID that owns the generated email
  - `emailId` string — Generated email ID from result.emails[].emailId. Recommended for series slots.
  - `subject` string — Email subject (auto-populated from conversation if omitted)
  - `preheaderText` string — Preheader text
  - `from` string, email, required — Sender email address
  - `fromName` string, required — Sender display name
  - `replyTo` string, email — Reply-to address
  - `recipientType` 'audience' | 'tag', required — Send to a segment (audience) or tag
  - `recipientId` string, required — Segment or list ID. Required unless recipientIds is set. Ignored when recipientIds is present except as recipientIds[0] on the stored campaign.
  - `recipientIds` string[] — Send to several segments or several lists of the same type. Unique people receive one email. Cannot mix segments and lists. Maximum 20.
  - `topicId` string — Topic ID for preference filtering
  - `providerType` 'ses' | 'resend' | 'sendgrid' | 'mailgun' | 'migma' — Email provider (default: migma)
  - `variables` object — Template variables

## Response `200`

Campaign created

- ApiResponseCampaign
  - `success` boolean, required
  - `data` object, nullable
    - `id` string
    - `projectId` string
    - `name` string
    - `conversationId` string
    - `emailId` string, nullable — Generated email ID when the campaign was created from a specific email.
    - `subject` string
    - `preheaderText` string, nullable
    - `from` string, email
    - `fromName` string
    - `replyTo` string, nullable
    - `recipientType` 'audience' | 'tag'
    - `recipientId` string — First segment or list ID. Always equals recipientIds[0] when recipientIds is set.
    - `recipientIds` string[] — Segment or list IDs of the same type. Unique people across the selection receive one email. Omitted on single-recipient campaigns.
    - `topicId` string, nullable
    - `estimatedRecipients` integer, nullable
    - `providerType` 'ses' | 'resend' | 'sendgrid' | 'mailgun' | 'migma'
    - `variables` object, nullable
    - `status` 'draft' | 'pending_review' | 'scheduled' | 'sending' | 'throttled' | 'sent' | 'failed' | 'cancelled'
    - `scheduledAt` string, date-time, nullable
    - `scheduledTimezone` string, nullable
    - `batchId` string, nullable
    - `sentAt` string, date-time, nullable
    - `completedAt` string, date-time, nullable
    - `error` string, nullable
    - `triggeredBy` 'manual' | 'api' | 'automation'
    - `createdAt` string, date-time
    - `updatedAt` string, date-time
  - `error` string, nullable

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `403` — Forbidden - Missing required permissions or access denied

## Changes

- **2026-08-31** `6b3357db6cf6` — 2 info
  - added the new optional request property `recipientIds`
  - added the optional property `allOf[subschema #2]/data/recipientIds` to the response with the `200` status
- **2026-07-26** `3f3dba69574b` — 1 warning
  - added the new `pending_review` enum value to the `allOf[subschema #2]/data/status` response property for the response status `200`

[Change history](https://skmtc.dev/migma/apis/migma-ai-api-v1/changes/v1/campaigns/post.md)

---

[API](https://skmtc.dev/migma/apis/migma-ai-api-v1.md) · [All operations](https://skmtc.dev/migma/apis/migma-ai-api-v1/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/migma/migma-ai-api-v1/revisions/6b3357db6cf6/schema)
