# line-bot-sdk-java: a generated Java client for the LINE Messaging API

> The LINE Messaging API SDK for Java is an Apache-2.0 set of Maven modules covering the messaging client, webhooks, insight, audience, shop and LIFF APIs, with Spring Boot integration and code generated from the OpenAPI spec. It suits Java and Kotlin teams building LINE bots, and its module split means you take only the clients you need.

**line/line-bot-sdk-java** — LINE Messaging API SDK for Java

- Repository: https://github.com/line/line-bot-sdk-java
- Website: https://developers.line.biz/en/docs/messaging-api/overview/
- Stars: 646 · Forks: 926
- Language: Java
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/line-line-bot-sdk-java

## An SDK that follows the OpenAPI spec

The LINE Messaging API SDK for Java makes it easy to develop bots using the LINE Messaging API, and the project states that a sample bot can be created within minutes. The interesting part is not the convenience but the mechanism behind it.

From version 7.x, the SDK developer team decided to generate the SDK code based on the OpenAPI spec. The consequence, stated in the README, is that version 7.x is not compatible with 6.x, and that it can follow future API changes very quickly.

That is a deliberate trade. A hand-written client can be shaped around a developer's taste, but every new endpoint or renamed field is a manual change. A generated client is less pleasant to hand-tune, but it can be regenerated when the spec moves, so a new platform capability appears in the SDK rather than requiring an upstream contribution.

The repository layout confirms the setup. There is a generator/ directory, a generate-code.py script, a line-openapi directory holding the specification, and separate clients/ directory for the generated API clients. The modules are then grouped by function, with line-bot-webhook, line-bot-parser, line-bot-jackson and line-bot-integration-test sitting alongside.

The audience is Java and Kotlin developers who have already committed to LINE as a channel. The SDK presumes the platform, its authentication model and its webhook delivery; it is not a general chatbot framework.

## The module list tells you what exists

The Gradle example in the README lists the published artifacts, and it is effectively the feature map of the platform.

The API clients are line-bot-messaging-api-client for the core messaging API, line-bot-insight-client for the analytics endpoints, line-bot-manage-audience-client for audience management, line-bot-module-attach-client and line-bot-module-client for LINE module features, line-bot-shop-client for the shop integrations, line-channel-access-token-client for token handling, and line-liff-client for the LINE Front-end Framework. On the receiving side there is line-bot-webhook for the event objects and line-bot-parser for parsing webhook payloads, with a comment in the README noting that you do not need to depend on the parser explicitly.

The Spring Boot family is separate: line-bot-spring-boot-webmvc, line-bot-spring-boot-client, line-bot-spring-boot-handler and line-bot-spring-boot-web, and again the README marks the handler and web modules as ones you do not need to depend on explicitly. That pattern is worth understanding, because pulling in a module you do not need creates version conflicts when the platform SDK and the Spring integration move at different speeds.

The insight client and the audience client deserve a note, because they are the two that most bots do not need. Insight gives delivery and usage statistics, and audience management handles segmentation and targeting. If you are building a straightforward reply bot, depending on the messaging client, the webhook and the Spring integration is enough.

## A Spring Boot echo bot, line by line

The README's sample application is the clearest explanation of how the pieces fit together, and it is worth reading as the mental model for the whole SDK.

The application class carries a @LineMessageHandler annotation, and the handler method is annotated with @EventMapping and takes a typed event, MessageEvent of TextMessageContent. The generic type is what gives you the message body without casting, and the event itself gives you the reply token.

The core of the handler is short:

```java
    @EventMapping
    public void handleTextMessageEvent(MessageEvent<TextMessageContent> event) {
        System.out.println("event: " + event);
        final String originalMessageText = ((TextMessageContent) event.message()).text();
        messagingApiClient.replyMessage(
            new ReplyMessageRequest.Builder(event.replyToken(), List.of(new TextMessage(originalMessageText)))
                .build()
        );
    }
```

Three things are visible there. The reply token comes from the event and is consumed by the reply, so the reply is tied to the user's action rather than to a push. The request is built through a nested Builder, and the response body is a list of message objects, in this case a single TextMessage carrying the original text. And the client is injected, so the constructor takes a MessagingApiClient and the framework supplies it.

A second @EventMapping method handles the default case with the base Event type, and the sample prints it. That pattern is what a real bot needs, because not every webhook is a text message and an unhandled event type that throws is a production incident.

## The Result wrapper, request ids and typed exceptions

The SDK makes two things available that matter in production, and both are easy to miss in the hello world sample.

The first is the x-line-request-id header. The README explains that you may need to store the x-line-request-id obtained as a response from several APIs, and that you can get it from Result<T>:

```java
Result<Object> apiResponse = messagingApiClient
    .narrowcast(retryKey, new NarrowcastRequest.Builder(messages).build())
    .get();
System.out.println("x-line-request-id: " + apiResponse.requestId());
```

This is the correlation id the platform generates for a request. When a user reports that a message did not arrive, this is the identifier that lets the platform side find the same request in its logs, and it is worth logging on your side for exactly that reason.

The second is error handling. Error messages can be obtained from MessagingApiClientException when you use MessagingApiClient, and each client defines its own exception class:

```java
try {
    messagingApiClient.replyMessage(new ReplyMessage(replyToken, messages));
} catch (ExecutionException e) {
    if (e.getCause() instanceof MessagingApiClientException){
        MessagingApiClientException exception=(MessagingApiClientException)e.getCause();
        System.out.println("Error http status code: " + exception.getCode());
        System.out.println("Error response: " + exception.getDetails());
        System.out.println("Error message: " + exception.getMessage());
    }
}
```

The exception carries the HTTP status code, the error response details and the message, and the README also notes that you can get the x-line-accepted-request-id header from an error response through exception.getHeader. Each client having its own exception class means the error types are tied to the API surface they came from, at the cost of catching several types.

## Proxies, static IPs and the IP allowlist

The README answers a practical question directly: how do I use a proxy server with this module.

The client builder accepts an API endpoint and a proxy:

```java
api = MessagingApiClient.builder("MY_OWN_TOKEN")
        .apiEndPoint(URI.create("https://api.line.me/"))
        .proxy(new Proxy(Proxy.Type.HTTP,
                new InetSocketAddress("proxy.example.com", 8080)
        ))
        .build();
```

The API endpoint is configurable alongside the proxy, which means the same client shape works against a different endpoint, whether that is a regional endpoint or a mock in a test.

The note under the snippet is the part with an operational consequence. It says you do not need to use an add-on like Fixie to have static IP addresses for proxy servers, and that you can make API calls without entering IP addresses on the server IP whitelist. In other words, routing through a proxy removes the need to manage an allowlist of your egress addresses, which is a meaningful simplification for a deployment that otherwise has to keep a list current.

The alternative is a static egress IP of your own with the allowlist maintained in the LINE console, which is more work but gives you a stable address without an extra hop. For a team that already runs an HTTP egress proxy, the builder hook removes an entire category of configuration.

## Java 17, Maven Central and the samples

The requirements section is short: this library requires Java 17 or later. That is the floor for a new project and the first thing to check, since older codebases still on Java 11 cannot take this SDK as it stands.

Distribution is through Maven Central, and the modules can be installed with Maven or Gradle. The README points at the Maven Central search page for the com.linecorp.bot group, and the Gradle example uses the Kotlin DSL, which is the common style in Spring Boot projects today. The repository also ships a Gradle wrapper, a settings.gradle.kts and a buildSrc directory, so the build is reproducible from a clone.

Four sample projects are listed. sample-spring-boot-echo is the simple echo server, sample-spring-boot-kitchensink is described as full featured sample code, sample-spring-boot-echo-kotlin is the echo server written in Kotlin, and sample-manage-audience is a sample for the Manage Audience API. Between them they cover the minimum viable bot, the widest possible surface, the Kotlin variant and the audience APIs, which is a good spread for deciding what to copy.

The licence is Apache 2.0, with the licence text in LICENSE.txt, which is the permissive choice with an explicit patent grant. The project states that it respects semantic versioning, and then adds an important caveat: if a feature that was publicly released is discontinued for business reasons and becomes completely unusable, the changes will be released as a patch release. That is a platform business decision leaking into your version policy, and it is worth reading before you make a strict SemVer guarantee in your own service.

## Where line-bot-sdk-java is the wrong tool

The first case is a chat product that is not LINE. This SDK has no value if your product lives in Slack, Discord, Teams or your own app, and there is no abstraction layer that would make it so. The LINE-specific types, the reply token model and the webhook events are all tied to the platform.

The second case is a team that needs a long-term pinned version. The 7.x rewrite was a hard break from 6.x, and the split of line-bot-model and line-bot-api-client into line-bot-webhook and the clients modules means artifact names changed. A platform feature can also be removed for business reasons and delivered as a patch release, which means you cannot treat a version as a stable contract. Teams that need a five year support window should evaluate that risk rather than assume the SemVer statement covers it.

The third case is a project that does not use Spring Boot. The integration is the most polished part of the SDK, with the annotation-driven handler and the injected client, but the core modules are usable without it. If you are on Quarkus, Jakarta EE or a plain Java application server, you are on the generated clients and webhook parsing only, and the convenience that makes this SDK pleasant largely disappears.

The alternative worth comparing is calling the HTTP API directly with your own HTTP client, or a different vendor SDK. The LINE API is a JSON over HTTPS API with a straightforward shape, so hand-rolling it is entirely feasible and gives you full control over retries, timeouts and connection pooling, at the cost of handling schema changes and the platform's message types yourself. The SDK wins when you want the message model, the event types and the spec-driven updates handled for you. It loses when the generated abstraction gets in the way of a specific behaviour you need, since a generated client is a compromise between the spec and a clean API.

## Conclusion

line-bot-sdk-java is the right choice for a Java or Kotlin team that has decided to build on the LINE Messaging API, because the clients are generated from the OpenAPI spec and therefore track new API features quickly, and the module structure lets you depend on the messaging client without pulling in insight, shop or LIFF. It is the wrong choice if you are not deploying to LINE at all, or if you need a supported long-term version pinned for the life of a product, since the 7.x rewrite broke compatibility with 6.x and the project states that a publicly released feature may be discontinued for business reasons and shipped as a patch release. Before adopting it, confirm your build runs on Java 17 or later, read the migration notes for the 7.x module split so you pick the right artifact names, and check the IP allowlist or proxy setup in the API documentation before your first production call.

## FAQ

### What Java version does line-bot-sdk-java require?

The documentation states that this library requires Java 17 or later. The modules are published to Maven Central under the com.linecorp.bot group and can be installed with Maven or Gradle.

### Which LINE Messaging API modules are published on Maven Central?

The Gradle example lists the messaging API client, insight client, manage audience client, module attach client, module client, shop client, channel access token client and LIFF client, plus the webhook, parser and four Spring Boot modules.

### How do I get the x-line-request-id header in line-bot-sdk-java?

You can get it from Result<T> using the requestId accessor, as shown in the narrowcast example in the README. The SDK also exposes the x-line-accepted-request-id header from an error response through exception.getHeader.

### Can line-bot-sdk-java use a proxy server?

Yes. The client builder accepts a proxy configuration alongside the API endpoint, and the README notes that this means you can make API calls without entering IP addresses on the server IP whitelist, so you do not need a static IP add-on.

### What licence is line-bot-sdk-java released under?

The SDK is licensed under Apache 2.0, with the licence text in LICENSE.txt. The project states it respects semantic versioning, with the caveat that a feature discontinued for business reasons may be removed in a patch release.

## Sources

- [License: Apache-2.0](https://github.com/line/line-bot-sdk-java/blob/master/LICENSE)
- [line/line-bot-sdk-java on GitHub](https://github.com/line/line-bot-sdk-java)
- [Project website](https://developers.line.biz/en/docs/messaging-api/overview/)
- [README](https://github.com/line/line-bot-sdk-java/blob/master/README.md)
- [Releases](https://github.com/line/line-bot-sdk-java/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/line-line-bot-sdk-java
