> ## Documentation Index
> Fetch the complete documentation index at: https://docs.msgflash.com/llms.txt
> Use this file to discover all available pages before exploring further.

# POST Create a campaign

> Create and schedule a messaging campaign.

## Endpoint

```txt theme={null}
POST /api/v1/campaigns
```

## Important — how to get `instanceId`

`instanceId` is required to create a campaign.

To get it:

1. call `GET /api/v1/instances`
2. choose an instance with `status = "connected"` when possible
3. copy `data[n].id`
4. send this value in `instanceId`

Do not use these instead:

* `name`
* `waNumber`

## Body

| Field         | Type     | Required             | Description                                                                         |
| ------------- | -------- | -------------------- | ----------------------------------------------------------------------------------- |
| `instanceId`  | UUID     | yes                  | Technical identifier of the MsgFlash instance, obtained via `GET /api/v1/instances` |
| `name`        | string   | yes                  | Nom interne                                                                         |
| `schedule`    | ISO 8601 | yes                  | Date de démarrage                                                                   |
| `repeat`      | string   | no                   | `noe`, `daily`, `weekly`                                                            |
| `recipients`  | object   | yes                  | Recipient selector                                                                  |
| `templateId`  | UUID     | yes si mode template | Template used                                                                       |
| `variables`   | object   | no                   | Variables `custom.*` globales                                                       |
| `type`        | enum     | yes si mode direct   | `text`, `image`, `video`, `audio`, `document`, `voice_note`, `buttons`              |
| `body`        | string   | depends on type      | Obligatoire pour `text`, optionnel pour certains medias                             |
| `mediaUrl`    | string   | depends on type      | Obligatoire pour les types media                                                    |
| `title`       | string   | if `buttons`         | Button message title                                                                |
| `description` | string   | if `buttons`         | Button message description                                                          |
| `footer`      | string   | no                   | Button message footer                                                               |
| `buttons`     | array    | if `buttons`         | List of buttons (max 2)                                                             |

## Content rule

A campaign must have exactly one content mode:

* soit `templateId`
* soit `type` + contenu direct

Ne pas envoyer les deux en même temps.

### `recipients`

| Field     | Type      | Required        | Description                        |
| --------- | --------- | --------------- | ---------------------------------- |
| `type`    | enum      | yes             | `all`, `tags`, `explicit`, `group` |
| `value`   | string\[] | depends on type | Tags ou IDs de contacts            |
| `groupId` | UUID      | if `type=group` | Target group                       |

## Success response `201`

```json theme={null}
{
  "data": {
    "id": "cmp_uuid",
    "userId": "user_uuid",
    "instanceId": "inst_uuid",
    "name": "April Newsletter",
    "status": "scheduled",
    "templateId": "tmpl_uuid",
    "type": null,
    "body": null,
    "mediaUrl": null,
    "schedule": "2026-04-15T09:00:00.000Z",
    "repeat": "noe",
    "recipients": {
      "type": "all"
    },
    "stats": {
      "planned": 0,
      "queued": 0,
      "sent": 0,
      "delivered": 0,
      "read": 0,
      "failed": 0,
      "cancelled": 0
    },
    "safety": {
      "decision": "warn",
      "riskLevel": "medium",
      "score": 56,
      "state": "warming",
      "reasons": [
        "This instance is still warming up and campaign pacing should stay gradual."
      ],
      "recommendations": [
        "Start with previously engaged contacts before scaling volume."
      ],
      "appliedLimits": {
        "maxCampaignRecipients": 100,
        "maxColdRatio": 0.4
      },
      "audience": {
        "totalRecipients": 120,
        "coldRatio": 0.625
      }
    },
    "createdAt": "2026-04-10T09:00:00.000Z",
    "updatedAt": "2026-04-10T09:00:00.000Z"
  }
}
```

<Note>
  In V1, `safety.decision` is `allow` or `warn`. A warning does not prevent campaign creation.
</Note>

## Common errors

| HTTP  | Code                              | When                                                            |
| ----- | --------------------------------- | --------------------------------------------------------------- |
| `400` | `VALIDATION_ERROR`                | Empty campaign, missing body, missing media, invalid recipients |
| `403` | `CAMPAIGNS_NOT_AVAILABLE_ON_PLAN` | Plan trop faible                                                |
| `403` | `UNSUPPORTED_FEATURE`             | Unsupported feature (buttons without WhatsApp Business)         |
| `404` | `NOT_FOUND`                       | Instance ou template not found                                  |

## Examples

### Simple text campaign

```bash theme={null}
curl -X POST https://srv.msgflash.com/api/v1/campaigns \
  -H "x-api-key: msgf_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceId": "INSTANCE_UUID",
    "name": "April Newsletter",
    "schedule": "2026-04-15T09:00:00.000Z",
    "recipients": {
      "type": "all"
    },
    "type": "text",
    "body": "Discover our latest offers!"
  }'
```

### Campaign with buttons

```bash theme={null}
curl -X POST https://srv.msgflash.com/api/v1/campaigns \
  -H "x-api-key: msgf_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceId": "INSTANCE_UUID",
    "name": "Satisfaction survey",
    "schedule": "2026-04-15T10:00:00.000Z",
    "recipients": {
      "type": "tags",
      "value": ["client"]
    },
    "type": "buttons",
    "title": "Your opinion matters!",
    "description": "Are you satisfied with our services?",
    "footer": "Reply before tomorrow",
    "buttons": [
      {
        "type": "reply",
        "displayText": "Very satisfied",
        "id": "satisfied"
      },
      {
        "type": "reply",
        "displayText": "Needs improvement",
        "id": "needs_improvement"
      }
    ]
  }'
```
