Send Custom Message

Send a message to a customer inside a conversation that is already open. Unlike Send Template — which is used to start the conversation — this endpoint assumes the customer already started a conversation or recently replied to a template, so the service window is still active.

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

Request body

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "content": "¡Hola! ¿En qué puedo ayudarte?",
  "client": {
    "name": "José",
    "customFields": {
      "placas": "ABC123"
    }
  }
}

Body parameters

FieldTypeDescriptionRequired
channelIdstringInternal channel ID OR the agent's phone number (E.164 format without +)
conversationIdstringCustomer phone number in E.164 format without +
contentstring | objectMessage content. If a string, sent as text. For media and interactive messages, use an object — see Message types
typeenumtext, image, video, file, audio, interactive, email. Optional when content is a string
clientobjectCustomer information to update (upsert)
campaignIdstringID of the campaign the message is attributed to. If omitted, it is logged under the api campaign
delaynumberDelay in milliseconds (3,000 – 86,400,000)
scheduleTimestringScheduled send date/time (ISO 8601). Maximum 1 year in the future

Message types

content can be plain text or a structured object. When it is an object, you must specify type, and the shape of content depends on the type.

Text

Shorthand form:

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "content": "¡Hola! ¿En qué puedo ayudarte?"
}

Explicit form:

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "text",
  "content": { "text": "¡Hola! ¿En qué puedo ayudarte?" }
}

Image

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "image",
  "content": {
    "image": {
      "url": "https://cdn.assets.com/foto.jpg",
      "caption": "Aquí está la foto que me pediste"
    }
  }
}
FieldTypeDescriptionRequired
content.image.urlstringPublic https:// image URL
content.image.captionstringCaption text shown under the image

Video

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "video",
  "content": {
    "video": {
      "url": "https://cdn.assets.com/video.mp4",
      "caption": "Mira este video"
    }
  }
}
FieldTypeDescriptionRequired
content.video.urlstringPublic https:// video URL
content.video.captionstringCaption text shown under the video

Document / file

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "file",
  "content": {
    "file": {
      "url": "https://cdn.assets.com/factura.pdf",
      "filename": "factura-2025-09.pdf",
      "caption": "Tu factura del mes"
    }
  }
}
FieldTypeDescriptionRequired
content.file.urlstringPublic https:// file URL
content.file.filenamestringName the customer sees for the file
content.file.captionstringCaption shown next to the file

Audio

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "audio",
  "content": {
    "audio": {
      "url": "https://cdn.assets.com/nota.ogg"
    }
  }
}
FieldTypeDescriptionRequired
content.audio.urlstringPublic https:// audio URL

Interactive messages

Interactive messages (buttons, lists, and flows) are available only on WhatsApp.

Up to 3 buttons per message. The customer taps one and the API receives the reply as a regular message with the id of the selected button.

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "interactive",
  "content": {
    "type": "button",
    "body": { "text": "¿Quieres confirmar tu cita?" },
    "action": {
      "buttons": [
        { "id": "confirmar", "title": "Sí, confirmar" },
        { "id": "reagendar", "title": "Reagendar" },
        { "id": "cancelar", "title": "Cancelar" }
      ]
    }
  }
}
FieldTypeDescriptionRequired
content.body.textstringMain message text
content.headerobjectOptional header ({ type: "text", text })
content.footer.textstringSmall text shown below the buttons
content.action.buttons[].idstringButton identifier. You receive it back when the customer taps the button
content.action.buttons[].titlestringVisible button text (max 20 characters recommended)

Up to 10 rows in total, distributed across one or more sections. The customer opens the list, taps a row, and the API receives the reply with the id of the chosen row.

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "interactive",
  "content": {
    "type": "list",
    "body": { "text": "Elige el horario que prefieras" },
    "action": {
      "button": "Ver horarios",
      "sections": [
        {
          "title": "Esta semana",
          "rows": [
            { "id": "lun-10", "title": "Lunes 10:00", "description": "Disponible" },
            { "id": "mar-12", "title": "Martes 12:00", "description": "Disponible" }
          ]
        }
      ]
    }
  }
}
FieldTypeDescriptionRequired
content.body.textstringMain message text
content.action.buttonstringText on the button that opens the list
content.action.sections[].titlestringSection title
content.action.sections[].rows[].idstringRow identifier. You receive it back when the customer taps it
content.action.sections[].rows[].titlestringVisible row text
content.action.sections[].rows[].descriptionstringSecondary text shown below the title

To send a published WhatsApp Flow, provide flow_id (or flow_name) and the CTA text. The API generates the flow_token automatically and correlates the customer's response with the send.

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "interactive",
  "content": {
    "type": "flow",
    "body": { "text": "Completa tu registro en menos de un minuto" },
    "action": {
      "parameters": {
        "flow_id": "1234567890",
        "flow_cta": "Empezar"
      }
    }
  }
}
FieldTypeDescriptionRequired
content.body.textstringMain message text
content.action.parameters.flow_idstringID of the published WhatsApp Flow. Alternative: flow_name✓¹
content.action.parameters.flow_namestringName of the published Flow. Alternative to flow_id✓¹
content.action.parameters.flow_ctastringText of the button that opens the Flow

¹ Send flow_id or flow_name, not both.

Instruction to the agent

An instruction is not sent to the customer: it acts on the agent operating the conversation. It is useful when you are supervising the chat through the API and want the agent to wait or resume control. The mode field defines the behavior.

{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "instruction",
  "content": {
    "text": "Espera a que el cliente confirme la cita antes de continuar.",
    "mode": "wait"
  }
}
FieldTypeDescriptionRequired
content.textstringInstruction or context the agent should consider
content.modeenumwait or resume

Behavior by mode

  • wait: records the instruction as a system message in the history and leaves the conversation waiting for the customer's next message. The agent does not reply immediately; when the next customer message arrives, it reads the instruction as context.
  • resume: marks the conversation as resumed and prompts the agent to continue the flow using the instruction as guidance. The agent can decide whether to reply to the customer based on its own logic.
{
  "channelId": "521234567890",
  "conversationId": "521234567890",
  "type": "instruction",
  "content": {
    "text": "Continúa con el flujo de venta y ofrece un descuento del 10%.",
    "mode": "resume"
  }
}

Scheduling

Just like in Send Template , you can send the message immediately, after a delay, or at a specific date and time.

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 1 year in the future
  • Examples:
    • "2025-07-01T18:40:00" — Mexico time (UTC-6)
    • "2025-07-01T18:40:00Z" — UTC time
    • "2025-07-01T18: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

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": "2025-02-14T12:00:00Z"
}

With delay:

{
  "messageId": "msg_123xyz",
  "status": "delayed",
  "timestamp": "2025-02-14T12:00:00Z",
  "executeAt": "2025-02-14T12:00:05.000Z",
  "delayMs": 5000
}

With scheduleTime:

{
  "messageId": "msg_123xyz",
  "status": "scheduled",
  "timestamp": "2025-02-14T12:00:00Z",
  "executeAt": "2025-07-01T00:40:00.000Z",
  "scheduledTime": "2025-07-01T18:40:00"
}
FieldTypeDescription
messageIdstringID of the created message. Use it to track its status in the campaign
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

Common errors

CodeCase
400Invalid schema, delay outside the allowed range, delay and scheduleTime sent together, or invalid scheduleTime
404No agent was found for the given channelId, or the customer has no open conversation on that channel
422The conversation exists but the service window is closed. Send a template with Send Template to reopen it

Channel rules

WhatsApp

  • Templates are required to start the conversation. Once the customer replies, the service window stays open for 24 hours and you can send any message type until it closes.
  • Every customer message resets the window.
  • Supports text, images, videos, files, audio, buttons, lists, and flows.

Instagram and Facebook

  • Support text, images, videos, files, and audio. Interactive messages (buttons, lists, flows) are not available outside WhatsApp.
  • These platforms may have windows and policies different from WhatsApp's; always check canSendDirectMessage before sending.

Checking status

Confirm your message was delivered:

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