---
title: HTTP API
description: LINE Agent SDK HTTP API for non-MCP programs: create a LINE connection, see whose turn each step is, send messages when live. The AI tool holds no credentials.
url: https://agentlab.cresclab.com/docs/en/line/api
language: en
updated: 2026-10-24
---

# HTTP API

LINE Agent SDK HTTP API for non-MCP programs: create a LINE connection, see whose turn each step is, send messages when live. The AI tool holds no credentials.

## Base URL

The API lives under the service you run, and every path starts with `/api`:

```text
https://line-oa-mcp--<organization>.hosting.agentlab.run/api
```

To run it, see [Run LINE OA MCP on Agent Lab](https://agentlab.cresclab.com/docs/en/line/quickstart.md).

> [!NOTE] MCP is simpler
> AI tools that speak MCP (Claude Code, Codex, Cursor) can use [LINE OA MCP](https://agentlab.cresclab.com/docs/en/line/mcp-tools.md) instead; its tools do what this API does. The running service also serves instructions for agents at `/agent.md`.

## Authentication

Every `/api` request needs an agent token. Sign in to the panel with Google and create one on the **Agent tokens** page (`/tokens`):

```http
Authorization: Bearer <agent token>
```

A missing, wrong or revoked token returns `401`. A token is shown once; revoke it on the same page when it is no longer needed.

> [!WARNING] Keep the token out of the chat
> Ask the person to put the token in an environment variable of the AI tool (for example `LINE_AGENT_SDK_TOKEN`) rather than pasting it into the conversation. The Channel Secret is entered only on the service's own page.

## 1. Create a connection

| Method and path             | Purpose                                                                                                                        |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `POST /api/connections`     | Create a connection to an existing LINE Official Account. Returns the connection, including the `setupUrl` to give the person. |
| `GET /api/connections`      | List connections.                                                                                                              |
| `GET /api/connections/{id}` | Read a connection's current state. Each read also checks whether the person has finished the step they were on in LINE.        |

```http
POST /api/connections
Content-Type: application/json

{ "workspace": "acme", "label": "Website support account" }
```

Both fields are optional. Give the person the returned `setupUrl`: the Channel ID and Channel Secret are entered only on that page.

## 2. Wait for each step

The connection's `nextStep` says whose turn it is, what to do, and how the step will be detected as done:

```json
{
  "id": "conn_9f3a1c2b4d5e",
  "state": "webhook_active",
  "live": false,
  "nextStep": {
    "key": "webhook_active",
    "title": "打開「Use webhook」",
    "actor": "human",
    "status": "current",
    "doneWhen": "LINE 回報 webhook active = true（每 2 秒自動偵測，不用回來按）",
    "how": "LINE Developers › Messaging API › Webhook settings › Use webhook 打開。",
    "url": "https://developers.line.biz/console/"
  }
}
```

- When `actor` is `human`, tell the person `title`, `how` and `url`, then keep reading the connection. The step completes on its own; don't ask "are you done?".
- When `actor` is `ops`, the service's operator is doing it; tell the person it is in progress.
- When `actor` is `agent`, the service does it itself.
- When `status` is `error`, the reason is in `note`.

Read every 2 to 5 seconds. When `live` is `true`, the first LINE message has reached the person's phone. Step titles and texts are in Traditional Chinese.

### Steps

| `key`            | Who       | Done when                                                                             |
| ---------------- | --------- | ------------------------------------------------------------------------------------- |
| `credentials`    | Person    | A token is issued with the Channel ID and Channel Secret.                             |
| `health`         | Automatic | Account info, chat mode, webhook, quota and followers are read. Nothing is changed.   |
| `mode`           | Person    | One of push only, relay or direct is chosen on the service's page.                    |
| `webhook_set`    | Automatic | The webhook URL is set to this service and read back.                                 |
| `webhook_active` | Person    | "Use webhook" is turned on in the LINE Developers console; detected automatically.    |
| `auto_reply`     | Person    | Auto-reply messages are turned off in OA Manager and confirmed on the service's page. |
| `pair`           | Person    | The person adds the account as a friend and sends `pairingCode`.                      |
| `first_message`  | Automatic | The reply to the pairing message is accepted.                                         |

With push only, `webhook_set`, `webhook_active` and `auto_reply` are `skipped`, and `pair` becomes pasting a test user ID. With relay, `auto_reply` is skipped and the existing system's settings stay as they are.

## 3. Send a message

| Method and path                       | Purpose                                      |
| ------------------------------------- | -------------------------------------------- |
| `POST /api/connections/{id}/messages` | Push a text message to the paired test user. |

```http
POST /api/connections/conn_9f3a1c2b4d5e/messages
Content-Type: application/json

{ "text": "Your order has shipped" }
```

```json
{ "ok": true, "to": "paired test user" }
```

A connection that is not live yet returns `409` with its `nextStep`.

> [!NOTE] Push messages use quota
> Push messages count toward the Official Account's monthly message limit; replies do not. When the test user messages the account, the agent answers with a reply and falls back to a push only if the reply token has expired.

## Sandbox

Without an Official Account, try the shared sandbox account the operator has set up:

| Method and path         | Purpose                                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `POST /api/sandbox`     | Get a join code. Returns `joinText` (for example `join blue-fox-42`) and the sandbox account's `account.addFriendUrl`. |
| `GET /api/sandbox/{id}` | Read the sandbox binding; `live` is `true` once the first message has arrived.                                         |

Give the person `addFriendUrl` and `joinText`: after adding the friend and sending that line, their phone is bound to the workspace. The sandbox only messages phones that joined, and friendships don't carry over to a real account.

## The connection object

| Field         | Meaning                                                                                                 |
| ------------- | ------------------------------------------------------------------------------------------------------- |
| `id`          | The connection ID used in every later call.                                                             |
| `state`       | The current step's `key`, or `live` when everything is done.                                            |
| `live`        | `true` once the first message has been delivered.                                                       |
| `mode`        | `push_only`, `relay`, `direct`, or `null` before one is chosen.                                         |
| `account`     | The Official Account's `basicId`, `displayName` and `addFriendUrl`; `null` before the health check.     |
| `pairingCode` | The code to send from the phone, for example `AL-7Q4K`.                                                 |
| `tester`      | The paired test user's `userId`.                                                                        |
| `webhookUrl`  | This connection's webhook URL; the service registers it with LINE itself.                               |
| `setupUrl`    | The page to give the person.                                                                            |
| `steps`       | Every step, each with `key`, `title`, `actor`, `status`, `doneWhen`, and possibly `how`, `url`, `note`. |
| `nextStep`    | The step to work on now; `null` when everything is done.                                                |

## Errors

| Status | Meaning                                                                        | What to do                                   |
| ------ | ------------------------------------------------------------------------------ | -------------------------------------------- |
| `400`  | The request is invalid, for example `text` is empty. The reason is in `error`. | Fix it and send again.                       |
| `401`  | The token is missing, wrong or revoked.                                        | Check `Authorization: Bearer <agent token>`. |
| `404`  | No such connection or sandbox binding.                                         | Check the `id`.                              |
| `409`  | The connection isn't live, so it can't send.                                   | Continue with the returned `nextStep`.       |

## Webhook

`POST /hooks/line/{id}` is for the LINE Platform. It needs no token, but every request must pass `x-line-signature` verification or it gets `401`. The service registers this URL with LINE itself in the `webhook_set` step; nobody pastes it by hand.
