Start a visitor chat session from an authorised domain, send messages, and stream the assistant's replies.
The API behind the Line chat widget. Use it to embed Line chat in your own front end instead of loading /widget/v1.js.
Two credentials are involved. The public key identifies the widget and is safe to ship in client code. POST /session exchanges it for a short-lived session token that authorises the rest of the conversation.
Every request is checked against the widget's allowed-domains list using the Origin header, so calls must come from a browser on an authorised domain. Requests are rate limited per visitor, per IP and per organisation.
Base URL
https://useline.io
/api/channels/webchat/sessionReturns the presentation settings for a widget so you can render the launcher before anyone starts a conversation. No session is created.
Parameters
keyquery · stringrequiredThe widget's public key.
Originheader · string · urirequiredMust match one of the widget's allowed domains.
Response
widgetobjectrequiredPresentation settings the tenant configured for this widget.
colourstringAccent colour as a CSS hex value.
positionstringOne of: left, right
launcherTextstringavatarUrlstring | null · uriassistantNamestringErrors
- 400
- The
keyparameter is missing. - 403
- The
Originis not on the widget's allowed-domains list. - 404
- No enabled widget matches that key.
Example request
curl -X GET 'https://useline.io/api/channels/webchat/session' \ -H 'Origin: https://example.com'
/api/channels/webchat/sessionOpens a conversation for a visitor and returns a session token plus the transcript so far, including the assistant's greeting.
Request body
Identifies the widget and the visitor, plus optional attribution.
keystringrequiredThe widget's public key.
visitorIdstringrequiredYour own stable identifier for this visitor. Reuse it to resume their conversation.
pageUrlstring · urireferrerstring · uriutmobjectCampaign parameters stored against the conversation.
{
"key": "pk_live_2f8c…",
"visitorId": "b6e1f0c2-4f0a-4f7c-9a1d-2c2f7c5f9b10",
"pageUrl": "https://example.com/pricing"
}Response
tokenstringrequiredBearer token for the other calls.
sessionIdstring · uuidrequiredexpiresInintegerrequiredToken lifetime in seconds.
widgetobjectPresentation settings the tenant configured for this widget.
colourstringAccent colour as a CSS hex value.
positionstringOne of: left, right
launcherTextstringavatarUrlstring | null · uriassistantNamestringhandoverStatestringrequiredWho is answering. ai — the assistant. queued — waiting on a teammate. human — a teammate has taken over. deferred — nobody was available and the visitor was asked to leave a message. closed — the conversation has ended.
One of: ai, queued, human, deferred, closed
messagesarray of objectrequiredErrors
- 400
keyorvisitorIdis missing.- 403
- The
Originis not on the widget's allowed-domains list. - 404
- No enabled widget matches that key.
- 429
- Rate limited. Back off and retry.
Example request
curl -X POST 'https://useline.io/api/channels/webchat/session' \
-H 'Origin: https://example.com' \
-H 'Content-Type: application/json' \
-d '{"key":"pk_live_2f8c…","visitorId":"b6e1f0c2-4f0a-4f7c-9a1d-2c2f7c5f9b10","pageUrl":"https://example.com/pricing"}'/api/channels/webchat/messagesession tokenSends a visitor message and streams the response as Server-Sent Events.
Event names:
received— the message was stored.delta—{ text }, a chunk of the assistant's reply. Concatenate in order.message—{ body, sender }, the complete reply.handover—{ state }, a human is taking over or the reply needs approval.error—{ message }, the reply failed. The stream then closes.
A conversation in queued or human state emits only handover; poll GET /api/channels/webchat/events for what the operator says next.
Request body
messagestringrequiredThe visitor's message.
{
"message": "Do you offer UK mobile numbers?"
}Response
event: received
data: {"ok":true}
event: delta
data: {"text":"Yes — "}
event: message
data: {"body":"Yes — every Line number is a real UK number.","sender":"agent","turn":1}
Errors
- 400
- The message is empty.
- 401
- The session token is missing, expired or does not match.
- 403
- The
Originis not on the widget's allowed-domains list. - 413
- The message is longer than 2000 characters.
- 429
- Rate limited. Back off and retry.
Example request
curl -X POST 'https://useline.io/api/channels/webchat/message' \
-H 'Authorization: Bearer $LINE_SESSION_TOKEN' \
-H 'Origin: https://example.com' \
-H 'Content-Type: application/json' \
-d '{"message":"Do you offer UK mobile numbers?"}'/api/channels/webchat/eventssession tokenReturns the transcript and the current handover state. Pass since to fetch only what arrived after a timestamp — this is how you receive replies typed by a human operator.
Parameters
sincequery · string · date-timeReturn only messages created strictly after this timestamp.
Response
handoverStatestringrequiredWho is answering. ai — the assistant. queued — waiting on a teammate. human — a teammate has taken over. deferred — nobody was available and the visitor was asked to leave a message. closed — the conversation has ended.
One of: ai, queued, human, deferred, closed
messagesarray of objectrequiredErrors
- 401
- The session token is missing, expired or does not match.
- 403
- The
Originis not on the widget's allowed-domains list. - 404
- The session or widget no longer exists.
Example request
curl -X GET 'https://useline.io/api/channels/webchat/events' \ -H 'Authorization: Bearer $LINE_SESSION_TOKEN' \ -H 'Origin: https://example.com'