NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #2856 most downloaded on Packagist
SDK of the LINE BOT API for PHP
Last release 9 days ago
29 Sep 2026
Ships fairly regularly
a new release about every 2 months
Rarely documented
notes for 11 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
105 releases · first in 2016
This version adds the templated LINE notification message (PNP) API, and lets you assign a custom aggregation unit (CAU) to LINE notification messages
This version adds the templated LINE notification message (PNP) API, and lets you assign a custom aggregation unit (CAU) to LINE notification messages.
Schema changes: line/line-openapi#131
templateKey and substituting values into the template's emphasizedItem, items, and buttons. New endpoint: POST /v2/bot/message/pnp/templated/push.GET /v2/bot/message/delivery/pnp/templated.customAggregationUnits, so their delivery can be aggregated per unit with the existing unit-based statistics APIs.This is a partner-only feature that requires an application. For more details, see:
use LINE\Clients\MessagingApi\Api\MessagingApiApi;
use LINE\Clients\MessagingApi\Configuration;
use LINE\Clients\MessagingApi\Model\PnpTemplatedMessageRequest;
use LINE\Clients\MessagingApi\Model\PnpTemplatedMessageBody;
use LINE\Clients\MessagingApi\Model\PnpTemplatedEmphasizedItem;
use LINE\Clients\MessagingApi\Model\PnpTemplatedItem;
use LINE\Clients\MessagingApi\Model\PnpTemplatedButton;
$config = new Configuration();
$config->setAccessToken('YOUR_CHANNEL_ACCESS_TOKEN');
$messagingApi = new MessagingApiApi(client: new \GuzzleHttp\Client(), config: $config);
$request = new PnpTemplatedMessageRequest([
// Phone number normalized to E.164 and hashed with SHA256
'to' => '0123...hashed_phone_number...cdef',
'templateKey' => 'order_confirmation',
'body' => new PnpTemplatedMessageBody([
'emphasizedItem' => new PnpTemplatedEmphasizedItem(['itemKey' => 'amount', 'content' => '$42.00']),
'items' => [
new PnpTemplatedItem(['itemKey' => 'order_id', 'content' => 'A1234567']),
new PnpTemplatedItem(['itemKey' => 'shop_name', 'content' => 'LINE Store']),
],
'buttons' => [
new PnpTemplatedButton(['buttonKey' => 'detail', 'url' => 'https://example.com/orders/A1234567']),
],
]),
'customAggregationUnits' => ['promotion_a'],
]);
// The second argument is the X-Line-Delivery-Tag (16-100 chars),
// which is returned in the delivery completion webhook.
$messagingApi->pushTemplatedMessagesByPhone($request, 'order-A1234567-0001');use LINE\Clients\MessagingApi\Api\MessagingApiApi;
use LINE\Clients\MessagingApi\Configuration;
$config = new Configuration();
$config->setAccessToken('YOUR_CHANNEL_ACCESS_TOKEN');
$messagingApi = new MessagingApiApi(client: new \GuzzleHttp\Client(), config: $config);
// GET /v2/bot/message/delivery/pnp/templated (date: yyyyMMdd, UTC+9)
$response = $messagingApi->getPNPTemplatedMessageStatistics('20240916');
echo $response->getStatus() . PHP_EOL; // ready / unready / unavailable_for_privacy / out_of_service
if ($response->getStatus() === 'ready') {
echo $response->getSuccess() . PHP_EOL;
}Full Changelog: v12.7.0...v12.8.0
This release is prepared by @mokuzon
One column per quarter.
Support Message Edited Webhook by @github-actions[bot] in #865
Add MessageEditedEvent webhook event to support the message editing feature.
When a user edits a message in a group that includes a LINE Official Account, a webhook event with type=messageEdited is sent.
messageEdited webhook events may arrive out of order. The event with the largest timestamp represents the latest edit state.Please also refer to the document: https://developers.line.biz/en/reference/messaging-api/#edit-event
(original PR is line/line-openapi#129)
use LINE\Webhook\Model\MessageEditedEvent;
use LINE\Webhook\Model\TextMessageContent;
foreach ($parsedEvents->getEvents() as $event) {
if ($event instanceof MessageEditedEvent
&& $event->getMessage() instanceof TextMessageContent
) {
echo "Message {$event->getMessage()->getId()} was edited to: {$event->getMessage()->getText()}";
}
}Full Changelog: v12.6.0...v12.7.0
This release is prepared by @habara-k
This release supports the new Rich Menu inshgit APIs. For details on the API, please see below.
This release supports the new Rich Menu inshgit APIs.
For details on the API, please see below.
AudienceGroupFailedType emum by @github-actions[bot] in #857Full Changelog: v12.5.0...v12.6.0
This release is prepared by @mokuzon
This release adds wrapper methods for ChannelAccessTokenApi#issueStatelessChannelToken , making stateless channel access token issuance simpler for bo
This release adds wrapper methods for ChannelAccessTokenApi#issueStatelessChannelToken, making stateless channel access token issuance simpler for both JWT assertion and client secret authentication. The original method accepts all parameters for two different authentication patterns, making it unclear which to pass for each pattern. These wrappers make the distinction explicit through their names and signatures.
- $token = $client->issueStatelessChannelToken(
- grantType: 'client_credentials',
- clientAssertionType: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
- clientAssertion: $clientAssertion,
- );
+ $token = $client->issueStatelessChannelTokenByJWTAssertion(
+ clientAssertion: $clientAssertion,
+ );- $token = $client->issueStatelessChannelToken(
- grantType: 'client_credentials',
- clientId: $channelId,
- clientSecret: $channelSecret,
- );
+ $token = $client->issueStatelessChannelTokenByClientSecret(
+ clientId: $channelId,
+ clientSecret: $channelSecret,
+ );Full Changelog: v12.4.0...v12.5.0
This release is prepared by @habara-k
Add new AudienceGroupType TRACKINGTAG_WEBTRAFFIC to Audience Group API by @github-actions[bot] in #784
TRACKINGTAG_WEBTRAFFIC to AudienceGroupType EnumWe have supported for the new audience‑group type TRACKINGTAG_WEBTRAFFIC (Tracking Tag Webtraffic audience) to the OpenAPI schema.
Updated AudienceGroupType enumeration
TRACKINGTAG_WEBTRAFFICThis update enables correct identification and handling of audience groups built from Tracking Tag Webtraffric.
For more information, please refer to the links provided above.
(original PR is line/line-openapi#118)
Full Changelog: v12.3.0...v12.4.0
This release is prepared by @eucyt
Support mark as read by token API by @github-actions[bot] in #757
We have released a new Mark as Read API that allows developers to mark a user’s messages as read.
Previously, this functionality was available only to partners, but it is now publicly available.
When your server receives a user message via Webhook, the MessageContent will include a new field: markAsReadToken.
By calling the Mark as Read API with this token, all messages in the chat room up to and including that message will be marked as read.
Note: This feature assumes that your service uses the chat feature through Official Account Manager.
If chat is not enabled, messages from users are automatically marked as read, making this API unnecessary.
For more details, please refer to the release note: https://developers.line.biz/en/news/2025/11/05/mark-as-read/
(original PR is line/line-openapi#115)
$bot->markAsReadByToken(new MarkAsReadByTokenRequest([
'markAsReadToken' => $message->markAsReadToken,
]))Full Changelog: v12.2.0...v12.3.0
This release is prepared by @habara-k
Make the constructor automatically set the discriminator value by @eucyt in #752
Previously, when creating a polymorphic model, you have to set the discriminator value manually each time, even though the value is obvious.
$message = (new TextMessage())
->setType(\LINE\Constants\MessageType::TEXT) // this is redundant.
->setText('hello!');With this release, the discriminator value will be automatically set in the constructor.
$message = (new TextMessage())
->setText('hello!');
$this->assertEquals('text', $message->getType()); // PassedFull Changelog: v12.1.0...v12.2.0
This release is prepared by @eucyt
Add forbidPartialDelivery option to the Narrowcast Limit Object by @github-actions[bot] in #750
We add a new forbidPartialDelivery option to the Narrowcast Limit Object.
When set to true, this option prevents messages from being delivered to only a subset of the target audience.
If partial delivery occurs, the narrowcast request will succeed but fail asynchronously.
You can verify whether the message delivery was canceled by checking the narrowcast message progress.
This property can only be set to true when upToRemainingQuota is also true.
For more details, see the https://developers.line.biz/en/news/2025/10/21/narrowcast-message-update/.
$bot->narrowcast(new NarrowcastRequest([
'messages' => [
(new TextMessage(['text' => 'Hello']))->setType('text'),
],
'limit' => new Limit([
'max' => 1000,
'upToRemainingQuota' => true,
'forbidPartialDelivery' => true
])
]))(original PR is line/line-openapi#114)
Previously, when upToRemainingQuota was set to true, messages could be partially delivered if the remaining message quota was smaller than the target audience size.
With the new forbidPartialDelivery option, you can now ensure that such partial deliveries do not occur.
Full Changelog: v12.0.0...v12.1.0
This release is prepared by @habara-k
This change introduces polymorphism support in API responses. ⚠️ This includes breaking changes.
This change introduces polymorphism support in API responses.
⚠️ This includes breaking changes.
Polymorphic types in responses were not handled correctly.
As a result, all responses were deserialized into the base class, making it impossible to access subclass-specific properties.
$api = new MessagingApiApi($client);
$richMenuListResponse = $api->getRichMenuList();
// Even if type=postback, it becomes an instance of Action, not PostbackAction
$action = $richMenuListResponse->getRichmenus()[0]->getAreas()[0]->getAction();
// Error: Call to undefined method LINE\Clients\MessagingApi\Model\Action::getData()
$data = $action->getData();
// or simply null
$data = $action["data"];Polymorphic types in responses are now properly supported.
Each response is deserialized into the correct subclass, allowing subclass properties to be accessed safely.
This change applies to all API responses, not just this specific endpoint.
If your existing code depends on the base class types, you will need to update it accordingly.
You can now directly access subclass-specific properties when polymorphism is involved.
When the discriminator is unknown, it is deserialized into the parent class, and no error occurs.
$api = new MessagingApiApi($client);
$richMenuListResponse = $api->getRichMenuList();
// If type=postback, it will now become an instance of PostbackAction
$action = $richMenuListResponse->getRichmenus()[0]->getAreas()[0]->getAction();
// You can now access subclass-specific properties
$data = $action->getData();
$data = $action["data"];Full Changelog: v11.4.0...v12.0.0
This release is prepared by @eucyt
Allow to skip signature verification by @habara-k in #741
With this release, developers can now optionally skip signature verification when parsing incoming webhook requests. This new capability is especially useful in scenarios where the channel secret may change, potentially causing temporary signature mismatches.
Example Usage:
$options = new EventRequestOptions(function () {
return true;
});
$parsedEvents = EventRequestParser::parseEventRequest(
$req->getBody(), $secret, $signature[0], $options
);When signature verification is skipped, the signatureValidator will not be invoked. This allows webhook requests to be processed even if their signatures do not match the current channel secret used for verification.
This feature is particularly helpful in high-availability systems where avoiding downtime or message loss during configuration updates is critical.
Full Changelog: v11.3.0...v11.4.0
Support new AudienceGroupType POP_AD_IMP to Audience Group API
We have supported for the new audience‑group type POP_AD_IMP (POP ad impression audience) to the OpenAPI schema.
Updated AudienceGroupType enumeration
POP_AD_IMPThis update enables correct identification and handling of audience groups built from POP ad impressions, a feature that will be released for the Taiwan market.
For more information, please refer to the links provided above.
(original PR is line/line-openapi#113)
Full Changelog: v11.2.1...v11.3.0
This release is prepared by @eucyt
2021/03/01
The UI of LIFF apps opened in LINE v11.3.0 will change.
Toast displayed during LIFF-to-LIFF transition will change
LIFF apps will be displayed in a modal window in LINE for iPadOS
Toast displayed during LIFF-to-LIFF transition will change
In LINE v11.3.0, the toast displayed during "LIFF-to-LIFF transitions," where users can transition to another LIFF app without closing the LIFF app opened in the LIFF browser, will change. This change makes it easier for users to identify the destination LIFF app.
The design of the toast differs between Android and iOS. The figure below shows an example of a toast when using an iPhone.
Changes Supported OS LINE v11.2.x and earlier LINE v11.3.0
Message*
iOS
Android Switched to another app. Switched to the {LIFF app name} app. **
Display location iOS only*** Center of screen Bottom of screen
** The {LIFF app name} section displays the app name specified in the LIFF app name section of the LIFF tab in the LINE Developers Console .
*** LINE v11.2.0 and earlier for Android will also display the toast at the bottom of the screen.
For more information about LIFF-to-LIFF transitions, see Opening a LIFF app from another LIFF app in the LIFF documentation.
LIFF apps will be displayed in a modal window in LINE for iPadOS
In LINE v11.3.0, to improve the experience with LIFF apps designed for many portrait modes (portrait display), LIFF apps opened on the iPad will be displayed in a formSheet size (540W x 620H pt) modal window.
Regardless of the Size setting ( Compact , Tall , or Full ) specified in the LIFF tab of the LINE Developers Console , LIFF apps will always be displayed in a formSheet size modal window in LINE v11.3.0 on iPad.
Example of a LIFF app with the screen size set to Compact :
About the screen ratio in landscape mode (landscape view)
formSheet will be displayed in portrait mode screen ratio (540W x 620H pt) even in landscape mode (landscape display).
LIFF
Previous post [Resolved] Notice about service outage for LINE Login Next post [Updated] Replace (Backward compatibility mode) has been removed from the permanent link redirect settings of the LIFF app and LINE MINI App
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →