Endpoint
Important — how to get instanceId
instanceId is required to create a campaign.
To get it:
- call
GET /api/v1/instances
- choose an instance with
status = "connected" when possible
- copy
data[n].id
- send this value in
instanceId
Do not use these instead:
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
{
"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"
}
}
In V1, safety.decision is allow or warn. A warning does not prevent campaign creation.
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
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!"
}'
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"
}
]
}'