Skip to main content

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.

Endpoint

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

FieldTypeRequiredDescription
instanceIdUUIDyesTechnical identifier of the MsgFlash instance, obtained via GET /api/v1/instances
namestringyesNom interne
scheduleISO 8601yesDate de démarrage
repeatstringnonoe, daily, weekly
recipientsobjectyesRecipient selector
templateIdUUIDyes si mode templateTemplate used
variablesobjectnoVariables custom.* globales
typeenumyes si mode directtext, image, video, audio, document, voice_note, buttons
bodystringdepends on typeObligatoire pour text, optionnel pour certains medias
mediaUrlstringdepends on typeObligatoire pour les types media
titlestringif buttonsButton message title
descriptionstringif buttonsButton message description
footerstringnoButton message footer
buttonsarrayif buttonsList 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

FieldTypeRequiredDescription
typeenumyesall, tags, explicit, group
valuestring[]depends on typeTags ou IDs de contacts
groupIdUUIDif type=groupTarget 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

HTTPCodeWhen
400VALIDATION_ERROREmpty campaign, missing body, missing media, invalid recipients
403CAMPAIGNS_NOT_AVAILABLE_ON_PLANPlan trop faible
403UNSUPPORTED_FEATUREUnsupported feature (buttons without WhatsApp Business)
404NOT_FOUNDInstance 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!"
  }'

Campaign with buttons

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"
      }
    ]
  }'