DEV Community

unifyport for UnifyPort

Posted on • Originally published at unifyport.ai

LINE Service Messages vs Messaging API: Choose the Right Message Path

LINE MINI App Service Messages and the LINE Messaging API can both deliver messages to users, but they solve different problems.

A Service Message confirms or follows up on an action completed inside a LINE MINI App. A Messaging API message comes from a LINE Official Account and supports conversations, direct outreach, and audience messaging.

They differ in:

  • Sender identity
  • Trigger
  • Recipient model
  • Token lifecycle
  • Message format
  • Review requirements
  • Chat room
  • Pricing
  • Content policy

Choosing the wrong path can result in rejected templates, unusable tokens, duplicate notifications, or an architecture that cannot support customer conversations.

The short answer

Use a LINE MINI App Service Message when:

  • The user completed an action inside the MINI App
  • The message confirms, reports, or reminds the user about that action
  • The MINI App is verified
  • The template has passed review
  • You have a valid service notification token

Use the Messaging API when:

  • The sender should be a LINE Official Account
  • You need to reply to a user conversation
  • You need push, multicast, narrowcast, or broadcast delivery
  • You need flexible message objects
  • You are operating under the Official Account recipient, quota, and pricing model

One API is not an upgraded version of the other.

Compare the two paths

Decision point Service Message API Messaging API
Product LINE MINI App LINE Official Account
Purpose Transactional action confirmation, result, or reminder Conversation, support, outreach, and audience delivery
Trigger User action inside the MINI App User webhook event or application decision
Recipient User associated with a service notification token User, group, chat, audience, or Official Account friends
Production requirement Verified MINI App and reviewed template Messaging API channel connected to an Official Account
Message design Reviewed LINE-provided template Text, image, video, Flex, template, sticker, location, and other objects
Chat room Regional MINI App notice chat Chat with the Official Account
Marketing Prohibited Supported through eligible methods and applicable rules
Message limit Normally up to five per qualifying action Monthly allowance, endpoint limits, and account plan
Pricing Described by LINE as free Depends on market and Official Account plan

The official boundaries are documented in LINE's Service Message guide and Messaging API sending guide.

Service Messages begin with a MINI App action

A Service Message should not exist without a specific action performed by the user inside the LINE MINI App.

Appropriate examples include:

  • Reservation confirmation
  • Order confirmation
  • Check-in result
  • Shipment completion
  • Reservation reminder
  • Reminder for a purchased ticket
  • Queue-status update tied to a submitted request

The relationship should be explicit:

User action
    ↓
Business transaction
    ↓
Service notification token
    ↓
Approved template
    ↓
Confirmation, result, or reminder
Enter fullscreen mode Exit fullscreen mode

The following are not valid Service Message use cases:

  • General promotions
  • Discount campaigns
  • Coupons
  • Shopping rewards
  • New-product announcements
  • Unrelated event notifications
  • Messages triggered by actions outside the MINI App

Verification does not remove these restrictions.

Messaging API messages begin with an Official Account

The Messaging API provides these primary delivery methods:

Method Typical use
Reply Respond to a webhook event from a user
Push Send to an eligible user, group, or multi-person chat
Multicast Send to a specified list of user IDs
Narrowcast Send to an audience or demographic segment
Broadcast Send to all friends of the Official Account

It also supports a broader set of message objects:

  • Text
  • Text v2
  • Image
  • Video
  • Audio
  • Sticker
  • Location
  • Imagemap
  • Template
  • Flex Message

This makes the Messaging API appropriate for customer support, chatbots, campaigns, and Official Account communication.

However, it follows the recipient, friendship, quota, rate-limit, and pricing rules of the Official Account.

Understand the token boundary

The most common implementation error is treating all LINE tokens as interchangeable.

They are not.

Credential or identifier Belongs to Purpose
LIFF access token Current MINI App user session Helps issue the first service notification token
MINI App channel access token MINI App channel Authenticates Service Message API calls
Service notification token One MINI App user and action flow Sends reviewed Service Messages
Messaging API channel access token Official Account channel Authenticates Messaging API requests
Reply token One eligible webhook event Sends a reply message once
LINE user ID User within a channel context Targets eligible Messaging API methods
Audience ID Official Account audience Targets narrowcast operations

A Service notification token is not:

  • A permanent user ID
  • A Messaging API reply token
  • An Official Account push target
  • A reusable cross-user credential
  • A general-purpose chat identity

Keep each token type in a separate model and storage path.

The Service Message token flow

The first Service Message normally starts with a LIFF access token obtained during the user action.

MINI App
    ↓ liff.getAccessToken()
Backend
    ↓ POST /message/v3/notifier/token
Service notification token
    ↓ POST /message/v3/notifier/send?target=service
Service Message
    ↓
Renewed service notification token
Enter fullscreen mode Exit fullscreen mode

LINE recommends stateless channel access tokens for LINE MINI App channels. Long-lived and v2.1 channel access tokens cannot be used for MINI App channels.

The Service Message API returns state that must be preserved:

type ServiceNotificationState = {
  businessActionId: string;
  userReference: string;
  notificationToken: string;
  remainingCount: number;
  expiresAt: string;
  version: number;
};
Enter fullscreen mode Exit fullscreen mode

Important characteristics include:

  • The token is associated with one user
  • It normally permits up to five messages for the approved action
  • It expires one year after issuance
  • The token value is renewed after a successful send
  • The renewed token must be used for the next message
  • One LIFF access token can issue only one Service notification token

Do not store the token in browser analytics or application logs.

Persist the renewed token atomically

Two workers must not send with the same Service notification token at the same time.

A safe operation looks like:

async function sendActionUpdate(input: {
  actionId: string;
  stage: "confirmation" | "result" | "reminder";
  templateName: string;
  params: Record<string, string>;
}) {
  return database.transaction(async (tx) => {
    const state = await tx.lockServiceNotificationState(
      input.actionId,
    );

    const idempotencyKey =
      `${input.actionId}:${input.stage}:${input.templateName}`;

    const existing = await tx.findDelivery(idempotencyKey);

    if (existing) {
      return existing;
    }

    if (state.remainingCount <= 0) {
      throw new Error("service_message_count_exhausted");
    }

    const response = await lineMiniApp.sendServiceMessage({
      notificationToken: state.notificationToken,
      templateName: input.templateName,
      params: input.params,
    });

    await tx.updateServiceNotificationState({
      actionId: input.actionId,
      notificationToken: response.notificationToken,
      remainingCount: response.remainingCount,
    });

    return tx.createDelivery({
      idempotencyKey,
      channel: "line_service_message",
      status: "sent",
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

The exact transaction implementation depends on your database and queue, but the invariants are the same:

  1. Lock the action state
  2. Check idempotency
  3. Send once
  4. Save the renewed token
  5. Save the new remaining count
  6. Commit together

If the request result is uncertain, reconcile it before retrying blindly.

Reply tokens have a different lifecycle

Messaging API reply tokens arrive in eligible webhook events.

They are:

  • Tied to one event
  • Usable only once
  • Intended to be used immediately
  • Not interchangeable with Service notification tokens

A reply flow looks like:

User sends message
       ↓
Official Account webhook
       ↓
Reply token
       ↓
POST /v2/bot/message/reply
       ↓
Reply in Official Account chat
Enter fullscreen mode Exit fullscreen mode

If the response is generated too late or the reply token has already been consumed, your application must evaluate whether an eligible push message is appropriate.

Do not store a reply token as a permanent conversation address.

Treat templates differently

Service Messages use LINE-provided templates that must pass review.

Your application supplies approved variables and permanent links:

{
  "templateName": "reservation_confirmation_en",
  "params": {
    "reservation_number": "R-20260807-001",
    "reservation_time": "2026-08-08 19:00",
    "button_uri_1": "reservation/detail?id=R-20260807-001"
  }
}
Enter fullscreen mode Exit fullscreen mode

The template must remain connected to the reviewed action.

Messaging API message objects are more flexible:

{
  "to": "USER_ID_PLACEHOLDER",
  "messages": [
    {
      "type": "text",
      "text": "How can we help with your reservation?"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

This flexibility does not mean every recipient is eligible for every send method. Recipient and friendship rules still apply.

Do not send the same message twice by default

A product that uses both APIs can accidentally send duplicate updates:

Reservation completed
       ├── Service Message
       └── Messaging API push
Enter fullscreen mode Exit fullscreen mode

Unless duplication has a deliberate product reason, select one delivery path per purpose.

A routing policy can be explicit:

type MessagePurpose =
  | "transaction_confirmation"
  | "transaction_result"
  | "transaction_reminder"
  | "support_reply"
  | "support_follow_up"
  | "marketing_campaign";

function selectLineMessagePath(
  purpose: MessagePurpose,
): "service_message" | "messaging_api" {
  switch (purpose) {
    case "transaction_confirmation":
    case "transaction_result":
    case "transaction_reminder":
      return "service_message";

    case "support_reply":
    case "support_follow_up":
    case "marketing_campaign":
      return "messaging_api";
  }
}
Enter fullscreen mode Exit fullscreen mode

The final implementation must still check verification, template, recipient, consent, and quota requirements.

Join both paths with your own business ID

A Service notification token is not a customer-support identity.

If a customer receives a reservation confirmation and later starts a support conversation, correlate both paths with your own transaction model:

type CustomerInteraction = {
  customerId: string;
  businessActionId: string;
  reservationId?: string;
  orderId?: string;
  lineMiniAppUserReference?: string;
  officialAccountUserId?: string;
  supportConversationId?: string;
};
Enter fullscreen mode Exit fullscreen mode

Do not assume identifiers from different LINE channels or products are globally interchangeable.

Your application should own the relationship between:

  • Customer
  • Order or reservation
  • MINI App action
  • Service Message delivery
  • Official Account conversation
  • Support ticket

Recommended hybrid architecture

LINE MINI App action
        ↓
Transaction service
        ↓
Service Message worker
        ↓
Regional MINI App notice chat

Customer support message
        ↓
Official Account webhook
        ↓
Conversation service
        ↓
Messaging API reply

Both paths
        ↓
Shared customer/order database
Enter fullscreen mode Exit fullscreen mode

Keep separate:

  • Credentials
  • Token storage
  • Queues
  • Delivery logs
  • Retry policies
  • Rate and quota monitoring
  • Compliance rules

Share only stable business context such as an internal order or reservation ID.

Common failure modes

Using the wrong token

Symptom:

Unauthorized, invalid token, or recipient error
Enter fullscreen mode Exit fullscreen mode

Check whether the request used:

  • A LIFF access token
  • A MINI App channel access token
  • A Service notification token
  • A Messaging API channel access token
  • A reply token

Token type should be part of your request tracing metadata, but never log the token value.

Losing the renewed Service notification token

Symptom:

  • First notification succeeds
  • The next notification fails
  • Stored remainingCount does not match the latest response

Cause:

The application continued using the previous token value.

Reusing a token concurrently

Symptom:

  • Two workers process the same action
  • One succeeds and one fails
  • The next token state becomes unclear

Fix:

Use an action-level lock, idempotency key, and atomic token update.

Using Service Messages for marketing

Symptom:

  • Template review fails
  • Production use is restricted
  • Message content no longer matches the approved action

Fix:

Move promotional communication to an eligible Official Account method and follow its rules.

Treating a push message as a guaranteed alternative

Symptom:

  • The Service Message path fails
  • The application attempts a push message
  • The user is not an eligible Messaging API recipient

Fix:

Evaluate recipient eligibility before designing a fallback. The two paths do not have the same reach.

A practical decision tree

Ask these questions in order:

  1. Did the user perform the triggering action inside the LINE MINI App?
  2. Is the message only a confirmation, action result, or reminder for that action?
  3. Is the MINI App verified?
  4. Has the exact template passed review?
  5. Is a valid Service notification token available?

If all answers are yes, use the Service Message API.

Otherwise ask:

  1. Should the sender be the LINE Official Account?
  2. Is this a reply to an eligible webhook event?
  3. Is the recipient eligible for push or audience delivery?
  4. Is the account within its message allowance?
  5. Which Messaging API method matches the recipient model?

Then choose reply, push, multicast, narrowcast, or broadcast as appropriate.

Final checklist

  • [ ] Message purpose is defined
  • [ ] Triggering user action is identified
  • [ ] Sender identity is correct
  • [ ] Chat-room destination is understood
  • [ ] Token type is explicit
  • [ ] Service Message template is approved
  • [ ] Promotional content is excluded from Service Messages
  • [ ] Renewed notification tokens are stored atomically
  • [ ] remainingCount and expiry are persisted
  • [ ] Action-level idempotency is implemented
  • [ ] Reply tokens are not stored as permanent addresses
  • [ ] Messaging API recipient eligibility is checked
  • [ ] Monthly allowance and rate limits are monitored
  • [ ] Duplicate cross-path delivery is prevented
  • [ ] Both paths correlate through an internal business ID
  • [ ] Credentials, queues, and retry policies remain separate

The correct question is not:

Which LINE API can send the most messages?

It is:

Which product, sender identity, trigger, recipient model, and policy match this specific message?

Official references


Originally published on UnifyPort.

This article was prepared with AI assistance for language and structure, then technically reviewed and verified by the author.

Top comments (0)