shell java ruby go php perl python

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.

Webhooks

Receive notifications in real-time when a user sends a message or friends your account.

Reply Message API

Reply to messages from users.

Push Message API

Send messages to users when you want to.

Multicast API

Send messages to multiple users at any time.

Get Content API

Download image, video, and audio data sent from users.

Get Profile API

Get user profile information.

Leave API

Leave a group or room.

LINE Bot SDK

The LINE Bot SDK is 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.

Getting Started

Check getting started to start developing with Messaging API.

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

Response headers

The following HTTP headers are included in Messaging API responses.

Response header Description
X-Line-Request-Id ID generated for each request

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, 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 Description
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. You can access the Channel Console from the accounts page of the LINE Business Center.

Your bot server should receive and handle this request appropriately for the event.

Request headers

Request header Description
X-Line-Signature Used for signature validation

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.

Signature Validation

Example of signature validation

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 validation

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 validation

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 validation

$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

Example of signature validation

use Digest::SHA 'hmac_sha256';
use MIME::Base64 'decode_base64';

my $channel_secret= ... # Channel Secret string
my $http_body = ... # Request body string
my $signature = decode_base64(hmac_sha256($http_body, $channel_secret));
# Compare X-Line-Signature request header string and the signature

Example of signature validation

import base64
import hashlib
import hmac

channel_secret = ... # Channel secret string
body = ... # Request body string
hash = hmac.new(channel_secret.encode('utf-8'),
    body.encode('utf-8'), hashlib.sha256).digest()
signature = base64.b64encode(hash)
# Compare X-Line-Signature request header 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.

  1. With the Channel secret as the secret key, your application retrieves the digest value in the request body created using the HMAC-SHA256 algorithm.
  2. The server confirms that the signature in the request header matches the digest value which is Base64 encoded.

Webhook event object

Example 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 Get 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 Get 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 Get 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 enters or leaves the range of 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

Depending on the type of event, the beacon.type field contains the following strings.

beacon.type Description
enter Entered beacon’s reception range
leave Left beacon’s reception range
banner Tapped beacon banner

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->getRawBody();
use LINE::Bot::API;
use LINE::Bot::API::Builder::SendMessage;

my $bot = LINE::Bot::API->new(
    channel_secret       => "<channel secret>",
    channel_access_token => "<channel access token>",
);

my $messages = LINE::Bot::API::Builder::SendMessage->new(
)->add_text(
    text => 'hello',
);
my $res = $bot->reply_message("<replyToken>", $messages->build);
unless ($res->is_success) {
    # error handling
    ....
}
from linebot import LineBotApi
from linebot.models import TextSendMessage

line_bot_api = LineBotApi('<channel access token>')

try:
    line_bot_api.reply_message('<reply_token>', TextSendMessage(text='Hello World!'))
except linebot.LineBotApiError as e:
    # error handle
    ...

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 Required Description
replyToken String yes replyToken received via webhook
messages Array of send message objects yes Messages
Max: 5

Response

Example JSON response

{}

Returns the status code 200 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->getRawBody();
use LINE::Bot::API;
use LINE::Bot::API::Builder::SendMessage;

my $bot = LINE::Bot::API->new(
    channel_secret       => "<channel secret>",
    channel_access_token => "<channel access token>",
);

my $messages = LINE::Bot::API::Builder::SendMessage->new(
)->add_text(
    text => 'hello',
);
my $res = $bot->push_message("<to>", $messages->build);
unless ($res->is_success) {
    # error handling
    ....
}
from linebot import LineBotApi
from linebot.models import TextSendMessage

line_bot_api = LineBotApi('<channel access token>')

try:
    line_bot_api.push_message('<to>', TextSendMessage(text='Hello World!'))
except linebot.LineBotApiError as e:
    # error handle
    ...

Send messages to a user, group, or room 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 Required Description
to String yes ID of the receiver
messages Array of send message objects yes Messages
Max: 5

Response

Example JSON response

{}

Returns the status code 200 and an empty JSON object.

Multicast

Multicast API example

curl -X POST \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer {ENTER_ACCESS_TOKEN}' \
-d '{
    "to": ["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        },
        {
            "type":"text",
            "text":"Hello, world2"
        }
    ]
}' https://api.line.me/v2/bot/message/multicast

Send messages to multiple users at any time.

HTTP request

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

Request headers

Request header Description
Content-Type application/json
Authorization Bearer {Channel Access Token}

Request body

Include an array of send message objects with the messages to be sent.

Field Type Required Description
to Array of strings yes IDs of the receivers
Max: 150 users
messages Array of send message objects yes Messages
Max: 5

Response

Example JSON response

{}

Returns the status code 200 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 Required Description
type String yes text
text String yes Message text
Max: 2000 characters

Text example with emoticon


{
    "type": "text",
    "text": "Hello, world 􀂲"
}

You can include emoticons in your message text. Because emoticons are a part of Unicode, they must be converted from their character codes.
Note that the character code, 0x1000B2, is used in the example on the right. Although the emoticon does not show up correctly in the browser, it will show up in LINE.
For a list of emoticons that can be sent with the Messaging API, see emoticon list.

Image

Image example

{
    "type": "image",
    "originalContentUrl": "https://example.com/original.jpg",
    "previewImageUrl": "https://example.com/preview.jpg"
}
Field Type Required Description
type String yes image
originalContentUrl String yes Image URL (Max: 1000 characters)
HTTPS
JPEG
Max: 1024 x 1024
Max: 1 MB
previewImageUrl String yes Preview image URL (Max: 1000 characters)
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 Required Description
type String yes video
originalContentUrl String yes URL of video file (Max: 1000 characters)
HTTPS
mp4
Less than 1 minute
Max: 10 MB
previewImageUrl String yes URL of preview image (Max: 1000 characters)
HTTPS
JPEG
Max: 240 x 240
Max: 1 MB

Audio

Audio example

{
    "type": "audio",
    "originalContentUrl": "https://example.com/original.m4a",
    "duration": 240000
}
Field Type Required Description
type String yes audio
originalContentUrl String yes URL of audio file (Max: 1000 characters)
HTTPS
m4a
Less than 1 minute
Max 10 MB
duration Number yes 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 Required Description
type String yes location
title String yes Title
Max: 100 characters
address String yes Address
Max: 100 characters
latitude Decimal yes Latitude
longitude Decimal yes 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 Required Description
type String yes sticker
packageId String yes Package ID
stickerId String yes 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 Required Description
type String yes imagemap
baseUrl String yes Base URL of image (Max: 1000 characters)
HTTPS
altText String yes Alternative text
Max: 400 characters
baseSize.width Number yes Width of base image (set to 1040px)
baseSize.height Number yes Height of base image(set to the height that corresponds to a width of 1040px)
actions Array of Imagemap action object yes Action when tapped
Max: 50

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.

The image used for the imagemap must meet the following specifications:

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 Required Description
type String yes uri
linkUri String yes Webpage URL
Max: 1000 characters
area Imagemap area object yes Defined tappable area

Message action

Field Type Required Description
type String yes message
text String yes Message to send
Max: 400 characters
area Imagemap area object yes 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 Required Description
x Number yes Horizontal position of the tappable area
y Number yes Vertical position of the tappable area
width Number yes Width of the tappable area
height Number yes 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 Required Description
type String yes template
altText String yes Alternative text for unsupported devices.
Max: 400 characters
template Buttons
Confirm
Carousel
yes 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 Required Description
type String yes buttons
thumbnailImageUrl String no Image URL (Max: 1000 characters)
HTTPS
JPEG or PNG
Aspect ratio: 1:1.51
Max width: 1024px
Max: 1 MB
title String no Title
Max: 40 characters
text String yes Message text
Max: 160 characters (no image or title)
Max: 60 characters (message with an image or title)
actions Array of template actions yes Action when tapped
Max: 4

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 Required Description
type String yes confirm
text String yes Message text
Max: 240 characters
actions Array of template actions yes Action when tapped
Set 2 actions for the 2 buttons

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 Required Description
type String yes carousel
columns Array of column objects yes Array of columns
Max: 5

Column object

Field Type Required Description
thumbnailImageUrl String no Image URL (Max: 1000 characters)
HTTPS
JPEG or PNG
Aspect ratio: 1:1.51
Max width: 1024px
Max: 1 MB
title String no Title
Max: 40 characters
text String yes Message text
Max: 120 characters (no image or title)
Max: 60 characters (message with an image or title)
actions Array of template actions yes Action when tapped
Max: 3

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 Required Description
type String yes postback
label String yes Label for the action
Max: 20 characters
data String yes String returned via webhook in the postback.data property of the postback event
Max: 300 characters
text String no Text sent when the action is performed
Max: 300 characters

Message action

When this action is tapped, the string in the text field is sent as a message from the user.

Field Type Required Description
type String yes message
label String yes Label for the action
Max: 20 characters
text String yes 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 Required Description
type String yes uri
label String yes Label for the action
Max: 20 characters
uri String yes URI opened when the action is performed (Max: 1000 characters)
http, https, tel

Get content

Get content request example

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>")
case response
when Net::HTTPSuccess then
  tf = Tempfile.open("content")
  tf.write(response.body)
else
  p "#{response.code} #{response.body}"
end
$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->getRawBody());
} else {
    error_log($response->getHTTPStatus() . ' ' . $response->getRawBody());
}
use LINE::Bot::API;

my $bot = LINE::Bot::API->new(
    channel_secret       => "<channel secret>",
    channel_access_token => "<channel access token>",
);

my $res = $bot->get_message_content("<messageId>");
unless ($res->is_success) {
    # error handling
    ....
}
my $filename = $ret->fh->filename;
open my $fh, '<', $file or die "$!: $file";
from linebot import LineBotApi

line_bot_api = LineBotApi('<channel access token>')

message_content = line_bot_api.get_content('<message_id>')
with open(file_path, 'wb') as fd:
    for chunk in message_content.iter_content():
        fd.write(chunk)

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 and the content in binary.

Get profile

Get profile request example

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>")
case response
when Net::HTTPSuccess then
  contact = JSON.parse(response.body)
  p contact['displayName']
  p contact['pictureUrl']
  p contact['statusMessage']
else
  p "#{response.code} #{response.body}"
end
$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 = $response->getJSONDecodedBody();
    echo $profile['displayName'];
    echo $profile['pictureUrl'];
    echo $profile['statusMessage'];
}
use LINE::Bot::API;

my $bot = LINE::Bot::API->new(
    channel_secret       => "<channel secret>",
    channel_access_token => "<channel access token>",
);

my $res = $bot->get_profile("<userId>");
unless ($res->is_success) {
    # error handling
    ....
}

say $ret->display_name;
say $ret->user_id;
say $ret->picture_url;
say $ret->status_message;
from linebot import LineBotApi

line_bot_api = LineBotApi('<channel access token>')

try:
    profile = line_bot_api.get_profile('<user_id>')
    print(profile.display_name)
    print(profile.user_id)
    print(profile.picture_url)
    print(profile.status_message)
except linebot.LineBotApiError as e:
    # error handle
    ...

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 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

Leave request example

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->getRawBody();
use LINE::Bot::API;

my $bot = LINE::Bot::API->new(
    channel_secret       => "<channel secret>",
    channel_access_token => "<channel access token>",
);

my $res = $bot->leave_room("<roomId>");
unless ($res->is_success) {
    # error handling
    ....
}
from linebot import LineBotApi

line_bot_api = LineBotApi('<channel access token>')

try:
    line_bot_api.leave_room('<room_id>')
except linebot.LineBotApiError as e:
    # error handle
    ...

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 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 enters or leaves the range of to a beacon. This lets you better target specific users with customized services.

Connecting your bot with Beacon

Enable Beacon for your Messaging API account on the LINE Official Account Manager.

Receiving webhooks from a LINE user

  1. Make sure that your smartphone has bluetooth turned on
  2. Select Use LINE Beacon
    • LINE > Settings > Privacy > Use LINE Beacon
  3. Add the bot account as a friend
    • Information is only sent from LINE users who have added the bot account as a friend
  4. 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 Banner

In certain stores and buildings, a banner (Beacon Banner) will appear above the friend list or talk list when the user comes close to a beacon. By tapping the Beacon Banner, 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.

Example of Beacon Banner
(Example of “Beacon Banner”. The green area of this picture is the banner.)

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 {“error”:“401”,“error_desciption”:“authentication scheme not found.”}
Authorization header required
Include Authorization: Bearer {ACCESS_TOKEN} in the HTTP header
401 {“error”:“401”,“error_desciption”:“invalid token”}
Invalid access token
401 {“error”:“412”,“error_desciption”:“accessToken expired(1)”}
Access token invalidated by the LINE Platform
401 {“error”:“412”,“error_desciption”:“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 'grant_type=refresh_token&client_id={ENTER_CLIENT_ID}&client_secret={ENTER_CLIENT_SECRET}&refreshToken={ENTER_REFRESH_TOKEN}' \
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
grant_type String Fixed refresh_token
refresh_token String Refresh token to reissue an access token
client_id String Channel ID. Found on the Channel Console.
client_secret String Channel secret. Found on the Channel Console.

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 {“error”:“412”,“error_desciption”:“accessToken expired(1)”}
Access token invalidated by the LINE Platform
401 {“error”:“412”,“error_desciption”:“accessToken expired(2)”}
The user has logged out of the LINE app
401 {“error”:“412”,“error_desciption”:“accessToken expired”}
Access token expired
401 {“error”:“401”,“error_desciption”:“invalid token”}
Invalid access token
401 {“error”:“401”,“error_desciption”:“invalid refreshToken”}
Invalid refresh token
403 {“error”:“414”,“error_desciption”:“TOKEN_NOT_REFRESHABLE”}
Cannot reissue access token
401 {“error”:“411”,“error_desciption”:“TOKEN_INVALID_TOKEN”}
The access token and refresh token pair are invalid
401 {“error”:“401”,“error_desciption”:“channel secret is not matched. maybe abusing?”}
Channel secret does not match
403 {“error”:“418”,“error_desciption”:“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

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

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.

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

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

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.

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