Skip to main content

LINE Onboarding: Messaging API Channel to Working Two-Way Chat

This guide walks you from an empty LINE channel to a working, production-ready setup. It complements the LINE channel page, which covers message shapes and capability detail — this guide is the ordered path you follow the first time, and re-run whenever you attach, rotate, or retire a LINE Official Account. LINE has no template approval cycle for plain text, and no brand gate beyond having a LINE Official Account. The real work is connecting the right credentials and understanding which LINE recipient ids are usable. The Asia channels onboarding guide positions LINE beside KakaoTalk, Viber, and WeChat; this guide is the LINE-specific walkthrough.

1. Prerequisites — the Messaging API channel

You need two things from a LINE Official Account before Orbit can carry traffic:
  1. A LINE Official Account. If you do not have one, create it in the LINE Official Account Manager.
  2. A Messaging API channel on that account, created in the LINE Developers Console.
From the channel you need two credentials — copy them once, because the console does not always show the secret again:
  • Channel access token (long-lived) — from the channel’s Messaging API tab. This is the bearer token LINE accepts on outbound push calls.
  • Channel secret — from the channel’s Basic settings tab. Orbit uses it to verify the x-line-signature header on inbound webhooks before any event reaches your handler.
Also copy the numeric channel id (from the Basic settings tab) — it is the destination value every inbound webhook carries, and it is what identifies your tenant on the shared inbound URL. Treat both values as bearer credentials: anyone holding them can message as your Official Account. See Credential handling — your responsibility on the channel page for the handling rules (never commit to git, scope dev/staging/production to separate channels, rotate on suspicion).

2. Connect the channel to Orbit

Paste the two values once in the dashboard:
  1. Navigate to Channels → LINE → Connect.
  2. Paste the channel access token and channel secret. Orbit validates the token at connect time — an expired or invalid token returns LINE_INVALID_TOKEN (401) instead of connecting.
  3. Orbit stores both values encrypted at rest under your organization’s settings.channels.line and never echoes them back through any API response.
  4. In the LINE Developers Console, set the channel’s Webhook URL to https://api.orbit.devotel.io/api/v1/webhooks/inbound/line and enable Use webhook. Every Orbit tenant shares this single URL — the LINE channel id (destination) on each inbound event is what resolves the receiving tenant (see §4).
Connect and disconnect are write-class operations — they require the owner, admin, or developer role.

3. Send — POST /api/v1/messages/line

Sending goes through the unified Messaging surface. The text body is the top-level body field, the LINE message type is the top-level type field (defaulting to text), and the per-type secondary options ride under metadata as string→string values. The sender is selected automatically from your connected channel credentials — you never pass a token or channel id on the request. The request body is the shared free-form shape used by the other OTT channels (Viber, Telegram, KakaoTalk) — to + body are the only required fields, with optional from, media_url, metadata, and scheduled_at:
202 Accepted means queued — the terminal delivered / failed state arrives later on the delivery-status webhook, whose envelope shape is documented on the channel page. A soft failure (recipient blocked your Official Account) shows up there as message.failed with error_code: MESSAGE_DELIVERY_FAILED. Outbound POST /messages/line is capped at 80 requests/minute per tenant; bursts past the cap receive 429 with a Retry-After header, so stage high-volume sends through the campaigns API.

4. Inbound — tenant resolution from destination

LINE fans every tenant’s inbound traffic into the single platform URL you set in §2. Each inbound event carries a destination field — the numeric LINE channel id of the receiving Official Account — and Orbit resolves the owning tenant from that value before doing anything else:
  1. Read the untrusted payload’s destination and resolve the tenant that connected that channel id.
  2. Verify the x-line-signature HMAC-SHA256 header against that tenant’s stored channel secret. Requests that fail verification are rejected before any webhook fires.
  3. Normalize each message-type event into the canonical inbound envelope and forward it to the endpoint configured under Settings → Webhooks, signed with the Standard-Webhooks scheme.
Because tenant resolution happens per-event, the shared URL is multi-tenant-safe: a misconfigured channel id cannot route traffic into a neighbor’s webhook chain. Inbound user messages are the only events that reach your webhook receiver. Follows (joins), unfollows, postbacks (button taps), and reads arrive in the same verified payload, but the dispatcher acknowledges and drops them — if your flow must react to a button press, run it inside Orbit (flows, journeys), not in your receiver. The sender’s LINE id (U…) on the envelope is the to value for every outbound reply. An inbound text message arrives like this:
Delivery receipts from LINE advance the outbound lifecycle on a separate POST /api/v1/webhooks/dlr/line route that Orbit registers as part of connect — nothing for you to wire. Full envelope samples are on the channel page.

5. Verify the loop end to end

  1. From a LINE device, message your Official Account — confirm a message.received event lands on your webhook within seconds.
  2. Reply through POST /messages/line using the sender’s U… id from that event — confirm the message arrives in the chat.
  3. Confirm the message.delivered event arrives and that the message record in the dashboard moved through queued → delivered.
If inbound never arrives, check the LINE Developers Console webhook section: Use webhook must be enabled and the URL must be exactly https://api.orbit.devotel.io/api/v1/webhooks/inbound/line. LINE also enforces that webhook URL validation responds on the same domain — if you rotate credentials, re-paste them in Orbit rather than re-pointing the URL.

6. Rotation and retirement

Rotating the access token from the LINE Developers Console does not break history — Orbit keys conversation history by channel id, not by token, and re-pasting the new token value under Channels → LINE preserves everything. Disconnecting the channel in the dashboard removes the credential row; inbound webhook traffic for that channel id then resolves to no tenant and is rejected, so retire it only after the Official Account has stopped receiving traffic.

7. Error reference

A failed send returns a JSON error envelope whose error.code is one of the values below. LINE_INVALID_TOKEN (401) is returned only at connect time, for an expired or invalid channel access token; it is never raised on the send path.

Compliance scope

LINE does not impose platform-side template or quiet-hours gates on plain text, and Orbit does not either — any consent, opt-out, or timing policy you promise your LINE audience is enforced from your own tenant configuration (quiet hours, frequency caps, suppression lists), not by this channel’s connect path. Keep those controls enabled in production and follow them in your journey logic; this guide only wires the transport.

Where to go next