Endpoint
POST /api/v1/messages/send
Authentication: x-api-key: <api_key>
The message is accepted as queued, then sent asynchronously.
From the MsgFlash dashboard, media can be prepared through a temporary upload before final sending. See Temporary media uploads.
Parameters
Body
| Field | Type | Required | Description |
|---|
instanceId | UUID | yes | Source WhatsApp instance |
to | string | yes | E.164 number |
type | enum | yes if no templateId | Direct message type |
templateId | UUID | yes if no type | MsgFlash template to use |
text | string | depends on type | Direct message body |
mediaUrl | string | depends on type | Public media URL |
latitude | number | if type=location | Latitude |
longitude | number | if type=location | Longitude |
locationName | string | no | Location name |
locationAddress | string | no | Location address |
contactId | UUID | no | Shared contact or template context |
variables | object | no | Values injected into custom.* |
This route has no path or query parameters.
Mode 1 — Direct message
Texte
curl -X POST https://srv.msgflash.com/api/v1/messages/send \
-H "x-api-key: msgf_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "text",
"text": "Hello, your order is ready."
}'
Image
Vidéo
Audio
Note vocale
Document
Localisation
Contact
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "image",
"mediaUrl": "https://cdn.example.com/banner.jpg",
"text": "Nouvelle collection"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "video",
"mediaUrl": "https://cdn.example.com/promo.mp4"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "audio",
"mediaUrl": "https://cdn.example.com/message.mp3"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "voice_note",
"mediaUrl": "https://cdn.example.com/note.ogg"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "document",
"mediaUrl": "https://cdn.example.com/facture.pdf",
"text": "Votre facture"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "location",
"latitude": 6.3654,
"longitude": 2.4183,
"locationName": "Boutique Cotonou Centre",
"locationAddress": "Avenue de la Marina, Cotonou"
}
{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"type": "contact",
"contactId": "CONTACT_UUID"
}
Mode 2 — Send via template
You can send a message by providing templateId instead of type.
curl -X POST https://srv.msgflash.com/api/v1/messages/send \
-H "x-api-key: msgf_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"instanceId": "YOUR_INSTANCE_ID",
"to": "+33612345678",
"contactId": "CONTACT_UUID",
"templateId": "TEMPLATE_UUID",
"variables": {
"app": "MsgFlash",
"coupon": "PROMO10"
}
}'
The backend:
- loads the template
- resolves
contact.*, user.*, instance.*
- injects your custom values into
custom.*
- stores the final rendered text in
Message.body
Template example:
Hello {{contact.firstName}}, bienvenue sur {{custom.app}} depuis {{instance.name}}.
Supported variables:
contact.*
user.*
instance.*
custom.*
For contact.* variables, provide contactId if you want enriched contact context.
Success response
{
"data": {
"id": "msg_uuid",
"instanceId": "inst_uuid",
"contactId": "cnt_uuid",
"campaignId": null,
"type": "text",
"to": "+33612345678",
"body": "Hello Awa, bienvenue sur MsgFlash depuis Boutique Porto-Novo.",
"mediaUrl": null,
"status": "queued",
"providerMessageId": null,
"createdAt": "2026-04-01T10:00:00.000Z",
"updatedAt": "2026-04-01T10:00:00.000Z"
}
}
Common errors
| Code | HTTP | When |
|---|
VALIDATION_ERROR | 400 | Invalid body |
TEMPLATE_INVALID | 400 | Invalid placeholder or template |
TEMPLATE_VARIABLES_MISSING | 400 | Variables template missing |
TEMPLATE_CONTEXT_UNAVAILABLE | 400 | Invalid contactId or instanceId context |
NOT_FOUND | 404 | Instance, contact, or template not found |
SUBSCRIPTION_INACTIVE | 403 | Subscription not usable |
MONTHLY_OUTBOUND_QUOTA_EXCEEDED | 429 | Monthly quota exhausted |
Possible statuses
queued → sent → delivered → read
└──────→ failed
| Status | Description |
|---|
queued | Message accepted and queued |
sent | Sent to WhatsApp |
delivered | Delivered to the device |
read | Read by recipient |
failed | Send failed |
Track status
GET /api/v1/messages/{id}
- Webhooks
message.sent, message.delivered, message.read, message.failed
See Webhooks.