Send template message

Send an approved WhatsApp template to start a conversation with a customer. If a conversation is already open, the message is appended to it; otherwise, a new one is created.

POST https://api.platica.mx/v1/messages/template

Request body

{
  "channelId": "wb-123456789",
  "conversationId": "521234567890",
  "responderAgentId": "agent_123",
  "campaignId": "pV6PvG2lc8ChQb2VmETr",
  "template": {
    "name": "bienvenida_cliente",
    "params": ["Juan", "Premium"],
    "type": "image",
    "file": "https://cdn.assets.com/welcome_image.jpg",
    "buttons": [
      {
        "index": 0,
        "parameters": [{ "type": "text", "text": "promo/enero" }]
      }
    ]
  },
  "client": {
    "name": "José",
    "customFields": {
      "placas": "ABC123",
      "id_recepcion": "REC001"
    }
  }
}

Body parameters

FieldTypeDescriptionRequired
channelIdstringSender channel. Prefer its prefixedChannelId (for example wb-123); the agent phone or legacy channelId remain accepted for compatibility✓
conversationIdstringCustomer phone number in E.164 format without +✓
responderAgentIdstringOptional agent that will handle replies. The agent does not need to own the sender channel—
campaignIdstringID of the campaign the message is attributed to. If omitted, it is logged under the api campaign—
template.namestringName of the template to use✓
template.paramsarrayVariables for the template body. The count must exactly match the number of variables defined in the template—
template.typeenumHeader type: image, document, video. Required if the template has a media header—
template.filestringPublic https:// URL of the header file. Required if template.type is present—
template.buttonsarrayDynamic variables for the template buttons. Maximum 3 items—
delaynumberDelay in milliseconds (3,000 – 86,400,000; maximum 24 hours)—
scheduleTimestringScheduled send date/time (ISO 8601). Maximum 30 days after the request—
clientobjectCustomer information to update (upsert)—

Sender channel and responder

The channel and responder are independent:

  • channelId chooses the number/channel used to send.
  • responderAgentId chooses the agent that handles replies.
  • When responderAgentId is omitted with a canonical channelId, the new conversation stays initiated and unassigned. channel.defaultAgentId is inbound routing and is not inherited.
  • A legacy identifier (agent phone) still preserves that inferred agent.
  • The message is still sent without an agent. When the contact replies, the thread becomes supervised and stays without AI until an agent is assigned.
  • An existing active conversation for the same contact and channel keeps its current agent.

Each item in the array represents a dynamic template button. Static buttons (no variables) do not need to be included.

FieldTypeDescriptionRequired
indexinteger0-based index of the button in the template. Must point to an existing button✓
sub_typeenumurl, phone_number, quick_reply, otp. Inferred automatically from the type defined in the template if omitted—
parametersarrayExactly one item with { "type": "text", "text": "<value>" }✓

Important rules:

  • Indexes must not repeat within the same array
  • For URL buttons, text must be a path segment (e.g. "promo/enero"), not a full URL. Sending "https://..." returns a 400 error
  • If sub_type is omitted, it is inferred from the button type defined in the template (URL → url, OTP → otp, PHONE_NUMBER → phone_number)
"buttons": [
  {
    "index": 0,
    "parameters": [{ "type": "text", "text": "promo/enero" }]
  },
  {
    "index": 1,
    "sub_type": "otp",
    "parameters": [{ "type": "text", "text": "482910" }]
  }
]

Scheduling

Send the template immediately, after a delay, or at a specific time. You can then retrieve, reschedule, or cancel it by messageId .

Delayed send (delay):

  • Minimum: 3000 ms (3 seconds)
  • Maximum: 86400000 ms (24 hours)
  • Example: "delay": 5000 sends the message in 5 seconds

Scheduled send (scheduleTime):

  • ISO 8601 format
  • Must be a future date
  • Cannot be more than 30 days after the request
  • Examples:
    • "2026-10-15T18:40:00" — Mexico time (UTC-6)
    • "2026-10-15T18:40:00Z" — UTC time
    • "2026-10-15T18:40:00-06:00" — With a specific time zone
FieldTypeDescription
client.namestringCustomer full name
client.firstnamestringFirst name
client.lastnamestringLast name
client.emailstringEmail address
client.birthdatestringDate of birth (dd/mm/yyyy)
client.genderenumGender: male or female
client.companystringCompany name
client.countryenumISO 3166-1 alpha-2 code (e.g. MX, US)
client.statestringState of residence
client.citystringCity of residence
client.addressstringFull address
client.postalCodestringPostal code
client.customFieldsmapKey-value object with the custom fields defined in the workspace. See Custom fields for what's available.
client.ownersarrayResponsible-user emails

Template validation

When the request is received, the API verifies that the payload is compatible with the template definition registered in WhatsApp. If there are mismatches, a 400 error is returned with the details of each issue.

Rules that are validated automatically:

  • Param count: must exactly match the number of {{1}}, {{2}}... variables in the template body
  • Media header: if the template has an image, video, or document header, template.type and template.file are required and type must match the defined format
  • Button indexes: every index in template.buttons must correspond to an existing button in the template
  • URL button variables: the text value must be a path segment, not a full URL
{
  "message": "Template payload is incompatible with template configuration",
  "template": "bienvenida_cliente",
  "errors": [
    {
      "field": "template.params",
      "message": "The number of params does not match the template definition",
      "expected": 2,
      "received": 1
    },
    {
      "field": "template.type",
      "message": "This template requires media header type",
      "expected": "image",
      "received": null,
      "example": {
        "type": "image",
        "file": "https://example.com/your-media-file"
      }
    }
  ]
}

Response

The response shape depends on whether the message is sent immediately, with a delay, or scheduled.

Immediate send:

{
  "messageId": "msg_123xyz",
  "status": "sent",
  "timestamp": "2026-09-20T20:00:00Z"
}

With delay (HTTP 202):

{
  "messageId": "msg_123xyz",
  "kind": "template",
  "status": "delayed",
  "timestamp": "2026-09-20T20:00:00Z",
  "executeAt": "2026-09-20T20:00:05.000Z",
  "delayMs": 5000
}

With scheduleTime (HTTP 202):

{
  "messageId": "msg_123xyz",
  "kind": "template",
  "status": "scheduled",
  "timestamp": "2026-09-20T20:00:00Z",
  "executeAt": "2026-10-16T00:40:00.000Z",
  "scheduledTime": "2026-10-15T18:40:00"
}
FieldTypeDescription
messageIdstringID of the created message. For scheduled sends, use it to retrieve, reschedule, or cancel the resource ; you do not need campaignId or runId
kindenumtemplate in HTTP 202 responses from this endpoint
statusenumsent, delayed, or scheduled
timestampstringDate/time when the request was processed (ISO 8601 UTC)
executeAtstringDate/time when the message will be sent (ISO 8601 UTC). Only present in delayed or scheduled sends
delayMsnumberConfigured delay in milliseconds. Only present when delay was used
scheduledTimestringOriginal scheduleTime value sent in the request. Only present when scheduleTime was used

Sends with delay or scheduleTime are accepted but have not been sent yet. See Scheduled Messages for their states and execution rules.

Blocked contact

A contact with status: "blocked" never receives template messages. The API returns:

{
  "code": 409,
  "error": "Conflict - The resource state conflicts with this request",
  "details": {
    "code": "CONTACT_BLOCKED",
    "clientId": "client_123",
    "status": "blocked"
  }
}

The policy is checked again when delayed or scheduled messages execute.

WhatsApp rules

Templates are mandatory

You must use a pre-approved template to start a conversation. You cannot send free-form text messages until the customer replies.

24-hour window

Conversations stay active for 24 hours since the customer's last message.

If the customer does NOT reply:

  • You send the template
  • The customer does not reply
  • You cannot send more messages until they reply

If the customer DOES reply:

  • You send the template
  • The customer replies
  • You can send messages freely for 24 hours
  • Each customer message resets the window

Delivery limitations

WhatsApp can block messages because of:

  • The customer's country restrictions
  • Numbers in WhatsApp experiments
  • Customers who turned off marketing notifications

Checking status

Confirm your message was delivered:

  1. From the platform's inbox
  2. Using the Get Conversation endpoint