Module 3: Core Messaging API
All message types, sending methods, and quota management.
3.1 Sending Methods Overview
LINE provides 5 ways to send messages, each with different use cases and cost implications:
| Method | Endpoint | Recipients | Counts toward quota? | Rate limit |
|---|---|---|---|---|
| Reply | POST /v2/bot/message/reply | 1 user | ✓ Free | 5 req/s |
| Push | POST /v2/bot/message/push | 1 user | ✗ Counted | 900 req/channel |
| Multicast | POST /v2/bot/message/multicast | Up to 500 users | ✗ Counted | 900 req/channel |
| Broadcast | POST /v2/bot/message/broadcast | All friends | ✗ Counted | 30 req/channel |
| Narrowcast | POST /v2/bot/message/narrowcast | Filtered audience | ✗ Counted | 900 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
replyTokenfrom 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
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 Type | Description | Example data |
|---|---|---|
postback | Sends data to your webhook | data: "action=buy&id=5" |
message | Sends a text message to OA | text: "Show menu" |
uri | Opens a URL | uri: "https://..." |
datetimepicker | Date/time picker | data, mode, initial, max, min |
camera | Opens camera | (no additional params) |
cameraRoll | Opens photo gallery | (no additional params) |
location | Shares user location | (no additional params) |
richmenuswitch | Switches active rich menu | richMenuAliasId, 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
}
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.