Skip to main content
POST
/
v2
/
whatsapp
/
{botId}
/
hsm
Send Individual HSM
curl --request POST \
  --url https://api.jelou.ai/v2/whatsapp/{botId}/hsm \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "elementName": "<string>",
  "destinations": [
    "<string>"
  ],
  "mediaUrl": "<string>",
  "filename": "<string>",
  "type": "text",
  "language": "en",
  "parameters": [
    "<string>"
  ],
  "buttonPayloads": [
    {}
  ],
  "actions": {},
  "headerParameters": [
    "<string>"
  ],
  "buttonParameters": [
    {
      "type": "URL",
      "payload": {},
      "param": 123
    }
  ],
  "ltoParams": {
    "expirationTime": 123
  },
  "cards": [
    {
      "mediaUrl": "<string>",
      "params": [
        "<string>"
      ],
      "buttonParameters": [
        {
          "type": "URL",
          "payload": {},
          "param": 123
        }
      ]
    }
  ],
  "expirationTime": "<string>",
  "campaignId": "<string>"
}
'
[
  {
    "id": "<string>",
    "destination": "<string>"
  }
]
The WhatsApp API allows companies to automate and personalize communication with their customers, enabling efficient, scalable interactions enriched with multimedia content. It is ideal for managing inquiries, sending notifications, and providing immediate responses through AI Agents.

Message sending configuration

Step 1: Define the Endpoint

To send messages, use the following API endpoint:
POST https://api.jelou.ai/v2/whatsapp/{botId}/hsm

Step 2: Request Parameters

The key parameters for the request include:
  • Text: The message content.
  • Message type (type): Defines the type of template to be sent.
  • Template property: Template previously created and approved by META.
  • Media file: If the template requires a URL (image, document, etc.).
  • Bot ID: Unique bot identifier.
  • Parameters: Specific data for each send (name, order number, etc.).

Step 3: Send the request

Send the message using the POST method. Upon completing the send, you will receive a response that allows you to verify the delivery status.
Make sure to comply with WhatsApp policies to avoid restrictions.

Content restrictions

Remember that, to send messages through WhatsApp, you must use templates previously approved by META. Each template has specific limitations based on its format and content, such as message length or the type of information allowed. Make sure to review these restrictions before using them to ensure correct delivery. Keep in mind that:
  • URLs, emojis, and multimedia files are not allowed within authentication messages.
  • Parameters must have a maximum of 15 characters.

Request Body

PropertyTypeDescriptionRequired
mediaUrlstringPublic URL of the media file. Required if your template is of type video, image, or document.Conditional
filenamestringFile name for document-type templates.Conditional
typestringMessage type: text, hsm, image, document, video, catalog, carousel. Defaults to text.No
languagestringTemplate language: en, es, ptNo
elementNamestringName of the approved template.Yes
parametersarraySet of strings that replace values in the template.Yes
destinationsarrayList of phone numbers. Numeric format with country code, without + or spaces.Yes
buttonPayloadsarrayInformation for quick reply buttons.No
actionsobjectTemplate configuration and actions in payload format.No
headerParametersarrayHeader parameter, maximum 1 parameter.No
thumbnailProductstringThumbnail image URL. Required for catalog templates.Conditional
expirationTimestringExpiration time in timestamp format (milliseconds).No
campaignIdstringUnique identifier of the associated campaign.No
buttonParametersarrayConfiguration for all button types.No
ltoParamsobjectLimited time offer (LTO) parameters.No
cardsarrayContent cards for carousel templates.No

Template types

In this section, we share request examples for the different template types. These examples provide a clear guide so you can easily substitute the values with your own data.
If a template name or a button within the JSON differs from the already approved template, even by an accent mark, the send will fail. Precision is key to ensuring functionality.
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "parameters": ["PARAMETER_1", "PARAMETER_2"],
    "destinations": ["PHONE_NUMBER"],
    "elementName": "ELEMENT_NAME"
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "parameters": ["PARAMETER_1", "PARAMETER_2"],
    "mediaUrl": "https://cdn.example.com/image.jpeg",
    "type": "image",
    "destinations": ["PHONE_NUMBER"],
    "elementName": "ELEMENT_NAME"
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "parameters": ["PARAMETER_1", "PARAMETER_2"],
    "mediaUrl": "https://cdn.example.com/video.mp4",
    "type": "video",
    "destinations": ["PHONE_NUMBER"],
    "elementName": "ELEMENT_NAME"
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "parameters": ["PARAMETER_1"],
    "mediaUrl": "https://cdn.example.com/document.pdf",
    "type": "document",
    "destinations": ["PHONE_NUMBER"],
    "elementName": "ELEMENT_NAME"
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "parameters": ["PARAMETER_1"],
    "destinations": ["PHONE_NUMBER"],
    "elementName": "ELEMENT_NAME"
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Accept-Language: en' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "destinations": ["PHONE_NUMBER"],
    "parameters": ["PARAMETER_1"],
    "elementName": "ELEMENT_NAME",
    "buttonParameters": [
      {
        "type": "URL",
        "payload": {"param": "PARAM_URL"}
      }
    ]
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "elementName": "ELEMENT_NAME",
    "language": "en",
    "type": "text",
    "parameters": ["param1", "param2"],
    "destinations": ["PHONE_NUMBER"],
    "buttonParameters": [
      {
        "type": "QUICK_REPLY",
        "payload": {"type": "edge", "action": "BTN1", "skillId": "1"}
      },
      {
        "type": "QUICK_REPLY",
        "payload": {"type": "edge", "action": "BTN2", "skillId": "2"}
      },
      {
        "type": "QUICK_REPLY",
        "payload": {"type": "edge", "action": "BTN3", "skillId": "3"}
      }
    ]
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "elementName": "ELEMENT_NAME",
    "destinations": ["PHONE_NUMBER"],
    "parameters": ["PARAMETER_1", "PARAMETER_2"],
    "headerParameters": ["PARAMETER_VALUE"]
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "elementName": "ELEMENT_NAME",
    "destinations": ["PHONE_NUMBER"],
    "parameters": ["PARAMETER_1"],
    "type": "catalog",
    "buttonParameters": [
      {
        "type": "CATALOG",
        "payload": {"thumbnailProduct": "productId"}
      }
    ]
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "buttonOptions": {},
    "elementName": "ELEMENT_NAME",
    "destinations": ["PHONE_NUMBER"],
    "parameters": ["PARAMETER_1", "PARAMETER_2"],
    "type": "image",
    "mediaUrl": "https://cdn.example.com/image.jpeg",
    "ltoParams": {"expirationTime": 1733260800000},
    "buttonParameters": [
      {
        "type": "COPY_CODE",
        "param": 1,
        "payload": {"param": "20OFF"}
      }
    ]
  }'
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "buttonOptions": {},
    "elementName": "ELEMENT_NAME",
    "destinations": ["PHONE_NUMBER"],
    "parameters": ["PARAMETER_1"],
    "type": "hsm"
  }'

Common use cases

1. Personalized messages

Use templates with variables to send messages tailored to each user’s needs (for example, payment reminders or order updates).

2. Automation with Webhooks

Personalized interactions based on user responses, allowing for a more dynamic and efficient conversation. Campaign examples:
  • Personalized promotions: Exclusive offers based on customer preferences.
  • Payment reminders: Automatic notifications for invoice due dates.
  • Service quotes: Quick inquiries about insurance, loans, etc.

Advanced configuration

Phone number

Since this is an individual send, the phone number of the recipient must be in the correct format for the send to be successful. The + sign must be omitted, the country code must be included, and only numeric characters are allowed. Dashes or spaces are not accepted.
For users in Ecuador: The ”+” sign and the first 0 of the phone number must be omitted for it to be entered correctly.
✅ Correct format❌ Incorrect format❌ Incorrect format
PHONE_NUMBER+PHONE_NUMBER09XXXXXXXX

Specific parameters

Depending on the campaign, you can use personalized data such as the message type or additional customer information.

Message personalization

Linking with Skills

Each message can be associated with a specific skill that defines how the user’s response should be handled. This is useful for creating more complex and targeted interactions, such as interactive menus or surveys.

Button configuration

You can use the following structure in the buttonPayloads field when your template includes quick reply buttons using skills; this will allow you to activate additional flows within the conversation based on the action selected by the user.
[
  {"type": "edge", "action": "Yes", "skillId": "1"},
  {"type": "edge", "action": "Reschedule", "skillId": "2"},
  {"type": "edge", "action": "Cancel", "skillId": "3"}
]
In this case, each button must have the keys type, action, and skillId. The action key defines the text that will appear on the button, while skillId indicates the ID of the skill that the button will activate.
Redirect users to specific skills based on their choice or interaction.Templates allow the following configurations:
{
  "actions": {
    "setSkill": {"id": 2222}
  }
}
{
  "actions": {
    "setMemoryParams": {
      "url": "https://apps.jelou.ai"
    }
  }
}

Cache Parameters

This function is used to save additional information in the cache for later use. It will depend on the desired configuration for the template. If a URL is sent, it can be used by a skill to redirect that URL for marketing purposes. All parameters to be stored in cache must go in setMemoryParams with their respective key-value fields.
This configuration will be valid for 3 months.
{
  "actions": {
    "setMemoryParams": {
      "url": "https://apps.jelou.ai"
    }
  }
}

API Responses

[
  {
    "id": "msg-12345-67890-abcde-fghij-klmno",
    "destination": "PHONE_NUMBER"
  }
]
{
  "message": ["Template does not exist"],
  "status": "failed",
  "_metadata": {
    "error": {},
    "body": {
      "destinations": [{"destination": "PHONE_NUMBER"}],
      "parameters": ["John", "example_value"],
      "elementName": "sample_template",
      "code": "en",
      "type": "text",
      "botId": "BOT_ID",
      "botName": "Your Bot"
    }
  },
  "error": {}
}
{
  "message": "Authentication failed"
}
{
  "message": ["The Bot could not be found at the moment."],
  "statusMessage": "failed",
  "status": 0,
  "error": {
    "code": "E1019",
    "key": "BOT_NOT_FOUND",
    "description": "Error to be thrown when trying to get a Bot.",
    "developerMessages": {
      "es": "El botId no se encuentra en la base de datos o ha sido eliminado.",
      "en": "The botId is not found in the database or has been deleted."
    },
    "clientMessages": {
      "es": "El Bot no se pudo encontrar por el momento.",
      "en": "The Bot could not be found at the moment."
    }
  }
}
{
  "message": ["The values entered are not correct."],
  "statusMessage": "failed",
  "status": 0,
  "error": {
    "code": "E0422",
    "key": "VALIDATOR_ERROR",
    "description": "Error to be thrown when cannot process request because of incoming values",
    "developerMessages": {
      "es": "Los valores del request no son correctos para ser procesados.",
      "en": "The request values are not correct for processing."
    },
    "clientMessages": {
      "es": "Los valores ingresados no son correctos.",
      "en": "The values entered are not correct."
    }
  },
  "validationError": {
    "parameters": [
      {
        "en": "The number of parameters is incorrect.",
        "es": "El número de parámetros es incorrecto."
      }
    ]
  }
}
{
  "message": ["We are having trouble processing your request. Please try again later."],
  "statusMessage": "failed",
  "status": 0,
  "error": {
    "code": "E0000",
    "key": "UNKNOWN_ERROR",
    "description": "Error to be thrown when it couldn't be determined the reason of failure",
    "developerMessages": {
      "es": "Error inesperado occurido, revisar logs.",
      "en": "Unexpected error occurred, check logs."
    },
    "clientMessages": {
      "es": "Estamos teniendo problemas procesando la solicitud. Por favor intenta mas tarde.",
      "en": "We are having trouble processing your request. Please try again later."
    }
  }
}

To facilitate testing and sending requests, we recommend using tools such as:
  • Postman
  • Insomnia
These tools allow you to make HTTP requests easily, test different configurations, and review API responses.

Frequently asked questions

There is currently no defined character limit per message; however, you should be mindful of the size of files that are part of the message, such as: image, video, or document. These are shared via mediaUrl.At Jelou, we have the following size and format limitations to follow:
  • DOCUMENT: Up to 15MB - Format: .pdf
  • VIDEO: Up to 15MB - Format: .mp4
  • IMAGE: Up to 5MB - Formats: .jpg, .jpeg, .png
Both the bulk and 1-1 send cURLs can be consumed in any HTTPS client such as Insomnia or Postman. Simply create an HTTPS request using the cURL (just paste it), then change the data and execute.Here is an example with basic-auth:
curl --request POST \
  --url 'https://api.jelou.ai/v2/whatsapp/BOT_ID/hsm' \
  --header 'Accept-Language: en' \
  --header 'Authorization: Basic {{Base64EncodedUsername:Password}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "destinations": ["PHONE_NUMBER"],
    "parameters": [],
    "elementName": "your_template_name"
  }'

Authorizations

Authorization
string
header
required

Basic authentication using Base64 encoded clientId:clientSecret

Path Parameters

botId
string
required

The unique identifier of the bot

Body

application/json
elementName
string
required

Approved template name

destinations
string[]
required

Phone numbers with country code, no + sign

mediaUrl
string<uri>

Public URL for media (required for image/video/document templates)

filename
string

Filename for document templates

type
enum<string>
default:text
Available options:
text,
hsm,
image,
document,
video,
catalog,
carousel
language
enum<string>
Available options:
en,
es,
pt
parameters
string[]

Template parameter values

buttonPayloads
object[]
actions
object
headerParameters
string[]
Maximum array length: 1
buttonParameters
object[]
ltoParams
object
cards
object[]
expirationTime
string

Expiration timestamp in milliseconds

campaignId
string

Response

HSM sent successfully

id
string
destination
string