Module 3: Core Messaging API

All message types, sending methods, and quota management.

⏱ 30 min read 📖 Intermediate

3.1 Sending Methods Overview

LINE provides 5 ways to send messages, each with different use cases and cost implications:

MethodEndpointRecipientsCounts toward quota?Rate limit
ReplyPOST /v2/bot/message/reply1 user✓ Free5 req/s
PushPOST /v2/bot/message/push1 user✗ Counted900 req/channel
MulticastPOST /v2/bot/message/multicastUp to 500 users✗ Counted900 req/channel
BroadcastPOST /v2/bot/message/broadcastAll friends✗ Counted30 req/channel
NarrowcastPOST /v2/bot/message/narrowcastFiltered audience✗ Counted900 req/channel

3.2 Reply vs Push — The Critical Difference

Reply is always free (not counted in quota) but has constraints:

  • Must be sent within 5 minutes of receiving a webhook event
  • Requires the replyToken from the webhook event
  • Can only be sent once per webhook event
  • Reply can contain up to 5 messages in a single call

Push counts toward quota but is more flexible:

  • Send anytime, to any user who has added your OA
  • No time limit
  • Requires the user's LINE User ID
Best practice: Use Reply for real-time responses (within 5 min), Push for scheduled/triggered messages. Always use Reply first when possible — it's free!

3.3 All 11 Message Types

3.3.1 Text Message

{
  "type": "text",
  "text": "Hello, {{displayName}}! Welcome to our service."
}

Text messages support LINE emoji via $ notation and Unicode emoji directly. Maximum 5000 characters.

3.3.2 Sticker Message

{
  "type": "sticker",
  "packageId": "11537",
  "stickerId": "52002734"
}

Find sticker IDs from LINE's sticker store. Popular packages: 11537 (LINE emoji), 6136 (brown face).

3.3.3 Image Message

{
  "type": "image",
  "originalContentUrl": "https://example.com/image-original.jpg",
  "previewImageUrl": "https://example.com/image-preview.jpg"
}

Both URLs must be HTTPS. Preview recommended max 240px width.

3.3.4 Video Message

{
  "type": "video",
  "originalContentUrl": "https://example.com/video.mp4",
  "previewImageUrl": "https://example.com/thumbnail.jpg",
  "trackingId": "my-video-001"  // optional, for viewing-complete events
}

Max video size: 200 MB. Max duration: 5 minutes.

The trackingId allows you to receive a videoPlayComplete webhook event when the user finishes watching.

3.3.5 Audio Message

{
  "type": "audio",
  "originalContentUrl": "https://example.com/audio.m4a",
  "duration": 60000  // milliseconds
}

Supported format: M4A. Max size: 200 MB.

3.3.6 Location Message

{
  "type": "location",
  "title": "CentralWorld",
  "address": "999/9 Rama I Rd, Pathum Wan, Bangkok",
  "latitude": 13.7463,
  "longitude": 100.5382
}

3.3.7 Template Message — Buttons

{
  "type": "template",
  "altText": "This is a buttons template",
  "template": {
    "type": "buttons",
    "thumbnailImageUrl": "https://example.com/thumb.jpg",
    "imageAspectRatio": "rectangle",
    "imageSize": "cover",
    "imageBackgroundColor": "#FFFFFF",
    "title": "Menu",
    "text": "Please select an option:",
    "actions": [
      { "type": "message", "label": "View Menu", "text": "Show menu" },
      { "type": "uri", "label": "Visit Website", "uri": "https://example.com" },
      { "type": "postback", "label": "Contact Us", "data": "action=contact" }
    ]
  }
}

3.3.8 Template Message — Confirm

{
  "type": "template",
  "altText": "Confirm your booking",
  "template": {
    "type": "confirm",
    "text": "Are you sure you want to book this appointment?",
    "actions": [
      { "type": "postback", "label": "Yes", "data": "action=book&id=123" },
      { "type": "postback", "label": "No", "data": "action=cancel&id=123" }
    ]
  }
}

3.3.9 Template Message — Carousel

{
  "type": "template",
  "altText": "Product carousel",
  "template": {
    "type": "carousel",
    "columns": [
      {
        "thumbnailImageUrl": "https://example.com/item1.jpg",
        "title": "Product A",
        "text": "฿199",
        "actions": [
          { "type": "postback", "label": "Buy", "data": "action=buy&id=1" }
        ]
      },
      {
        "thumbnailImageUrl": "https://example.com/item2.jpg",
        "title": "Product B",
        "text": "฿299",
        "actions": [
          { "type": "postback", "label": "Buy", "data": "action=buy&id=2" }
        ]
      }
    ]
  }
}

Max 10 columns in a carousel. Each column can have up to 3 actions.

3.3.10 Image Map Message

{
  "type": "imagemap",
  "baseUrl": "https://example.com/imagemap",
  "altText": "Promotion banner",
  "baseSize": { "width": 1040, "height": 1040 },
  "actions": [
    {
      "type": "uri",
      "linkUri": "https://example.com/promo1",
      "area": { "x": 0, "y": 0, "width": 520, "height": 520 }
    },
    {
      "type": "uri",
      "linkUri": "https://example.com/promo2",
      "area": { "x": 520, "y": 0, "width": 520, "height": 520 }
    }
  ]
}

LINE requests image at: {baseUrl}/2048, {baseUrl}/1024, {baseUrl}/1040 (different widths).

3.3.11 Flex Message

Flex Messages are the most powerful and flexible type. They have their own dedicated module (Module 5).

{
  "type": "flex",
  "altText": "This is a flex message",
  "contents": {
    "type": "bubble",
    "body": {
      "type": "box",
      "layout": "vertical",
      "contents": [
        { "type": "text", "text": "Hello!", "weight": "bold", "size": "xl" }
      ]
    }
  }
}

3.4 Quick Reply — Inline Buttons

Quick Reply adds buttons below the message that disappear after the user taps one. Can be added to any message type.

{
  "type": "text",
  "text": "How can I help you today?",
  "quickReply": {
    "items": [
      {
        "type": "action",
        "action": {
          "type": "message",
          "label": "📄 Menu",
          "text": "Show menu"
        }
      },
      {
        "type": "action",
        "action": {
          "type": "uri",
          "label": "📞 Call Us",
          "uri": "tel:02-123-4567"
        }
      },
      {
        "type": "action",
        "imageUrl": "https://example.com/location-icon.png",
        "action": {
          "type": "location"
        }
      }
    ]
  }
}

Max 13 items per quick reply. Supports actions: message, uri, postback, datetimepicker, camera, cameraRoll, location.

3.5 Action Types Reference

Actions are used in Rich Menus, Template Messages, Flex Messages, and Quick Replies:

Action TypeDescriptionExample data
postbackSends data to your webhookdata: "action=buy&id=5"
messageSends a text message to OAtext: "Show menu"
uriOpens a URLuri: "https://..."
datetimepickerDate/time pickerdata, mode, initial, max, min
cameraOpens camera(no additional params)
cameraRollOpens photo gallery(no additional params)
locationShares user location(no additional params)
richmenuswitchSwitches active rich menurichMenuAliasId, data

3.6 Sending a Reply (Node.js)

const axios = require('axios');

async function replyMessage(replyToken, messages) {
  const TOKEN = process.env.CHANNEL_ACCESS_TOKEN;
  const url = 'https://api.line.me/v2/bot/message/reply';

  const payload = {
    replyToken,
    messages: Array.isArray(messages) ? messages : [messages]
  };

  const res = await axios.post(url, payload, {
    headers: {
      'Authorization': `Bearer ${TOKEN}`,
      'Content-Type': 'application/json'
    }
  });

  return res.data;
}

// Usage in webhook handler:
app.post('/webhook', (req, res) => {
  const event = req.body.events[0];
  if (event.type === 'message' && event.message.type === 'text') {
    replyMessage(event.replyToken, {
      type: 'text',
      text: `You said: ${event.message.text}`
    });
  }
  res.status(200).send('OK');
});

3.7 Sending a Push Message (Python)

import requests

def push_message(user_id, messages):
    url = 'https://api.line.me/v2/bot/message/push'
    headers = {
        'Authorization': f'Bearer {CHANNEL_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        'to': user_id,
        'messages': messages if isinstance(messages, list) else [messages]
    }
    res = requests.post(url, json=payload, headers=headers)
    return res.json()

# Send to specific user
push_message('U4a8b...', {
    'type': 'text',
    'text': 'Your order #123 has been shipped! 🚚'
})

3.8 Multicast, Broadcast & Narrowcast

Multicast

Send to up to 500 user IDs in one call:

POST https://api.line.me/v2/bot/message/multicast

{
  "to": ["U4a8b...", "Ucdef...", "U1234..."],
  "messages": [{ "type": "text", "text": "Special promotion just for you!" }]
}

Broadcast

Send to ALL followers. Use sparingly — respects your quota and can annoy users.

POST https://api.line.me/v2/bot/message/broadcast

{
  "messages": [{ "type": "text", "text": "Weekly newsletter is here!" }]
}

Narrowcast

Send to a filtered audience segment. More details in Module 9.

POST https://api.line.me/v2/bot/message/narrowcast

{
  "messages": [{ "type": "text", "text": "VIP members only offer!" }],
  "recipient": {
    "type": "audience",
    "audienceGroupId": 12345678
  }
}

3.9 Quota & Consumption

Check your remaining quota:

GET https://api.line.me/v2/bot/message/quota

Response:
{
  "type": "limited",    // or "none" for Free plan
  "value": 15000        // monthly limit
}
GET https://api.line.me/v2/bot/message/quota/consumption

Response:
{
  "totalUsage": 3200    // messages used this month
}
Quota resets monthly on your plan's billing date. Use the API to monitor consumption and alert before you hit the limit.

3.10 Loading Indicator

Show a "typing" indicator to make the bot feel more responsive:

POST https://api.line.me/v2/bot/chat/loading/start

{
  "chatId": "U4a8b...",  // user ID
  "loadingSeconds": 60    // max 60 seconds
}

Best practice: Set loading indicator, then do your processing, then reply.