Messaging API
With the Messaging API, you can develop a bot that interacts with users in LINE chats.
The Messaging API is made up of the following components.
Receive notifications in real-time when a user sends a message or friends your account.
Reply to messages from users.
Send messages to users when you want to.
Download image, video, and audio data sent from users.
Get user profile information.
Leave a group or room.
Messaging API SDK
The following SDKs are provided in multiple languages to make it easier for you to start developing bot applications with the Messaging API. These SDKs were also used to generate the sample code found in our API documentation.
Stay connected
Follow our official Twitter account to receive the latest news on documentation, APIs, and issues and to report issues related to our documentation or APIs.
You can also add our official LINE Developers account as a friend on LINE to stay up to date on all the latest news for developers.
Common specifications
The following are specifications that are common to all the APIs provided by the Messaging API.
Rate limits
The limit for the number of requests you can make for each API are shown below. Rate limits vary depending on your plan.
Plan | Limit |
---|---|
Developer Trial | 1,000/min |
Other plans | 10,000/min |
Status codes
The following status codes are returned by the APIs.
Error code | Description |
---|---|
200 OK | Request successful |
400 Bad Request | Problem with the request |
401 Unauthorized | Valid Channel access token is not specified |
403 Forbidden | Not authorized to use the API. Confirm that your account or plan is authorized to used the API. |
429 Too Many Requests | Exceeded the rate limit for API calls |
500 Internal Server Error | Error on the internal server |
Error response
Example of JSON error response
{
"message":"The request body has 2 error(s)",
"details":[
{"message":"May not be empty","property":"messages[0].text"},
{"message":"Must be one of the following values: [text, image, video, audio, location, sticker, richmessage, template, imagemap]","property":"messages[1].type"}
]
}
{
"message":"Invalid reply token"
}
The following JSON data is returned in the response body when an error occurs.
Field | Type | Description |
---|---|---|
message | String | Summary of the error |
details[].message | String | Details of the error |
Or
Field | Type | Content |
---|---|---|
message | String | Details of the error |
Webhooks
Example webhook request body
{
"events": [
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "text",
"text": "Hello, world"
}
}
]
}
When an event, such as when a user adds your account or sends a message, is triggered, an HTTPS POST request is sent to the webhook URL that is configured on the Channel Console in LINE Developers.
Your bot server should receive and handle this request appropriately for the event.
Request headers
Request header | Description |
---|---|
X-Line-Signature | Used for signature verification |
Request body
The request body contains a JSON object with an array of webhook event objects
Field | Type | Description |
---|---|---|
events | Array of webhook event objects | Information about the event |
Response
Your server should return the status code 200
for a HTTP POST request sent by a webhook.
Webhook authentication
Example of signature verification
String channelSecret = ...; // Channel secret string
String httpRequestBody = ...; // Request body string
SecretKeySpec key = new SecretKeySpec(channelSecret.getBytes(), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
byte[] source = httpRequestBody.getBytes("UTF-8");
String signature = Base64.encodeBase64String(mac.doFinal(source));
// Compare X-Line-Signature request header string and the signature
Example of signature verification
CHANNEL_SECRET = ... # Channel Secret string
http_request_body = request.raw_post # Request body string
hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, CHANNEL_SECRET, http_request_body)
signature = Base64.strict_encode64(hash)
# Compare X-Line-Signature request header string and the signature
Example of signature verification
defer req.Body.Close()
body, err := ioutil.ReadAll(req.Body)
if err != nil {
// ...
}
decoded, err := base64.StdEncoding.DecodeString(req.Header.Get("X-LINE-Signature"))
if err != nil {
// ...
}
hash := hmac.New(sha256.New, []byte("<channel secret>"))
hash.Write(body)
// Compare decoded signature and `hash.Sum(nil)` by using `hmac.Equal`
Example of signature verification
$channelSecret = ...; // Channel secret string
$httpRequestBody = ...; // Request body string
$hash = hash_hmac('sha256', $httpRequestBody, $channelSecret, true);
$signature = base64_encode($hash);
// Compare X-Line-Signature request header string and the signature
The signature in the X-Line-Signature
request header must be verified to confirm that the request was sent from the LINE platform.
Authentication is performed as follows.
- With the Channel secret as the secret key, your application retrieves the digest value in the request body created using the HMAC-SHA256 algorithm.
- The server confirms that the signature in the request header matches the digest value which is Base64 encoded.
Webhook event object
{
"events": [
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "text",
"text": "Hello, world"
}
},
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "follow",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
}
}
]
}
JSON object which contains events generated on the LINE Platform.
Common fields
The following are the fields found in the webhook event object
Field | Type | Description |
---|---|---|
type | String | Identifier for the type of event |
timestamp | Number | Time of the event in milliseconds |
source | User Group Room |
JSON object which contains the source of the event |
Source user
JSON object which contains the source user of the event.
Field | Type | Description |
---|---|---|
type | String | user |
userId | String | ID of the source user |
Source group
JSON object which contains the source group of the event.
Field | Type | Description |
---|---|---|
type | String | group |
groupId | String | ID of the source group |
Source room
JSON object which contains the source room of the event.
Field | Type | Description |
---|---|---|
type | String | room |
roomId | String | ID of the source room |
Message event
Event object which contains the sent message.
The message
field contains a message object which corresponds with the message type. You can reply to message events.
Field | Type | Description |
---|---|---|
type | String | message |
replyToken | String | Token for replying to this event |
message | Text Image Video Audio Location Sticker |
Contents of the message |
Text message
Text message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "text",
"text": "Hello, world"
}
}
Message object which contains the text sent from the source.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | text |
text | String | Message text |
Image message
Image message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "image"
}
}
Message object which contains the image content sent from the source. The binary image data can be retrieved with the Content API.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | image |
Video message
Video message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "video"
}
}
Message object which contains the video content sent from the source. The binary video data can be retrieved with the Content API.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | video |
Audio message
Audio message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "audio"
}
}
Message object which contains the audio content sent from the source. The binary audio data can be retrieved with the Content API.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | audio |
Location message
Location message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "location",
"title": "my location",
"address": "〒150-0002 東京都渋谷区渋谷2丁目21−1",
"latitude": 35.65910807942215,
"longitude": 139.70372892916203
}
}
Message object which contains the location data sent from the source.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | location |
title | String | Title |
address | String | Address |
latitude | Decimal | Latitude |
longitude | Decimal | Longitude |
Sticker message
Sticker message example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "message",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"message": {
"id": "325708",
"type": "sticker",
"packageId": "1",
"stickerId": "1"
}
}
Message object which contains the sticker data sent from the source.
For a list of basic LINE stickers and sticker IDs, see sticker list.
Field | Type | Description |
---|---|---|
id | String | Message ID |
type | String | sticker |
packageId | String | Package ID |
stickerId | String | Sticker ID |
Follow event
Follow event example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "follow",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
}
}
Event object for when your account is added as a friend (or unblocked). You can reply to follow events.
Field | Type | Description |
---|---|---|
type | String | follow |
replyToken | String | Token for replying to this event |
Unfollow event
Unfollow event example
{
"type": "unfollow",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
}
}
Event object for when your account is blocked.
Field | Type | Description |
---|---|---|
type | String | unfollow |
Join event
Join event example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "join",
"timestamp": 1462629479859,
"source": {
"type": "group",
"groupId": "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Event object for when your account joins a group or talk room. You can reply to join events.
Field | Type | Description |
---|---|---|
type | String | join |
replyToken | String | Token for replying to this event |
Leave event
Leave event example
{
"type": "leave",
"timestamp": 1462629479859,
"source": {
"type": "group",
"groupId": "cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Event object for when your account leaves a group.
Field | Type | Description |
---|---|---|
type | String | leave |
Postback event
Postback event example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "postback",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"postback": {
"data": "action=buyItem&itemId=123123&color=red"
}
}
Event object for when a user performs an action on a template message which initiates a postback. You can reply to postback events.
Field | Type | Description |
---|---|---|
type | String | postback |
replyToken | String | Token for replying to this event |
postback.data | String | Postback data |
Beacon event
Beacon event example
{
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"type": "beacon",
"timestamp": 1462629479859,
"source": {
"type": "user",
"userId": "U206d25c2ea6bd87c17655609a1c37cb8"
},
"beacon": {
"hwid": "d41d8cd98f",
"type": "enter"
}
}
Event object for when a user detects a LINE Beacon. You can reply to beacon events.
Field | Type | Description |
---|---|---|
type | String | beacon |
replyToken | String | Token for replying to this event |
beacon.hwid | String | Hardware ID of the beacon that was detected |
beacon.type | String | Type of beacon event |
Reply message
Reply message API example
curl -X POST \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
-d '{
"replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
"messages":[
{
"type":"text",
"text":"Hello, user"
},
{
"type":"text",
"text":"May I help you?"
}
]
}' https://api.line.me/v2/bot/message/reply
TextMessage textMessage = new TextMessage("hello");
ReplyMessage replyMessage = new ReplyMessage(
"<replyToken>",
textMessage
);
Response<BotApiResponse> response =
LineMessagingServiceBuilder
.create("<channel access token>")
.build()
.replyMessage(replyMessage)
.execute();
System.out.println(response.code() + " " + response.message());
bot, err := linebot.New(<channel secret>, <channel token>)
if err != nil {
...
}
if _, err := bot.ReplyMessage(<replyToken>, linebot.NewTextMessage("hello")).Do(); err != nil {
...
}
message = {
type: 'text',
text: 'hello'
}
client = Line::Bot::Client.new { |config|
config.channel_secret = "<channel secret>"
config.channel_token = "<channel access token>"
}
response = client.reply_message("<replyToken>", message)
p response
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient('<channel access token>');
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => '<channel secret>']);
$textMessageBuilder = new \LINE\LINEBot\MessageBuilder\TextMessageBuilder('hello');
$response = $bot->replyMessage('<replyToken>', $textMessageBuilder);
echo $response->getHTTPStatus() . ' ' . $response->getBody();
Respond to events from users, groups, and rooms.
Webhooks are used to notify you when an event occurs. For events that you can respond to, a replyToken
is issued for replying to messages.
Because the replyToken
becomes invalid after a certain period of time, responses should be sent as soon as a message is received. Reply tokens can only be used once.
HTTP request
POST https://api.line.me/v2/bot/message/reply
Request headers
Request header | Description |
---|---|
Content-Type | application/json |
Authorization | Bearer {Channel Access Token} |
Request body
Include an array of send message objects for your message.
Field | Type | Description |
---|---|---|
replyToken | String | replyToken received via webhook |
messages | Array of send message objects | Messages Max: 5 |
Response
Example JSON response
{}
Returns the status code 200 OK
and an empty JSON object.
Push message
Push message API example
curl -X POST \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
-d '{
"to": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"messages":[
{
"type":"text",
"text":"Hello, world1"
},
{
"type":"text",
"text":"Hello, world2"
}
]
}' https://api.line.me/v2/bot/message/push
TextMessage textMessage = new TextMessage("hello");
PushMessage pushMessage = new PushMessage(
"<to>",
textMessage
);
Response<BotApiResponse> response =
LineMessagingServiceBuilder
.create("<channel access token>")
.build()
.pushMessage(pushMessage)
.execute();
System.out.println(response.code() + " " + response.message());
bot, err := linebot.New(<channel secret>, <channel token>)
if err != nil {
...
}
if _, err := bot.PushMessage(<to>, linebot.NewTextMessage("hello")).Do(); err != nil {
...
}
message = {
type: 'text',
text: 'hello'
}
client = Line::Bot::Client.new { |config|
config.channel_secret = "<channel secret>"
config.channel_token = "<channel access token>"
}
response = client.push_message("<to>", message)
p response
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient('<channel access token>');
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => '<channel secret>']);
$textMessageBuilder = new \LINE\LINEBot\MessageBuilder\TextMessageBuilder('hello');
$response = $bot->pushMessage('<to>', $textMessageBuilder);
echo $response->getHTTPStatus() . ' ' . $response->getBody();
Send messages to users, groups, and rooms at any time.
HTTP request
POST https://api.line.me/v2/bot/message/push
Request headers
Request header | Description |
---|---|
Content-Type | application/json |
Authorization | Bearer {Channel Access Token} |
Request body
Include an array of send message objects for your message.
Field | Type | Description |
---|---|---|
to | String | ID of the receiver |
messages | Array of send message object | Messages Max: 5 |
Response
Example JSON response
{}
Returns the status code 200 OK
and an empty JSON object.
Send message object
JSON object which contains the contents of the message you send.
Text
Text example
{
"type": "text",
"text": "Hello, world"
}
Field | Type | Description |
---|---|---|
type | String | text |
text | String | Message text |
Image
Image example
{
"type": "image",
"originalContentUrl": "https://example.com/original.jpg",
"previewImageUrl": "https://example.com/preview.jpg"
}
Field | Type | Description |
---|---|---|
type | String | image |
originalContentUrl | String | Image URL HTTPS JPEG Max: 1024 x 1024 Max: 1 MB |
previewImageUrl | String | Preview image URL HTTPS JPEG Max: 240 x 240 Max: 1 MB |
Video
Video example
{
"type": "video",
"originalContentUrl": "https://example.com/original.mp4",
"previewImageUrl": "https://example.com/preview.jpg"
}
Field | Type | Description |
---|---|---|
type | String | video |
originalContentUrl | String | URL of video file HTTPS mp4 Less than 1 minute Max: 10 MB |
previewImageUrl | String | URL of preview image HTTPS JPEG Max: 240 x 240 Max: 1 MB |
Audio
Audio example
{
"type": "audio",
"originalContentUrl": "https://example.com/original.m4a",
"duration": 240000
}
Field | Type | Description |
---|---|---|
type | String | audio |
originalContentUrl | String | URL of audio file HTTPS m4a Less than 1 minute Max 10 MB |
duration | Number | Length of audio file (milliseconds) |
Location
Location example
{
"type": "location",
"title": "my location",
"address": "〒150-0002 東京都渋谷区渋谷2丁目21−1",
"latitude": 35.65910807942215,
"longitude": 139.70372892916203
}
Field | Type | Description |
---|---|---|
type | String | location |
title | String | Title |
address | String | Address |
latitude | Decimal | Latitude |
longitude | Decimal | Longitude |
Sticker
Sticker example
{
"type": "sticker",
"packageId": "1",
"stickerId": "1"
}
For a list of the sticker IDs for stickers that can be sent with the Messaging API, see Sticker list.
Field | Type | Description |
---|---|---|
type | String | sticker |
packageId | String | Package ID |
stickerId | String | Sticker ID |
Imagemap message
Imagemaps are images with one or more links. You can assign one link for the entire image or multiple links which correspond to different regions of the image.
Imagemap with two tappable regions on the left and the right
{
"type": "imagemap",
"baseUrl": "https://example.com/bot/images/rm001",
"altText": "this is an imagemap",
"baseSize": {
"height": 1040,
"width": 1040
},
"actions": [
{
"type": "uri",
"linkUri": "https://example.com/",
"area": {
"x": 0,
"y": 0,
"width": 520,
"height": 1040
}
},
{
"type": "message",
"text": "hello",
"area": {
"x": 520,
"y": 0,
"width": 520,
"height": 1040
}
}
]
}
Field | Type | Description |
---|---|---|
type | String | imagemap |
baseUrl | String | Base URL of image HTTPS |
altText | String | Alternative text |
baseSize.width | Number | Width of base image (set to 1040px) |
baseSize.height | Number | Height of base image(set to the height that corresponds to a width of 1040px) |
actions | Array of Imagemap action object | Action when tapped |
Base URL
To use an imagemap, you must include URLs with the image width (px) at the end of the base URL so that the client can download the image at the required resolution.
For example, if the base URL is,
https://example.com/images/cats
the URL for a client device to download a 700px image would be
https://example.com/images/cats/700
Below are the image resolutions required by client devices.
- Width: 240px, 300px, 460px, 700px, 1040px
The image used for the imagemap must meet the following specifications:
- Image format: JPEG or PNG
- File size: Up to 1 MB
Imagemap action object
Object which specifies the actions and tappable regions of an imagemap.
When a region is tapped, the user is redirected to the URI specified in uri
and the message specified in message
is sent.
URI action
Field | Type | Description |
---|---|---|
type | String | uri |
linkUri | String | Webpage URL |
area | Imagemap area object | Defined tappable area |
Message action
Field | Type | Description |
---|---|---|
type | String | message |
text | String | Message to send |
area | Imagemap area object | Defined tappable area |
Imagemap area object
Defines the size of the full imagemap with the width as 1040px. The top left is used as the origin of the area.
Field | Type | Description |
---|---|---|
x | Number | Horizontal position of the tappable area |
y | Number | Vertical position of the tappable area |
width | Number | Width of the tappable area |
height | Number | Height of the tappable area |
Template messages
Template messages are messages with predefined layouts which you can customize. There are three types of templates available that can be used to interact with users through your bot.
Field | Type | Description |
---|---|---|
type | String | template |
altText | String | Alternative text for unsupported devices. |
template | Buttons Confirm Carousel |
Object with the contents of the template. |
Buttons
Buttons template message example
{
"type": "template",
"altText": "this is a buttons template",
"template": {
"type": "buttons",
"thumbnailImageUrl": "https://example.com/bot/images/image.jpg",
"title": "Menu",
"text": "Please select",
"actions": [
{
"type": "postback",
"label": "Buy",
"data": "action=buy&itemid=123"
},
{
"type": "postback",
"label": "Add to cart",
"data": "action=add&itemid=123"
},
{
"type": "uri",
"label": "View detail",
"uri": "http://example.com/page/123"
}
]
}
}
Template message with an image, title, text, and multiple action buttons.
Field | Type | Description |
---|---|---|
type | String | buttons |
thumbnailImageUrl | String | Image URL HTTPS JPEG or PNG Aspect ratio: 1:1.51 Max width: 1024px Max: 1 MB |
title | String | Title Max: 40 characters |
text | String | Message text Max: 160 characters (no image or title) Max: 60 characters (message with an image or title) |
actions | Array of template actions | Action when tapped Max: 4 |
The thumbnailImageUrl
and title
fields are optional.
Confirm
Confirm template message example
{
"type": "template",
"altText": "this is a confirm template",
"template": {
"type": "confirm",
"text": "Are you sure?",
"actions": [
{
"type": "message",
"label": "Yes",
"text": "yes"
},
{
"type": "message",
"label": "No",
"text": "no"
}
]
}
}
Template message with two action buttons.
Field | Type | Description |
---|---|---|
type | String | confirm |
text | String | Message text Max: 240 characters |
actions | Array of template actions | Action when tapped Max: 2 |
Carousel
Carousel template message example
{
"type": "template",
"altText": "this is a carousel template",
"template": {
"type": "carousel",
"columns": [
{
"thumbnailImageUrl": "https://example.com/bot/images/item1.jpg",
"title": "this is menu",
"text": "description",
"actions": [
{
"type": "postback",
"label": "Buy",
"data": "action=buy&itemid=111"
},
{
"type": "postback",
"label": "Add to cart",
"data": "action=add&itemid=111"
},
{
"type": "uri",
"label": "View detail",
"uri": "http://example.com/page/111"
}
]
},
{
"thumbnailImageUrl": "https://example.com/bot/images/item2.jpg",
"title": "this is menu",
"text": "description",
"actions": [
{
"type": "postback",
"label": "Buy",
"data": "action=buy&itemid=222"
},
{
"type": "postback",
"label": "Add to cart",
"data": "action=add&itemid=222"
},
{
"type": "uri",
"label": "View detail",
"uri": "http://example.com/page/222"
}
]
}
]
}
}
Template message with multiple columns which can be cycled like a carousel.
Field | Type | Description |
---|---|---|
type | String | carousel |
columns | Array of column objects | Array of columns Max: 5 |
Column object
Field | Type | Description |
---|---|---|
thumbnailImageUrl | String | Image URL HTTPS JPEG or PNG Aspect ratio: 1:1.51 Max width: 1024px Max: 1 MB |
title | String | Title Max: 40 characters |
text | String | Message text Max: 120 characters (no image or title) Max: 60 characters (message with an image or title) |
actions | Array of template actions | Action when tapped Max: 3 |
The thumbnailImageUrl
and title
fields for each column are optional.
Template action
Action to include in your template message.
Postback action
When this action is tapped, a postback event is returned via webhook with the specified string in the data
field.
If you have included the text
field, the string in the text
field is sent as a message from the user.
Field | Type | Description |
---|---|---|
type | String | postback |
label | String | Label for the action Max: 20 characters |
data | String | String returned via webhook in the postback.data property of the postback eventMax: 300 characters |
text | String | Text sent when the action is performed Max: 300 characters |
The text
field is optional.
Message action
When this action is tapped, the string in the text
field is sent as a message from the user.
Field | Type | Description |
---|---|---|
type | String | message |
label | String | Label for the action Max: 20 characters |
text | String | Text sent when the action is performed Max: 300 characters |
URI action
When this action is tapped, the URI specified in the uri
field is opened.
Field | Type | Description |
---|---|---|
type | String | uri |
label | String | Label for the action Max: 20 characters |
uri | String | URI opened when the action is performedhttp , https , tel |
Get content
curl -X GET \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v2/bot/message/{messageId}/content
Response<ResponseBody> response =
LineMessagingServiceBuilder
.create("<channel access token>")
.build()
.getMessageContent("<messageId>")
.execute();
if (response.isSuccessful()) {
ResponseBody content = response.body();
Files.copy(content.byteStream(),
Files.createTempFile("foo", "bar"));
} else {
System.out.println(response.code() + " " + response.message());
}
bot, err := linebot.New(<channel secret>, <channel token>)
if err != nil {
...
}
content, err := bot.GetMessageContent(<messageID>).Do()
if err != nil {
...
}
defer content.Content.Close()
...
client = Line::Bot::Client.new { |config|
config.channel_secret = "<channel secret>"
config.channel_token = "<channel access token>"
}
response = client.get_message_content("<messageId>")
if response.code == 200 {
tf = Tempfile.open("content")
tf.write(response.body)
} else {
p "#{response.code} #{response.body}"
}
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient('<channel access token>');
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => '<channel secret>']);
$response = $bot->getMessageContent('<messageId>');
if ($response->isSucceeded()) {
$tempfile = tmpfile();
fwrite($tempfile, $response->getBody());
} else {
error_log($response->getHTTPStatus() . ' ' . $response->getBody());
}
Retrieve image, video, and audio data sent by users.
HTTP request
GET https://api.line.me/v2/bot/message/{messageId}/content
Request headers
Request header | Description |
---|---|
Authorization | Bearer {Channel Access Token} |
URL parameters
Parameter | Description |
---|---|
messageId | Message ID |
Response
Returns status code 200 OK
and the content in binary.
Get profile
curl -X GET \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v2/bot/profile/{userId}
Response<UserProfileResponse> response =
LineMessagingServiceBuilder
.create("<channel access token>")
.build()
.getProfile("<userId>")
.execute();
if (response.isSuccessful()) {
UserProfileResponse profile = response.body();
System.out.println(profile.getDisplayName());
System.out.println(profile.getPictureUrl());
System.out.println(profile.getStatusMessage());
} else {
System.out.println(response.code() + " " + response.message());
}
bot, err := linebot.New(<channel secret>, <channel token>)
if err != nil {
...
}
res, err := bot.GetUserProfile(<userId>).Do();
if err != nil {
...
}
println(res.Displayname)
println(res.PicutureURL)
println(res.StatusMessage)
client = Line::Bot::Client.new { |config|
config.channel_secret = "<channel secret>"
config.channel_token = "<channel access token>"
}
response = client.get_profile("<userId>")
if response.code == 200 {
contact = JSON.parse(response.body)
p contact['displayName']
p contact['pictureUrl']
p contact['statusMessage']
}
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient('<channel access token>');
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => '<channel secret>']);
$response = $bot->getProfile('<userId>');
if ($response->isSucceeded()) {
$profile = decode_json($response->getBody);
echo $profile->{'displayName'};
echo $profile->{'pictureUrl'};
echo $profile->{'statusMessage'};
}
Get user profile information.
HTTP request
GET https://api.line.me/v2/bot/profile/{userId}
Request headers
Request header | Description |
---|---|
Authorization | Bearer {Channel Access Token} |
URL parameters
Parameter | Description |
---|---|
userId | User ID |
Response
Response body example
{
"displayName":"LINE taro",
"userId":"Uxxxxxxxxxxxxxx...",
"pictureUrl":"http://obs.line-apps.com/...",
"statusMessage":"Hello, LINE!"
}
Returns the status code 200 OK
and a JSON object with the following parameters.
Field | Type | Description |
---|---|---|
displayName | String | Display name |
userId | String | User ID |
pictureUrl | String | Image URL |
statusMessage | String | Status message |
Leave
curl -X POST \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v2/bot/room/{roomId}/leave
Response<BotApiResponse> response =
LineMessagingServiceBuilder
.create("<channel access token>")
.build()
.leaveRoom("<roomId>")
.execute();
System.out.println(response.code() + " " + response.message());
bot, err := linebot.New(<channel secret>, <channel token>)
if err != nil {
...
}
if _, err := bot.LeaveRoom(<roomId>).Do(); err != nil {
...
}
client = Line::Bot::Client.new { |config|
config.channel_secret = "<channel secret>"
config.channel_token = "<channel access token>"
}
response = client.leave_room("<roomId>")
p response.body
$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient('<channel access token>');
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => '<channel secret>']);
$response = $bot->leaveRoom('<roomId>');
echo $response->getHTTPStatus() . ' ' . $response->getBody();
Leave a group or room.
HTTP request
POST https://api.line.me/v2/bot/group/{groupId}/leave
POST https://api.line.me/v2/bot/room/{roomId}/leave
Request headers
Request header | Description |
---|---|
Authorization | Bearer {Channel Access Token} |
URL parameters
Parameter | Description |
---|---|
groupId | Group ID |
roomId | Room ID |
Response
JSON response example
{}
Returns the status code 200 OK
and an empty JSON object.
LINE Beacon
LINE Beacon is a service which lets your bot receive notifications through webhooks when a connected LINE user comes close to a beacon. This lets you better target specific users with customized services.
Connecting your bot with Beacon
Enable Beacon for your bot account on the LINE Official Account Manager.
Receiving webhooks from a LINE user
- Make sure that your smartphone has bluetooth turned on
- Select Use LINE Beacon
- LINE -> Settings -> Privacy -> Use LINE Beacon
- Add the bot account as a friend
- Information is only sent from LINE users who have added the bot account as a friend
- Make sure that the beacon is turned on and bring your smartphone close to it
- Information is sent to the LINE Platform once the LINE app detects the beacon
Bringing information together with Beacon Layer
In certain stores and buildings, a banner (Beacon Layer) will appear above the friend list or talk list when the user comes close to a beacon. By tapping the Beacon Layer, it’s possible to select the “Use LINE Beacon” option, add the bot account as a friend, and send a message all at the same time.
If you are interested in using LINE Beacon, please make an inquiry at LINE Partner.
Social REST API
How to use the APIs
To use the REST APIs, you need to have an access token.
The following APIs can be used with the default permissions.
Validating the access token
Example of validating the access token
curl -X GET \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v1/oauth/verify
{
"channelId":1350031035,
"mid":"ub00b9ac609e51f4707cd86d8e797491b"
}
Validates the access token.
Request header
Item | Description |
---|---|
HTTP method | GET |
Endpoint URL | https://api.line.me/v1/oauth/verify |
Required request header | Authorization: Bearer {ACCESS_TOKEN} |
Query parameter
Name | Type | Default value | Description |
---|---|---|---|
extend | String | false | Optional. Set to “true” to see the expiry date of the access token. |
Response
Responses are returned in JSON.
Property | Type | Description |
---|---|---|
mid | String | Unique ID of the user who had the access token validated. |
channelId | Integer | Channel ID that the access token is issued to. |
expire | Integer | Expiry date of the access token. Expressed in milliseconds from epoch (January 1 1970 00:00:00 GMT). |
Error response
The following responses may be returned when an error occurs.
HTTP status | Response body and description |
---|---|
401 | {“statusCode”:“401”,“statusMessage”:“authentication scheme not found.”} Authorization header required Include Authorization: Bearer {ACCESS_TOKEN} in the HTTP header |
401 | {“statusCode”:“401”,“statusMessage”:“invalid token”} Invalid access token |
401 | {“statusCode”:“412”,“statusMessage”:“accessToken expired(1)”} Access token invalidated by the LINE Platform |
401 | {“statusCode”:“412”,“statusMessage”:“accessToken expired”} The access token has expired |
Reissuing access tokens
Example of reissuing an access token
curl -X POST \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'refreshToken=123ab456cdef8910ghu' \
https://api.line.me/v1/oauth/accessToken
{
"mid":"u0047556f2e40dba2456887320ba7c76d",
"accessToken":"ud81c65b01f5a59d39f8163815b34dad7aXNzdWVkV",
"expire":1371721724089,
"refreshToken":"ZkcqmSWsKnMSXq5hPpWd"
}
Refresh tokens are used to reissue access tokens. Refresh tokens (refresh_token
) are included in the JSON response that is returned when issuing an access token.
Refresh tokens are valid for 10 days from when the access token expires. If the refresh token expires, the user will need to be authorized again.
Request header
Item | Description |
---|---|
HTTP method | POST |
Endpoint URL | https://api.line.me/v1/oauth/accessToken |
Required request header | Content-Type: application/x-www-form-urlencoded Authorization: Bearer {ACCESS_TOKEN} |
Request body
The request body is in a form-encoded format.
Name | Type | Description |
---|---|---|
refreshToken | String | refresh_token from the JSON response when retrieving the access token. |
Response
The response is returned in JSON.
Property | Type | Description |
---|---|---|
mid | String | Unique ID of the user |
accessToken | String | Access token (valid for 10 days) |
expire | Integer | Expiry date of the access token. Expressed in milliseconds from epoch (January 1 1970 00:00:00 GMT). |
refreshToken | String | Token used to reissue an access token |
Error response
The following responses may be returned when an error occurs.
HTTP status | Response body and description |
---|---|
401 | {“statusCode”:“412”,“statusMessage”:“accessToken expired(1)”} Access token invalidated by the LINE Platform |
401 | {“statusCode”:“412”,“statusMessage”:“accessToken expired(2)”} The user has logged out of the LINE app |
401 | {“statusCode”:“412”,“statusMessage”:“accessToken expired”} Access token expired |
401 | {“statusCode”:“401”,“statusMessage”:“invalid token”} Invalid access token |
401 | {“statusCode”:“401”,“statusMessage”:“invalid refreshToken”} Invalid refresh token |
403 | {“statusCode”:“414”,“statusMessage”:“TOKEN_NOT_REFRESHABLE”} Cannot reissue access token |
401 | {“statusCode”:“411”,“statusMessage”:“TOKEN_INVALID_TOKEN”} The access token and refresh token pair are invalid |
401 | {“statusCode”:“401”,“statusMessage”:“channel secret is not matched. maybe abusing?”} Channel secret does not match |
403 | {“statusCode”:“418”,“statusMessage”:“CHANNEL_INACTIVE”} Invalid Channel |
Logout
Logout example
curl -X DELETE \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v1/oauth/logout
{"result":"OK"}
Logs the user out of the app. When the user logs out, the access token is invalidated.
Request header
Item | Description |
---|---|
HTTP method | DELETE |
Endpoint URL | https://api.line.me/v1/oauth/logout |
Required request header | Authorization: Bearer {ACCESS_TOKEN} |
Response
The response is in JSON. There are no error responses.
Property | Type | Description |
---|---|---|
result | String | Fixed value “OK” |
Get user profiles
Example of getting a user profile
curl -X GET \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
https://api.line.me/v1/profile
{
"displayName":"Brown",
"mid":"u0047556f2e40dba2456887320ba7c76d",
"pictureUrl":"http://example.com/abcdefghijklmn",
"statusMessage":"Hello, LINE!"
}
You can retrieve a user’s display name, profile image, and status message.
Request header
Item | Description |
---|---|
HTTP method | GET |
Endpoint URL | https://api.line.me/v1/profile |
Required request header | Authorization: Bearer {ACCESS_TOKEN} |
Response
The response is in JSON.
Property | Type | Description |
---|---|---|
displayName | String | User’s display name |
mid | String | Unique ID of the user |
pictureUrl | String | Profile image URL. “http” image URL. |
statusMessage | String | User’s status message. Not included in the response if the user doesn’t have a status message. |
Profile image thumbnails
Example of how to retrieve a large profile image
http://obs.line-apps.com/abcdefghijklmn/large
You can change the user’s profile image size by adding a suffix to the URL.
Image size | Suffix |
---|---|
200 x 200 | /large |
51 x 51 | /small |
Android SDK API
The LINE SDK for Android lets you call APIs without worrying about access tokens because the SDK automatically refreshes them. The LINE SDK for Android provides the following APIs.
- Get access tokens
- Get user profiles
Get access tokens
Example of how to get access tokens
Activity activity = ...;
LineAuthManager authManager = ...;
LineLoginFuture loginFuture = authManager.login(activity);
loginFuture.addFutureListener(new LineLoginFutureListener() {
@Override
public void loginComplete(LineLoginFuture future) {
switch(future.getProgress()) {
case SUCCESS:
...
AccessToken token = future.getAccessToken();
String mid = token.mid; // User ID
String accessToken = token.accessToken;
long expire = token.expire; // Expired datetime
String refreshToken = token.refreshToken;
// Send these data to your server.
break;
...
}
}
});
Methods
LineLoginFuture#getAccessToken()
Implementation
You can call the Social REST API from the server once you have retrieved an access token from the LINE SDK and passed it to the server. We recommend hashing the access token and sending the hash over SSL to the server.
Get user profiles
Requirements
To retrieve user profiles, the following are required.
- The “PROFILE” permission selected under “Allowed permissions” for your Channel
- The user agrees to share profile information on the permissions screen
Methods
ApiClient#getMyProfile()
Example of retrieving user profile
ApiClient apiclient = LineSdkContextManager.getSdkContext().getApiClient();
apiClient.getMyProfile(new ApiRequestFutureListener() {
@Override
public void requestComplete(ApiRequestFuture future) {
switch(future.getStatus()) {
case SUCCESS:
Profile profile = future.getResponseObject();
String mid = profile.mid;
String displayName = profile.displayName;
String pictureUrl = profile.pictureUrl;
String statusMessage = profile.statusMessage;
// do something...
break;
case FAILED:
default:
Throwable cause = future.getCause();
// do something for error...
break;
};
}
});
Implementation
The object retrieves the profile information from the getResponseObject()
method of ApiRequestFutureListener
, which receives the result of the request. The details of the object are as follows.
Property | Description |
---|---|
displayName | User’s nickname |
mid | Unique ID of the user |
pictureUrl | User’s profile image URL |
statusMessage | User’s status message. |
Profile image thumbnails
Example of how to retrieve a large profile image
http://obs.line-apps.com/abcdefghijklmn/large
You can change the size of the user’s profile thumbnail image by adding a suffix to the URL.
Image size | suffix |
---|---|
200 x 200 | /large |
51 x 51 | /small |
iOS SDK API
The LINE SDK for iOS lets you call APIs without worrying about access tokens because the SDK automatically refreshes them. The LINE SDK for iOS provides the following APIs.
- Get access tokens
- Get user profiles
Get access tokens
Example of how to get access tokens
- (void)lineAdapterAuthorizationDidChange:(NSNotification*)aNotification
{
LineAdapter *_adapter = [aNotification object];
if ([_adapter isAuthorized])
{
LineApiClient *apiClient = [adapter getLineApiClient];
NSString *accessToken = apiClient.accessToken;
NSString *refreshToken = apiClient.refreshToken;
// The above information will be sent to the
// backend server and processed accordingly.
}
else
{
...
}
}
Methods
apiClient#accessToken()
Implementation
You can call the Social REST API from the server once you have retrieved an access token from the LINE SDK and passed it to the server. We recommend hashing the access token and sending the hash over SSL to the server.
Get user profiles
Requirements
To retrieve user profiles, the following are required.
- The “PROFILE” permission selected under “Allowed permissions” for your Channel
- The user agrees to share profile information on the permissions screen
Methods
LineApiClient#getMyProfileWithResultBlock:
Example of retrieving user profile
[[adapter getLineApiClient] getMyProfileWithResultBlock:^(NSDictionary *aResult, NSError *aError)
{
if (aResult)
{
// API call was successfully.
NSLog(@"displayName : %@", aResult[@"displayName"]);
NSLog(@"mid : %@", aResult[@"mid"]);
NSLog(@"pictureUrl : %@", aResult[@"pictureUrl"]);
NSLog(@"statusMessage : %@", aResult[@"statusMessage"]);
}
else
{
// API call failed.
NSDictionary *userInfo = [aError userInfo];
NSLog(@"statusCode : %@", userInfo[@"statusCode"]);
NSLog(@"statusMessage : %@", userInfo[@"statusMessage"]);
}
}];
Implementation example
This code example shows how to retrieve user profile information. The following are details about the object which is retrieved.
Property | Description |
---|---|
displayName | User’s nickname |
mid | Unique ID of the user |
pictureUrl | User’s profile image URL |
statusMessage | User’s status message |
Profile image thumbnails
Example of how to retrieve a large profile image
http://obs.line-apps.com/abcdefghijklmn/large
You can change the size of the user’s profile thumbnail image by adding a suffix to the URL.
Image size | suffix |
---|---|
200 x 200 | /large |
51 x 51 | /small |