Messages

Send a template message

POST/messagesScope messages:send

Sends one approved template. This is the message to use when you start the conversation: an order update, an OTP, a reminder. Outside the 24-hour window it is the only kind WhatsApp will deliver (see The 24-hour window).

Get the template names and the variables each expects from List templates.

Body

  • tostringrequired

    Recipient phone number with country code, for example +919876543210. Spaces and dashes are ignored. A number without a country code is not guessed at and will not reach anyone.

  • fromstring

    Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta phone_number_id or its Wamafy id. Defaults to your default number.

  • templateNamestringrequired

    Name of an approved template. Optional when you pass campaignName, because the campaign names the template.

  • variablesobject

    Values for the template placeholders. A template written as Hi {{1}} takes positions as keys ("1", "2"); one written as Hi {{customer_name}} takes the names. Values are strings or numbers. List templates says which kind each template is (variableFormat) and gives the keys. See the examples below.

  • campaignNamestring

    File the send under an API campaign so it shows in that campaign's report. See API campaigns.

  • languagestring

    Template language. Defaults to the template's own.

  • headerMediaUrlstring

    Public https link to the image, video or document, for a template with a media header. Required for those: we refuse the send without it. List templates gives each template's headerType.

  • buttonsobject[]

    Values for dynamic buttons: a URL button with a placeholder, or a copy-code button. Required when the template has one, since WhatsApp rejects the send without it.

    • indexintegerrequired

      The button's position in the template, starting at 0, as List templates reports it.

    • typestringrequired

      What kind of button it is.

      One of: url, copy_code

    • valuestringrequired

      For a URL button, only the part that replaces the placeholder (order/1043). For a tracked link, the full destination URL instead (see Click tracking). For copy code, the code.

  • offerExpiresAtstring

    For a limited-time offer template with a countdown: when the offer ends, as an ISO 8601 time with offset. Must be in the future.

  • catalogProductRetailerIdstring

    For a catalog template: the retailer id of the product whose image becomes the thumbnail. Optional: without it WhatsApp picks the picture.

  • productsobject

    For a product template (multi-product, single-product or product carousel): the products to show. Required for those: we refuse the send without them. List templates gives each template's headerType (mpm, spm, product_carousel).

    • productIdsstring[]required

      Content IDs from Commerce Manager. A multi-product template takes 1 to 30, a single-product template exactly 1, a product carousel 2 to 10 (one card each).

    • catalogIdstring

      Your Meta catalog's ID. Required for a single-product template and a product carousel.

    • thumbnailProductIdstring

      Multi-product only: the product whose picture leads the message. Defaults to the first.

    • sectionTitlestring

      Multi-product only: the heading over the list, up to 24 characters. Defaults to Products.

Good to know

  • Keep messageId. It is how you look the message up later with Get message status, and how status webhook events refer to it.
  • from in the response is the Wamafy id of the number that sent it, even when you passed a phone number.

Errors

StatusCodeWhen
400BAD_REQUESTThe template is not approved, a dynamic button has no value, or WhatsApp refused the send. The message says which.
400BAD_REQUESTcampaignName and templateName disagree, or the campaign is paused.
400HEADER_MEDIA_REQUIREDThe template has an image, video or document header and no headerMediaUrl was sent.
402WALLET_INSUFFICIENTThe workspace pays through the Wamafy wallet and its balance cannot cover the message. Nothing was sent.
404NOT_FOUNDNo template, number or API campaign by that name.

Plus the errors any endpoint can return, such as a missing key or scope. See Errors.

# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/messages" \
  -H "Authorization: Bearer $WAMAFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "templateName": "order_update",
  "variables": {
    "1": "Priya",
    "2": "#1043"
  }
}'
Response 200
{
  "success": true,
  "data": {
    "messageId": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU",
    "to": "919876543210",
    "from": "6f1c2a9e-1b3d-4c7a-9e2f-7d4b8a1c0e55",
    "status": "sent",
    "campaignName": null,
    "templateName": "order_update"
  }
}

Base URL https://api.wamafy.com/api/v1/public

More examples

Named variables

For a template written with names, such as Hi {{customer_name}}, your appointment on {{appointment_date}} is confirmed., use the names as the keys.

# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/messages" \
  -H "Authorization: Bearer $WAMAFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "templateName": "appointment_confirmed",
  "variables": {
    "customer_name": "Priya",
    "appointment_date": "12 October"
  }
}'

An image header with the body

For a template with an image header, send the image as a public link in headerMediaUrl, alongside the body variables. A video or document header works the same way.

# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/messages" \
  -H "Authorization: Bearer $WAMAFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "templateName": "festive_offer",
  "headerMediaUrl": "https://wamafy.com/smoke/sample.png",
  "variables": {
    "1": "Priya"
  }
}'

A link button with its value

For a button whose link ends in a placeholder, such as https://yourshop.com/{{1}}, send the part that replaces it. index is the button's position, as List templates gives it.

# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/messages" \
  -H "Authorization: Bearer $WAMAFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "templateName": "order_tracking",
  "variables": {
    "1": "Priya"
  },
  "buttons": [
    {
      "index": 0,
      "type": "url",
      "value": "orders/1043"
    }
  ]
}'

Under an API campaign, with an image header

Set up an API campaign in the dashboard and pick its template there, then send with campaignName instead of templateName. Everything else works the same: here, named variables and an image header. See API campaigns.

# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.
curl -X POST "https://api.wamafy.com/api/v1/public/messages" \
  -H "Authorization: Bearer $WAMAFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "to": "+919876543210",
  "campaignName": "appointment_confirmations",
  "headerMediaUrl": "https://wamafy.com/smoke/sample.png",
  "variables": {
    "customer_name": "Priya",
    "date": "12 October",
    "time": "4:30 PM",
    "host": "Dr Rao"
  }
}'
    Send a template message - Wamafy API