diff --git a/gitlab4j-api/src/main/java/org/gitlab4j/api/ErrorTrackingApi.java b/gitlab4j-api/src/main/java/org/gitlab4j/api/ErrorTrackingApi.java
new file mode 100644
index 000000000..89484e395
--- /dev/null
+++ b/gitlab4j-api/src/main/java/org/gitlab4j/api/ErrorTrackingApi.java
@@ -0,0 +1,60 @@
+package org.gitlab4j.api;
+
+import java.util.List;
+
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.Response;
+
+import org.gitlab4j.api.models.ErrorTrackingClientKey;
+
+/**
+ * This class provides an entry point to the GitLab API error tracking.
+ * GitLab Error tracking API Documentation
+ */
+public class ErrorTrackingApi extends AbstractApi {
+
+    public ErrorTrackingApi(GitLabApi gitLabApi) {
+        super(gitLabApi);
+    }
+
+    /**
+     * Creates an integrated error tracking client key for a specified project.
+     *
+     * 
GitLab Endpoint: POST /projects/:id/error_tracking/client_keys
+     *
+     * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
+     * @return the created ErrorTrackingClientKey
+     * @throws GitLabApiException if any exception occurs
+     */
+    public ErrorTrackingClientKey createClientKey(Object projectIdOrPath) throws GitLabApiException {
+        GitLabApiForm formData = new GitLabApiForm();
+        Response response = post(
+                Response.Status.CREATED,
+                formData,
+                "projects",
+                getProjectIdOrPath(projectIdOrPath),
+                "error_tracking",
+                "client_keys");
+        return (response.readEntity(ErrorTrackingClientKey.class));
+    }
+
+    /**
+     * Lists all integrated error tracking client keys for a specified project.
+     *
+     * GitLab Endpoint: GET /projects/:id/error_tracking/client_keys
+     *
+     * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
+     * @return a list of ErrorTrackingClientKey
+     * @throws GitLabApiException if any exception occurs
+     */
+    public List getClientKeys(Object projectIdOrPath) throws GitLabApiException {
+        Response response = get(
+                Response.Status.OK,
+                null,
+                "projects",
+                getProjectIdOrPath(projectIdOrPath),
+                "error_tracking",
+                "client_keys");
+        return (response.readEntity(new GenericType<>() {}));
+    }
+}
diff --git a/gitlab4j-api/src/main/java/org/gitlab4j/api/GitLabApi.java b/gitlab4j-api/src/main/java/org/gitlab4j/api/GitLabApi.java
index aee3cbd9a..b4e511959 100644
--- a/gitlab4j-api/src/main/java/org/gitlab4j/api/GitLabApi.java
+++ b/gitlab4j-api/src/main/java/org/gitlab4j/api/GitLabApi.java
@@ -103,6 +103,7 @@ public String getApiNamespace() {
     private WikisApi wikisApi;
     private KeysApi keysApi;
     private MetadataApi metadataApi;
+    private ErrorTrackingApi errorTrackingApi;
 
     /**
      * Get the GitLab4J shared Logger instance.
@@ -1897,6 +1898,23 @@ public MetadataApi getMetadataApi() {
         return metadataApi;
     }
 
+    /**
+     * Gets the ErrorTrackingApi instance owned by this GitLabApi instance.
+     *
+     * @return the ErrorTrackingApi instance owned by this GitLabApi instance
+     */
+    public ErrorTrackingApi getErrorTrackingApi() {
+        if (errorTrackingApi == null) {
+            synchronized (this) {
+                if (errorTrackingApi == null) {
+                    errorTrackingApi = new ErrorTrackingApi(this);
+                }
+            }
+        }
+
+        return errorTrackingApi;
+    }
+
     /**
      * Create and return an Optional instance associated with a GitLabApiException.
      *
diff --git a/gitlab4j-api/src/test/java/org/gitlab4j/api/TestErrorTrackingApi.java b/gitlab4j-api/src/test/java/org/gitlab4j/api/TestErrorTrackingApi.java
new file mode 100644
index 000000000..0c37a5743
--- /dev/null
+++ b/gitlab4j-api/src/test/java/org/gitlab4j/api/TestErrorTrackingApi.java
@@ -0,0 +1,66 @@
+package org.gitlab4j.api;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
+
+import java.util.List;
+
+import org.gitlab4j.api.models.ErrorTrackingClientKey;
+import org.gitlab4j.api.models.Project;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * In order for these tests to run you must set the following properties in test-gitlab4j.properties
+ * 
+ * TEST_NAMESPACE
+ * TEST_PROJECT_NAME
+ * TEST_HOST_URL
+ * TEST_PRIVATE_TOKEN
+ * 
+ * If any of the above are NULL, all tests in this class will be skipped.
+ */
+@Tag("integration")
+@ExtendWith(SetupIntegrationTestExtension.class)
+@org.junit.jupiter.api.Disabled(
+        "Integration tests are disabled, see https://github.com/gitlab4j/gitlab4j-api/issues/1165")
+public class TestErrorTrackingApi extends AbstractIntegrationTest {
+
+    private static GitLabApi gitLabApi;
+    private static Project testProject;
+
+    @BeforeAll
+    public static void setup() {
+        gitLabApi = baseTestSetup();
+        testProject = getTestProject();
+    }
+
+    @BeforeEach
+    public void beforeMethod() {
+        assumeTrue(gitLabApi != null);
+        assumeTrue(testProject != null);
+    }
+
+    @Test
+    public void testCreateClientKey() throws GitLabApiException {
+        assertNotNull(testProject);
+        Long projectId = testProject.getId();
+        ErrorTrackingClientKey errorTrackingClientKey =
+                gitLabApi.getErrorTrackingApi().createClientKey(projectId);
+        assertNotNull(errorTrackingClientKey);
+    }
+
+    @Test
+    public void testGetClientKeys() throws GitLabApiException {
+        assertNotNull(testProject);
+        Long projectId = testProject.getId();
+        ErrorTrackingClientKey errorTrackingClientKey =
+                gitLabApi.getErrorTrackingApi().createClientKey(projectId);
+        List clientKeys =
+                gitLabApi.getErrorTrackingApi().getClientKeys(projectId);
+        assertEquals(errorTrackingClientKey, clientKeys.get(0));
+    }
+}
diff --git a/gitlab4j-models/src/main/java/org/gitlab4j/api/models/ErrorTrackingClientKey.java b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/ErrorTrackingClientKey.java
new file mode 100644
index 000000000..70a15e254
--- /dev/null
+++ b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/ErrorTrackingClientKey.java
@@ -0,0 +1,57 @@
+package org.gitlab4j.api.models;
+
+import java.io.Serializable;
+
+import org.gitlab4j.models.utils.JacksonJson;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ErrorTrackingClientKey implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+    private Boolean active;
+
+    @JsonProperty("public_key")
+    private String publicKey;
+
+    @JsonProperty("sentry_dsn")
+    private String sentryDsn;
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Boolean getActive() {
+        return active;
+    }
+
+    public void setActive(Boolean active) {
+        this.active = active;
+    }
+
+    public String getSentryDsn() {
+        return sentryDsn;
+    }
+
+    public void setSentryDsn(String sentryDsn) {
+        this.sentryDsn = sentryDsn;
+    }
+
+    @Override
+    public String toString() {
+        return (JacksonJson.toJsonString(this));
+    }
+}
diff --git a/gitlab4j-models/src/test/java/org/gitlab4j/models/TestGitLabApiBeans.java b/gitlab4j-models/src/test/java/org/gitlab4j/models/TestGitLabApiBeans.java
index 59d834b7f..887e4ae2e 100644
--- a/gitlab4j-models/src/test/java/org/gitlab4j/models/TestGitLabApiBeans.java
+++ b/gitlab4j-models/src/test/java/org/gitlab4j/models/TestGitLabApiBeans.java
@@ -808,4 +808,11 @@ public void testWebhook() throws Exception {
         GroupHook groupHook = unmarshalResource(GroupHook.class, "group-hook.json");
         assertTrue(compareJson(groupHook, "group-hook.json"));
     }
+
+    @Test
+    public void testErrorTrackingClientKey() throws Exception {
+        ErrorTrackingClientKey errorTrackingClientKey =
+                unmarshalResource(ErrorTrackingClientKey.class, "error-tracking-client-key.json");
+        assertTrue(compareJson(errorTrackingClientKey, "error-tracking-client-key.json"));
+    }
 }
diff --git a/gitlab4j-models/src/test/resources/org/gitlab4j/models/error-tracking-client-key.json b/gitlab4j-models/src/test/resources/org/gitlab4j/models/error-tracking-client-key.json
new file mode 100644
index 000000000..7d889482a
--- /dev/null
+++ b/gitlab4j-models/src/test/resources/org/gitlab4j/models/error-tracking-client-key.json
@@ -0,0 +1,6 @@
+{
+  "id": 3,
+  "active": true,
+  "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3",
+  "sentry_dsn": "https://glet_aa77551d849c083f76d0bc545ed053a3@example.com/errortracking/api/v1/projects/5"
+}