GitLab4J API: a Java client for the GitLab REST API, kept current by version
GitLab4J API (gitlab4j-api) provides a full featured Java client library for working with GitLab repositories via the GitLab REST API
At a glance
- What is it?
- GitLab4J API is a MIT licensed Java library for working with GitLab over its REST API, covering Community and Enterprise editions plus webhooks and system hooks, and it is published to Maven Central with a separate models artifact for projects that cannot use the Jersey HTTP layer. Since 6.0.0 it requires Java 11 or newer, and support for the long dead API v3 was removed in April 2025.
- Who is it for?
- Adopt GitLab4J API if your Java service has to talk to GitLab and you would rather not hand-roll request signing, pagination and model mapping against a large REST surface, since the library is on Maven Central, supports both GitLab editions and ships javadocs.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A client library shaped by the size of the GitLab API
GitLab4J API provides a full featured and easy to consume Java library for working with GitLab repositories via the GitLab REST API, and full support for working with GitLab webhooks and system hooks is also provided.
The reason a library like this exists is surface area. The GitLab REST API covers projects, issues, merge requests, pipelines, jobs, runners, groups, users, deploy tokens, container registries and a long tail of administration endpoints, each with its own pagination, filtering and return shape. Writing that by hand means writing the request layer, the deserialisation and the model classes, then keeping them in step with a server that keeps changing.
The target user is a Java engineer whose application needs to act on a GitLab instance: a release tool that creates tags, a CI dashboard that reads pipeline status, an onboarding service that provisions group membership, a service that listens for merge request webhooks and reacts. The library is a dependency in a `build.gradle` or a `pom.xml`, and the entry point is a `GitLabApi` instance.
The project metadata records the primary language as Java, the licence as MIT, and the default branch as `main`. The repository is a Gradle build with two published artifacts in `gitlab4j-api/` and `gitlab4j-models/`, plus a `jitpack.yml` and a `CHANGELOG.mustache` template that generates the changelog from commit messages.
The release history is what tells you whether the library keeps up. Version 6.3.0 was published on 2026-05-05, 6.2.0 on 2025-11-11 and 5.8.1 on 2025-09-21, and the last push to `main` was on 2026-10-04. The repository is not archived, and releases keep coming, which is what a client library tracking a fast moving server needs.
The API v3 removal and the Java 11 baseline
Two compatibility facts shape adoption, and the README puts both under explicit notices.
The first is API v3. As of GitLab 11.0, support for the GitLab API v3 was removed from the GitLab server, and support for GitLab API v3 was removed from this library in April 2025. That is the moment to check your instance. If a self-managed GitLab has been sitting on an old release without upgrades, its API version predates v4, and no version of this library will talk to it any more. For most deployments this is a non-issue, since GitLab 11.0 is many years old, but for a locked down instance that has never been upgraded it is a hard stop and the instance needs an upgrade before the client can help.
The second is the language baseline. As of GitLab4J API 6.0.0, Java 11 or newer is required. For a library that has existed for long enough to be used in older codebases, that is the kind of change that propagates: the library moves to Java 11, and any service still on Java 8 cannot take the upgrade without moving its own runtime.
Both changes point the same way. The library is aligned with modern GitLab and modern Java, and using it means being on the modern side of both lines. The alternative, using an older 5.x release to stay on Java 8, means staying on a version that no longer receives work against current GitLab releases.
The library supports both GitLab Community Edition and GitLab Enterprise Edition, which matters for organisations that run the commercial edition or migrate between them, since the API surface is a superset in that direction.
Adding the dependency and making the first call
Setting the project up is one dependency. In Gradle:
dependencies {
...
implementation group: 'org.gitlab4j', name: 'gitlab4j-api', version: '6.3.0'
}And in Maven:
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>6.3.0</version>
</dependency>The coordinates are `org.gitlab4j:gitlab4j-api`, and 6.3.0 is the version in the README's examples.
The first call is short. You need the URL of your GitLab server and a Personal Access Token from your GitLab account settings, and then:
// Create a GitLabApi instance to communicate with your GitLab server
GitLabApi gitLabApi = new GitLabApi("http://your.gitlab.server.com", "YOUR_PERSONAL_ACCESS_TOKEN");
// Get the list of projects your account has access to
List<Project> projects = gitLabApi.getProjectApi().getProjects();The structure to notice is the one-per-area API objects hanging off the `GitLabApi` instance. `getProjectApi()` returns the projects API, and there is a parallel object for each other area of the GitLab API. That structure is what keeps a large API surface navigable, and it is also what makes the model classes meaningful, since each area's methods return its own typed models.
There is also a username and password login, for the cases where a personal access token is not available:
// Log in to the GitLab server using a username and password
GitLabApi gitLabApi = GitLabApi.oauth2Login("http://your.gitlab.server.com", "username", "password");For scripts rather than applications, the README also documents Jbang, where a single line at the top of the file pulls in the library:
//DEPS org.gitlab4j:gitlab4j-api:6.3.0That is a genuinely useful path for a one-off administrative script, since it removes the build file from the picture entirely.
sudo, request timeouts and proxy configuration
Three operational features are worth knowing about, because each of them exists because someone needed it in production.
The first is impersonation. As of GitLab4J API 4.6.6, all API requests support performing the API call as if you were another user, provided you are authenticated as an administrator:
// Create a GitLabApi instance to communicate with your GitLab server (must be an administrator)
GitLabApi gitLabApi = new GitLabApi("http://your.gitlab.server.com", "YOUR_PERSONAL_ACCESS_TOKEN");
// sudo as as a different user, in this case the user named "johndoe", all future calls will be done as "johndoe"
gitLabApi.sudo("johndoe")
// To turn off sudo mode
gitLabApi.unsudo();The mechanism is a mode on the client instance rather than a per-call parameter, so `sudo` and `unsudo` bracket a region of calls. That is convenient for an administrative tool and dangerous if you forget to turn it off, since every subsequent call silently runs as the impersonated user.
The second is timeouts. As of GitLab4J API 4.14.21, support was added for setting the connect and read timeouts for the API client:
GitLabApi gitLabApi = new GitLabApi("http://your.gitlab.com", "YOUR_PERSONAL_ACCESS_TOKEN", proxyConfig);
// Set the connect timeout to 1 second and the read timeout to 5 seconds
gitLabApi.setRequestTimeout(1000, 5000);The third is proxy support, added in 4.8.2:
// Log in to the GitLab server using a proxy server (with basic auth on proxy)
Map<String, Object> proxyConfig = ProxyClientConfig.createProxyClientConfig(
"http://your-proxy-server", "proxy-username", "proxy-password");Corporate egress through a proxy with basic authentication is a common requirement for on-premises installations, and having it in the client avoids hand-rolling proxy handling on the underlying HTTP library.
The models jar for projects that cannot use Jersey
The library publishes a second artifact, and the reason is architectural.
The README explains it directly. For some usages, the HTTP layer based on Jersey can't be used. Those projects might want to use the Jackson-based model classes, and implement the REST call themselves. The models artifact is `org.gitlab4j:gitlab4j-models`:
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-models</artifactId>
<version>6.3.0</version>
</dependency>So the split is between the transport and the data. If you want the library's HTTP client, the Jersey-based layer, the request handling, the authentication and the typed API objects, you take `gitlab4j-api`. If your project already has its own HTTP stack, or runs on a runtime where Jersey and the JAX-RS stack do not fit, you take only the Jackson model classes and write the calls yourself.
That is a deliberate design choice and a good one for library design in general, since it lets the model layer be reused without dragging the transport along. The trade is that the models-only path leaves you responsible for the request layer, which is precisely the work the full artifact was supposed to save you from.
There is a related practical note in the setup section. There have been reports of problems resolving some dependencies when using Ivy or SBT, and the README links two JAX-RS API issues on the Eclipse EE4J tracker for help resolving them. Maven and Gradle, the two builds the README documents in detail, are not the ones with reported trouble.
Snapshots from jitpack, and the cost of living on main
The README has a section on getting the newest version, and it is worth reading carefully because it is an invitation to run unreleased code.
The setup is that while the maintainers are frequently creating releases, you might be interested in a feature that has not been published yet. You can use jars created by jitpack to get the newest version. The coordinates change, because jitpack builds from the GitHub repository rather than Maven Central:
<dependency>
<groupId>com.github.gitlab4j.gitlab4j-api</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>main-SNAPSHOT</version>
</dependency>And you have to add the jitpack repository to your build, with a content filter in the Gradle form so that only the expected group is fetched from it, because the group is a GitHub-style `com.github.gitlab4j.gitlab4j-api` rather than the `org.gitlab4j` used by the releases.
The same section shows how to pin a specific commit rather than the branch tip, with `ab6b84c6b0` as the worked example, and the Jbang equivalent pointing at a commit tree URL. That is the option to use if you need an unreleased feature but want the build to be reproducible.
The trade is straightforward. A snapshot from `main` gives you a GitLab endpoint that the released version does not have yet, at the cost of a moving target and a dependency that is not published to a repository you control. The commit-pinned form is the responsible version of that idea, and for a production service it is the only one of the two worth taking.
For the record, the released version 6.3.0 is on Maven Central, with a badge in the README pointing at the artifact page, and the javadocs are published on javadoc.io.
Editorial conclusion
Adopt GitLab4J API if your Java service has to talk to GitLab and you would rather not hand-roll request signing, pagination and model mapping against a large REST surface, since the library is on Maven Central, supports both GitLab editions and ships javadocs. Do not adopt it if you are still on a GitLab instance that only speaks API v3, since that support was removed from the library in April 2025, or if you want a client that exposes the newest GitLab features on the day they ship. Verify three things first: that your instance is on API v4 and that the operations you need exist in the version you pin, that your build resolves the JAX-RS API cleanly, since the README records unresolved dependency problems with Ivy and SBT, and that the Java 11 baseline matches your runtime, since that requirement arrived with the 6.0.0 line.
Frequently asked questions
How do I add the GitLab4J API to a Java project?
Add the dependency `org.gitlab4j:gitlab4j-api` at version 6.3.0 to your Gradle or Maven build, or use the Jbang `//DEPS` line in a script. You then create a `GitLabApi` instance with your server URL and a Personal Access Token.
Which GitLab versions does GitLab4J API support?
It supports GitLab Community Edition and GitLab Enterprise Edition. Support for the GitLab API v3 was removed from the server in GitLab 11.0 and was removed from the library in April 2025, so a v4 instance is required.
What Java version does GitLab4J API need?
Java 11 or newer is required as of GitLab4J API 6.0.0. Staying on an older Java runtime means staying on the 5.x line, which no longer receives work against current GitLab releases.
What is the gitlab4j-models artifact for?
For usages where the Jersey based HTTP layer cannot be used. It provides the Jackson based model classes so a project can implement the REST calls itself, and it is published as `org.gitlab4j:gitlab4j-models` with the same version number as the main artifact.
Can GitLab4J API run a request as another user?
Yes, if you are authenticated as an administrator. Since version 4.6.6 you can call `gitLabApi.sudo("johndoe")` so that all future calls are performed as that user, and `gitLabApi.unsudo()` to turn the mode off.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gitlab4j-gitlab4j-api)Was this useful?