Skip to content

Messaging

Message types

Every content type you can send, with its fields, an example request and the channels that support it.

How content is structured#

A message has a type and a content object under the key named by that type. To send a location, set "type": "location" and provide a location object. Exactly one content object is allowed per message.

The message object you get back stores the same content under content, again keyed by type: "content": { "location": { ... } }.

Channel support#

Which types a channel accepts is listed in its capabilities. Sending a type the channel does not support fails with 400 unsupported_message_type and nothing is charged.

TypeWhatsAppTelegramSMSSMS OTPMessengerInstagramTikTok
textYesYesYesYesYesYesYes
attachmentsYesYesYes–YesYesYes
templateYes––––––
buttonYesYes––YesYesYes
listYes––––––
cta_urlYes––––––
locationYesYes–––––
contactsYesYes–––––
poll–Yes–––––

The nine types on this page are validated by OmniMessage before the message is accepted. Some channels accept further types that are passed through without validation: see Channel-specific types.

text#

Plain text of 1 to 4096 characters. The only type every channel supports, and the only one for SMS OTP.

Channels: WhatsApp Business, Telegram, SMS, SMS OTP, Messenger, Instagram, TikTok.

FieldTypeRequiredDescription
bodystringRequiredMessage text, 1 to 4096 characters.
preview_urlbooleanOptionalAsk the channel to render a preview for the first URL in body, where the channel supports it.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "text",
    "text": {
      "body": "Your code is 482910"
    },
    "reference": "order-1042",
    "metadata": {
      "user_id": "u_17"
    }
  }'

Individual channels may enforce a shorter limit or split long text. An SMS longer than one segment is split by the carrier, for example.

attachments#

One media file: an image, video, document, audio file, voice note or sticker. attachments is an array that must contain exactly one item; to send several files, send several messages.

Channels: WhatsApp Business, Telegram, SMS, Messenger, Instagram, TikTok.

FieldTypeRequiredDescription
typestringRequiredKind of media. One of image, video, document, audio, voice, sticker.
urlstringRequiredPublicly reachable HTTPS URL of the file. It is fetched at send time.
captionstringOptionalText shown with the media, where the channel supports captions.
filenamestringOptionalFile name shown to the recipient for documents.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "attachments",
    "attachments": [
      {
        "type": "document",
        "url": "https://example.com/invoices/1042.pdf",
        "filename": "invoice-1042.pdf",
        "caption": "Invoice for order #1042"
      }
    ]
  }'

The file is fetched from url when the message is sent, so the URL must be public HTTPS and stay valid until then. Accepted formats and size limits are those of the channel provider. A file the provider rejects produces a failed message with provider_error.

On SMS, an attachment is sent as MMS and depends on the sending number and the destination supporting it.

template#

A WhatsApp message template that was approved in WhatsApp Manager. Templates are the only way to message a WhatsApp user outside the 24-hour customer service window.

Channels: WhatsApp Business.

FieldTypeRequiredDescription
namestringRequiredTemplate name as approved in WhatsApp Manager.
languageobjectRequiredTemplate language.
language.codestringRequiredLanguage or locale code of the approved translation, for example en or en_US.
componentsarray of objectsOptionalValues for the template variables, in the WhatsApp Cloud API component format. Omit for templates without variables.
components[].typestringRequiredWhich part of the template the parameters fill. One of header, body, button.
components[].sub_typestringOptionalButton kind, for button components (for example url or quick_reply).
components[].indexstringOptionalZero-based button position, for button components.
components[].parametersarray of objectsOptionalParameter values in template order.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "template",
    "template": {
      "name": "order_shipped",
      "language": {
        "code": "en"
      },
      "components": [
        {
          "type": "body",
          "parameters": [
            {
              "type": "text",
              "text": "Layla"
            },
            {
              "type": "text",
              "text": "#1042"
            }
          ]
        }
      ]
    }
  }'

components follows the WhatsApp Cloud API format and is forwarded as is. List the templates of a channel, with their languages and variables, through GET /v1/channels/{id}/templates. The WhatsApp guide covers approval and the messaging window.

button#

Text with one to three quick-reply buttons. When the recipient taps a button you receive an inbound message that carries the id you assigned.

Channels: WhatsApp Business, Telegram, Messenger, Instagram, TikTok.

FieldTypeRequiredDescription
headerobjectOptionalOptional header shown above the body.
header.typestringRequiredHeader kind. One of text.
header.textstringRequiredHeader text, up to 60 characters.
bodyobjectRequiredMain message text.
body.textstringRequiredBody text.
footerobjectOptionalOptional small print below the body.
footer.textstringRequiredFooter text, up to 60 characters.
actionobjectRequiredThe buttons.
action.buttonsarray of objectsRequiredOne to three reply buttons.
action.buttons[].replyobjectRequiredA reply button.
action.buttons[].reply.idstringRequiredYour identifier for the button. Returned when the recipient taps it.
action.buttons[].reply.titlestringRequiredButton label, up to 20 characters.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "button",
    "button": {
      "body": {
        "text": "Your delivery is scheduled for tomorrow, 10:00-12:00. Does that work?"
      },
      "footer": {
        "text": "Order #1042"
      },
      "action": {
        "buttons": [
          {
            "reply": {
              "id": "confirm",
              "title": "Confirm"
            }
          },
          {
            "reply": {
              "id": "reschedule",
              "title": "Reschedule"
            }
          }
        ]
      }
    }
  }'

Button titles are limited to 20 characters. Keep id values stable: they are what your code branches on when the reply arrives.

list#

A WhatsApp list picker: a single button that opens a menu of rows grouped into sections. Use it when there are more than three choices.

Channels: WhatsApp Business.

FieldTypeRequiredDescription
headerobjectOptionalOptional header shown above the body.
header.typestringRequiredHeader kind. One of text.
header.textstringRequiredHeader text, up to 60 characters.
bodyobjectRequiredMain message text.
body.textstringRequiredBody text.
footerobjectOptionalOptional small print below the body.
footer.textstringRequiredFooter text, up to 60 characters.
actionobjectRequiredThe menu.
action.buttonstringRequiredLabel of the button that opens the list, up to 20 characters.
action.sectionsarray of objectsRequiredGroups of rows.
action.sections[].titlestringRequiredSection heading, up to 24 characters.
action.sections[].rowsarray of objectsRequiredSelectable rows.
action.sections[].rows[].idstringRequiredYour identifier for the row. Returned when the recipient selects it.
action.sections[].rows[].titlestringRequiredRow label, up to 24 characters.
action.sections[].rows[].descriptionstringOptionalOptional second line, up to 72 characters.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "list",
    "list": {
      "body": {
        "text": "Pick a delivery window for order #1042."
      },
      "action": {
        "button": "Choose a slot",
        "sections": [
          {
            "title": "Tomorrow",
            "rows": [
              {
                "id": "slot_am",
                "title": "10:00-12:00",
                "description": "Morning"
              },
              {
                "id": "slot_pm",
                "title": "16:00-18:00",
                "description": "Afternoon"
              }
            ]
          }
        ]
      }
    }
  }'

The label of the opening button is limited to 20 characters. The selected row arrives as an inbound message carrying its id.

cta_url#

A WhatsApp message with a single call-to-action button that opens a URL in the browser.

Channels: WhatsApp Business.

FieldTypeRequiredDescription
headerobjectOptionalOptional header shown above the body.
header.typestringRequiredHeader kind. One of text.
header.textstringRequiredHeader text, up to 60 characters.
bodyobjectRequiredMain message text.
body.textstringRequiredBody text.
footerobjectOptionalOptional small print below the body.
footer.textstringRequiredFooter text, up to 60 characters.
actionobjectRequiredThe link button.
action.parametersobjectRequired
action.parameters.display_textstringRequiredButton label, up to 20 characters.
action.parameters.urlstringRequiredURL opened when the button is tapped.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "cta_url",
    "cta_url": {
      "body": {
        "text": "Your order is on its way."
      },
      "action": {
        "parameters": {
          "display_text": "Track order",
          "url": "https://example.com/track/1042"
        }
      }
    }
  }'

location#

A map pin with a name and an address.

Channels: WhatsApp Business, Telegram.

FieldTypeRequiredDescription
latitudenumberRequiredLatitude in decimal degrees.
longitudenumberRequiredLongitude in decimal degrees.
namestringRequiredName of the place.
addressstringRequiredAddress of the place.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "location",
    "location": {
      "latitude": 25.197197,
      "longitude": 55.274376,
      "name": "Pickup point",
      "address": "Sheikh Mohammed bin Rashid Blvd, Dubai"
    }
  }'

contacts#

One or more contact cards. The array uses the contact format of the provider and is forwarded without further validation; the fields below are the commonly used ones.

Channels: WhatsApp Business, Telegram.

FieldTypeRequiredDescription
nameobjectOptionalContact name.
name.formatted_namestringRequiredFull display name.
name.first_namestringOptionalGiven name.
name.last_namestringOptionalFamily name.
phonesarray of objectsOptionalPhone numbers.
phones[].phonestringOptionalPhone number in E.164 format.
phones[].typestringOptionalLabel such as CELL, WORK or HOME.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_7Hq2mN5vB8cX1zL0pK3j",
    "to": "+971501234567",
    "type": "contacts",
    "contacts": [
      {
        "name": {
          "formatted_name": "Acme Support",
          "first_name": "Acme",
          "last_name": "Support"
        },
        "phones": [
          {
            "phone": "+971800123456",
            "type": "WORK"
          }
        ]
      }
    ]
  }'

poll#

A Telegram poll with a question and a list of answer options.

Channels: Telegram.

FieldTypeRequiredDescription
questionstringRequiredPoll question, up to 300 characters.
optionsarray of stringsRequiredTwo to ten answer options of up to 100 characters each.
curl https://api.omnimessage.co/v1/messages \
  -H "Authorization: Bearer om_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "ch_2pT5gB8nM1kL4jH7fD0s",
    "to": "482910375",
    "type": "poll",
    "poll": {
      "question": "Which delivery window suits you?",
      "options": [
        "Morning",
        "Afternoon",
        "Evening"
      ]
    }
  }'

Channel-specific types#

Besides the common types, a channel may list further types in its capabilities. For these, OmniMessage checks only that the content object is present under the key named by type, then forwards it to the channel unchanged, in the format of the channel provider.

ChannelAdditional types
WhatsApp Businessflow, product, product_list, catalog, carousel, location_request
TelegramNone
SMSNone
SMS OTPNone
Messengercarousel, product_list, receipt
Instagramcarousel, product_list
TikTokNone

    Loading