Skip to content

    Arabic or English · ↑↓ to move · Enter to open · Esc to close

    العربية
    On this page

    Interactive buttons and their numbered fallback

    Reply buttons, list menus and link buttons from a linked number — and why every customer can still answer when buttons don’t render.

    POST /v2/messages sends three interactive types: buttons (up to 3 reply buttons), list (a menu of up to 10 rows) and cta_url (one link button).

    type: buttons
    {
      "numberId": "cm1abcd2345efgh6789ijkl",
      "to": "201001234567",
      "type": "buttons",
      "body": {
        "text": "Your order #1042 is ready. Confirm delivery today?"
      },
      "footer": {
        "text": "Mursilat Store"
      },
      "buttons": [
        {
          "id": "confirm",
          "title": "Confirm"
        },
        {
          "id": "cancel_order",
          "title": "Cancel"
        }
      ],
      "reference": "order-1042"
    }
    FieldLimits
    body.textLimits1–1024 (required)
    header.text / footer.textLimits≤ 60
    buttons[]Limits1–3 · id ≤ 64 (A-Z a-z 0-9 _ . : -, unique) · title ≤ 20 (unique)
    list.buttonTextLimits≤ 20
    list.sections[]Limits1–10 sections, title ≤ 24 · rows: 1–10 in total, id ≤ 64, title ≤ 24, description ≤ 72
    cta.title / cta.urlLimits≤ 20 · a public https:// URL
    expiresInMinutesLimits5–10080 (default 1440): how long answers are matched

    The numbered fallback

    WhatsApp shows interactive messages from linked devices on most phones, but not all. So Mursilat appends a numbered copy of the options to the text by default (fallback: "numbered"). A customer who sees plain text answers with the number or the title:

    What a customer without buttons sees
    Your order #1042 is ready. Confirm delivery today?
    
    1) Confirm
    2) Cancel
    
    Reply with the number of your choice

    Either way you receive one interactive.reply webhook. reply.source tells you how: button / list (tapped) or number / title (typed). Only the first valid answer per message is reported; the customer’s message also arrives as message.received.

    interactive.reply → data
    {
      "interactionId": "int_8f2c1d9a7b3e4f56a1b2c3d4",
      "messageId": "3EB0A1B2C3D4E5F60718",
      "reference": "order-1042",
      "from": {
        "phone": "201099887766",
        "lid": null,
        "name": "Mona"
      },
      "reply": {
        "id": "confirm",
        "title": "Confirm",
        "index": 1,
        "source": "number"
      },
      "replyMessageId": "3EB0FFEE0011223344",
      "timestamp": "2026-10-10T12:03:00.000Z"
    }

    Tips

    Keep titles short and distinct (they are matched when typed). Use reference to link the answer back to your order. In campaigns, GET /v2/campaigns/{id}/recipients?reply=ANY lists who answered what.