diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml
index 22a9f1e6a48..531154bda8c 100644
--- a/.generator/schemas/v2/openapi.yaml
+++ b/.generator/schemas/v2/openapi.yaml
@@ -2396,6 +2396,116 @@ components:
$ref: "#/components/schemas/JSONAPIErrorResponse"
description: The server cannot process the request because it contains invalid data.
schemas:
+ AIImpactUserActivityAttributes:
+ additionalProperties: false
+ description: |-
+ Daily AI coding tool activity for a single user. Each entry reports whether the user was
+ active on a given day and which AI tools and models they used.
+ properties:
+ day:
+ description: The day the activity refers to, in `YYYY-MM-DD` format.
+ example: "2026-05-26"
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$"
+ type: string
+ is_active:
+ description: Whether the user actively used the listed AI tools on that day.
+ example: true
+ type: boolean
+ models:
+ $ref: "#/components/schemas/AIImpactUserActivityModels"
+ tools:
+ $ref: "#/components/schemas/AIImpactUserActivityTools"
+ user_email:
+ description: |-
+ The email address of the user. It is case-insensitive and is matched against the
+ email addresses of commit authors.
+ example: user@example.com
+ pattern: "^[^@]+@[^@.]+(?:\\.[^@.]+)+$"
+ type: string
+ required:
+ - user_email
+ - is_active
+ - day
+ - tools
+ type: object
+ AIImpactUserActivityData:
+ additionalProperties: false
+ description: A single daily AI tool activity entry.
+ properties:
+ attributes:
+ $ref: "#/components/schemas/AIImpactUserActivityAttributes"
+ type:
+ $ref: "#/components/schemas/AIImpactUserActivityType"
+ required:
+ - type
+ - attributes
+ type: object
+ AIImpactUserActivityDataArray:
+ description: |-
+ A batch of daily AI tool activity entries. A batch must contain between 1 and 1,000 entries.
+ example:
+ - attributes:
+ day: "2026-05-26"
+ is_active: true
+ models:
+ - claude-sonnet-4.5
+ - gpt-5
+ tools:
+ - Claude Code
+ - Cursor
+ user_email: user@example.com
+ type: ai_impact_user_activity
+ items:
+ $ref: "#/components/schemas/AIImpactUserActivityData"
+ maxItems: 1000
+ minItems: 1
+ type: array
+ AIImpactUserActivityModels:
+ description: |-
+ The AI models the user used on that day, for example `claude-sonnet-4.5` or `gpt-5`.
+ Values are lowercased and duplicates are removed.
+ example:
+ - claude-sonnet-4.5
+ - gpt-5
+ items:
+ description: The name of an AI model.
+ example: claude-sonnet-4.5
+ type: string
+ type: array
+ AIImpactUserActivityRequest:
+ additionalProperties: false
+ description: Request to send daily AI tool activity for one or more users.
+ properties:
+ data:
+ $ref: "#/components/schemas/AIImpactUserActivityDataArray"
+ required:
+ - data
+ type: object
+ AIImpactUserActivityTools:
+ description: |-
+ The AI coding tools the user used on that day, for example `Claude Code`, `Cursor`, or
+ `GitHub Copilot`. Known tools are normalized to a canonical name (`claude_code`, `cursor`,
+ `copilot`), and other values are converted to snake case. Entries must not be empty.
+ example:
+ - Claude Code
+ - Cursor
+ items:
+ description: The name of an AI coding tool.
+ example: Claude Code
+ minLength: 1
+ pattern: ".*\\S.*"
+ type: string
+ minItems: 1
+ type: array
+ AIImpactUserActivityType:
+ default: ai_impact_user_activity
+ description: JSON:API type for AI Impact user activity entries.
+ enum:
+ - ai_impact_user_activity
+ example: ai_impact_user_activity
+ type: string
+ x-enum-varnames:
+ - AI_IMPACT_USER_ACTIVITY
APIErrorResponse:
description: API error response.
properties:
@@ -141616,6 +141726,59 @@ paths:
operator: OR
permissions:
- security_monitoring_findings_read
+ /api/v2/ai_impact/user_activity:
+ post:
+ description: |-
+ Send daily AI coding tool activity for one or more users. Each entry records whether a
+ user was active on a given day, along with the AI tools and models they used. An entry
+ is stored once per tool, and sending the same user, day, and tool again overwrites the
+ previous value.
+ operationId: CreateAIImpactUserActivity
+ requestBody:
+ content:
+ application/json:
+ examples:
+ default:
+ value:
+ data:
+ - attributes:
+ day: "2026-05-26"
+ is_active: true
+ models:
+ - claude-sonnet-4.5
+ - gpt-5
+ tools:
+ - Claude Code
+ - Cursor
+ user_email: user@example.com
+ type: ai_impact_user_activity
+ schema:
+ $ref: "#/components/schemas/AIImpactUserActivityRequest"
+ required: true
+ responses:
+ "200":
+ description: OK
+ "400":
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/JSONAPIErrorResponse"
+ description: |-
+ Bad Request: the batch is empty, has more than 1,000 entries, or contains an invalid entry.
+ An entry is invalid when `user_email`, `is_active`, or `day` is missing, `tools` is missing
+ or an empty array, `user_email` is not a valid email address, `day` is not in `YYYY-MM-DD`
+ format, or a tool name is empty. The error message identifies the index of the first invalid
+ entry. Fix the payload and send the request again.
+ "403":
+ $ref: "#/components/responses/NotAuthorizedResponse"
+ "429":
+ $ref: "#/components/responses/TooManyRequestsResponse"
+ security:
+ - apiKeyAuth: []
+ summary: Send AI tool user activity
+ tags:
+ - AI Impact
+ x-codegen-request-body-name: body
/api/v2/annotation:
get:
description: Returns a flat list of annotations matching the given page, time window, and optional widget filter.
@@ -244846,6 +245009,9 @@ servers:
default: api
description: The subdomain where the API is deployed.
tags:
+ - description: |-
+ Send AI coding tool usage data to measure the impact of AI tools on software delivery.
+ name: AI Impact
- description: |-
Configure your API endpoints through the Datadog API.
name: API Management
diff --git a/examples/v2/ai-impact/CreateAIImpactUserActivity.java b/examples/v2/ai-impact/CreateAIImpactUserActivity.java
new file mode 100644
index 00000000000..ceb896dc175
--- /dev/null
+++ b/examples/v2/ai-impact/CreateAIImpactUserActivity.java
@@ -0,0 +1,42 @@
+// Send AI tool user activity returns "OK" response
+
+import com.datadog.api.client.ApiClient;
+import com.datadog.api.client.ApiException;
+import com.datadog.api.client.v2.api.AiImpactApi;
+import com.datadog.api.client.v2.model.AIImpactUserActivityAttributes;
+import com.datadog.api.client.v2.model.AIImpactUserActivityData;
+import com.datadog.api.client.v2.model.AIImpactUserActivityRequest;
+import com.datadog.api.client.v2.model.AIImpactUserActivityType;
+import java.util.Arrays;
+import java.util.Collections;
+
+public class Example {
+ public static void main(String[] args) {
+ ApiClient defaultClient = ApiClient.getDefaultApiClient();
+ AiImpactApi apiInstance = new AiImpactApi(defaultClient);
+
+ AIImpactUserActivityRequest body =
+ new AIImpactUserActivityRequest()
+ .data(
+ Collections.singletonList(
+ new AIImpactUserActivityData()
+ .attributes(
+ new AIImpactUserActivityAttributes()
+ .day("2026-05-26")
+ .isActive(true)
+ .models(Arrays.asList("claude-sonnet-4.5", "gpt-5"))
+ .tools(Arrays.asList("Claude Code", "Cursor"))
+ .userEmail("user@example.com"))
+ .type(AIImpactUserActivityType.AI_IMPACT_USER_ACTIVITY)));
+
+ try {
+ apiInstance.createAIImpactUserActivity(body);
+ } catch (ApiException e) {
+ System.err.println("Exception when calling AiImpactApi#createAIImpactUserActivity");
+ System.err.println("Status code: " + e.getCode());
+ System.err.println("Reason: " + e.getResponseBody());
+ System.err.println("Response headers: " + e.getResponseHeaders());
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/api/AiImpactApi.java b/src/main/java/com/datadog/api/client/v2/api/AiImpactApi.java
new file mode 100644
index 00000000000..4e9ef7c397b
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/api/AiImpactApi.java
@@ -0,0 +1,177 @@
+package com.datadog.api.client.v2.api;
+
+import com.datadog.api.client.ApiClient;
+import com.datadog.api.client.ApiException;
+import com.datadog.api.client.ApiResponse;
+import com.datadog.api.client.Pair;
+import com.datadog.api.client.v2.model.AIImpactUserActivityRequest;
+import jakarta.ws.rs.client.Invocation;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class AiImpactApi {
+ private ApiClient apiClient;
+
+ public AiImpactApi() {
+ this(ApiClient.getDefaultApiClient());
+ }
+
+ public AiImpactApi(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * Get the API client.
+ *
+ * @return API client
+ */
+ public ApiClient getApiClient() {
+ return apiClient;
+ }
+
+ /**
+ * Set the API client.
+ *
+ * @param apiClient an instance of API client
+ */
+ public void setApiClient(ApiClient apiClient) {
+ this.apiClient = apiClient;
+ }
+
+ /**
+ * Send AI tool user activity.
+ *
+ *
See {@link #createAIImpactUserActivityWithHttpInfo}.
+ *
+ * @param body (required)
+ * @throws ApiException if fails to make API call
+ */
+ public void createAIImpactUserActivity(AIImpactUserActivityRequest body) throws ApiException {
+ createAIImpactUserActivityWithHttpInfo(body);
+ }
+
+ /**
+ * Send AI tool user activity.
+ *
+ *
See {@link #createAIImpactUserActivityWithHttpInfoAsync}.
+ *
+ * @param body (required)
+ * @return CompletableFuture
+ */
+ public CompletableFuture createAIImpactUserActivityAsync(AIImpactUserActivityRequest body) {
+ return createAIImpactUserActivityWithHttpInfoAsync(body)
+ .thenApply(
+ response -> {
+ return response.getData();
+ });
+ }
+
+ /**
+ * Send daily AI coding tool activity for one or more users. Each entry records whether a user was
+ * active on a given day, along with the AI tools and models they used. An entry is stored once
+ * per tool, and sending the same user, day, and tool again overwrites the previous value.
+ *
+ * @param body (required)
+ * @return ApiResponse<Void>
+ * @throws ApiException if fails to make API call
+ * @http.response.details
+ *
+ * Response details
+ * | Status Code | Description | Response Headers |
+ * | 200 | OK | - |
+ * | 400 | Bad Request: the batch is empty, has more than 1,000 entries, or contains an invalid entry. An entry is invalid when `user_email`, `is_active`, or `day` is missing, `tools` is missing or an empty array, `user_email` is not a valid email address, `day` is not in `YYYY-MM-DD` format, or a tool name is empty. The error message identifies the index of the first invalid entry. Fix the payload and send the request again. | - |
+ * | 403 | Not Authorized | - |
+ * | 429 | Too many requests | - |
+ *
+ */
+ public ApiResponse createAIImpactUserActivityWithHttpInfo(AIImpactUserActivityRequest body)
+ throws ApiException {
+ Object localVarPostBody = body;
+
+ // verify the required parameter 'body' is set
+ if (body == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'body' when calling createAIImpactUserActivity");
+ }
+ // create path and map variables
+ String localVarPath = "/api/v2/ai_impact/user_activity";
+
+ Map localVarHeaderParams = new HashMap();
+
+ Invocation.Builder builder =
+ apiClient.createBuilder(
+ "v2.AiImpactApi.createAIImpactUserActivity",
+ localVarPath,
+ new ArrayList(),
+ localVarHeaderParams,
+ new HashMap(),
+ new String[] {"*/*"},
+ new String[] {"apiKeyAuth"});
+ return apiClient.invokeAPI(
+ "POST",
+ builder,
+ localVarHeaderParams,
+ new String[] {"application/json"},
+ localVarPostBody,
+ new HashMap(),
+ false,
+ null);
+ }
+
+ /**
+ * Send AI tool user activity.
+ *
+ * See {@link #createAIImpactUserActivityWithHttpInfo}.
+ *
+ * @param body (required)
+ * @return CompletableFuture<ApiResponse<Void>>
+ */
+ public CompletableFuture> createAIImpactUserActivityWithHttpInfoAsync(
+ AIImpactUserActivityRequest body) {
+ Object localVarPostBody = body;
+
+ // verify the required parameter 'body' is set
+ if (body == null) {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(
+ new ApiException(
+ 400,
+ "Missing the required parameter 'body' when calling createAIImpactUserActivity"));
+ return result;
+ }
+ // create path and map variables
+ String localVarPath = "/api/v2/ai_impact/user_activity";
+
+ Map localVarHeaderParams = new HashMap();
+
+ Invocation.Builder builder;
+ try {
+ builder =
+ apiClient.createBuilder(
+ "v2.AiImpactApi.createAIImpactUserActivity",
+ localVarPath,
+ new ArrayList(),
+ localVarHeaderParams,
+ new HashMap(),
+ new String[] {"*/*"},
+ new String[] {"apiKeyAuth"});
+ } catch (ApiException ex) {
+ CompletableFuture> result = new CompletableFuture<>();
+ result.completeExceptionally(ex);
+ return result;
+ }
+ return apiClient.invokeAPIAsync(
+ "POST",
+ builder,
+ localVarHeaderParams,
+ new String[] {"application/json"},
+ localVarPostBody,
+ new HashMap(),
+ false,
+ null);
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityAttributes.java b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityAttributes.java
new file mode 100644
index 00000000000..cf29c81b804
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityAttributes.java
@@ -0,0 +1,226 @@
+/*
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
+ * Copyright 2019-Present Datadog, Inc.
+ */
+
+package com.datadog.api.client.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Daily AI coding tool activity for a single user. Each entry reports whether the user was active
+ * on a given day and which AI tools and models they used.
+ */
+@JsonPropertyOrder({
+ AIImpactUserActivityAttributes.JSON_PROPERTY_DAY,
+ AIImpactUserActivityAttributes.JSON_PROPERTY_IS_ACTIVE,
+ AIImpactUserActivityAttributes.JSON_PROPERTY_MODELS,
+ AIImpactUserActivityAttributes.JSON_PROPERTY_TOOLS,
+ AIImpactUserActivityAttributes.JSON_PROPERTY_USER_EMAIL
+})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class AIImpactUserActivityAttributes {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_DAY = "day";
+ private String day;
+
+ public static final String JSON_PROPERTY_IS_ACTIVE = "is_active";
+ private Boolean isActive;
+
+ public static final String JSON_PROPERTY_MODELS = "models";
+ private List models = null;
+
+ public static final String JSON_PROPERTY_TOOLS = "tools";
+ private List tools = new ArrayList<>();
+
+ public static final String JSON_PROPERTY_USER_EMAIL = "user_email";
+ private String userEmail;
+
+ public AIImpactUserActivityAttributes() {}
+
+ @JsonCreator
+ public AIImpactUserActivityAttributes(
+ @JsonProperty(required = true, value = JSON_PROPERTY_DAY) String day,
+ @JsonProperty(required = true, value = JSON_PROPERTY_IS_ACTIVE) Boolean isActive,
+ @JsonProperty(required = true, value = JSON_PROPERTY_TOOLS) List tools,
+ @JsonProperty(required = true, value = JSON_PROPERTY_USER_EMAIL) String userEmail) {
+ this.day = day;
+ this.isActive = isActive;
+ this.tools = tools;
+ this.userEmail = userEmail;
+ }
+
+ public AIImpactUserActivityAttributes day(String day) {
+ this.day = day;
+ return this;
+ }
+
+ /**
+ * The day the activity refers to, in YYYY-MM-DD format.
+ *
+ * @return day
+ */
+ @JsonProperty(JSON_PROPERTY_DAY)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public String getDay() {
+ return day;
+ }
+
+ public void setDay(String day) {
+ this.day = day;
+ }
+
+ public AIImpactUserActivityAttributes isActive(Boolean isActive) {
+ this.isActive = isActive;
+ return this;
+ }
+
+ /**
+ * Whether the user actively used the listed AI tools on that day.
+ *
+ * @return isActive
+ */
+ @JsonProperty(JSON_PROPERTY_IS_ACTIVE)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public Boolean getIsActive() {
+ return isActive;
+ }
+
+ public void setIsActive(Boolean isActive) {
+ this.isActive = isActive;
+ }
+
+ public AIImpactUserActivityAttributes models(List models) {
+ this.models = models;
+ return this;
+ }
+
+ public AIImpactUserActivityAttributes addModelsItem(String modelsItem) {
+ if (this.models == null) {
+ this.models = new ArrayList<>();
+ }
+ this.models.add(modelsItem);
+ return this;
+ }
+
+ /**
+ * The AI models the user used on that day, for example claude-sonnet-4.5 or
+ * gpt-5. Values are lowercased and duplicates are removed.
+ *
+ * @return models
+ */
+ @jakarta.annotation.Nullable
+ @JsonProperty(JSON_PROPERTY_MODELS)
+ @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS)
+ public List getModels() {
+ return models;
+ }
+
+ public void setModels(List models) {
+ this.models = models;
+ }
+
+ public AIImpactUserActivityAttributes tools(List tools) {
+ this.tools = tools;
+ return this;
+ }
+
+ public AIImpactUserActivityAttributes addToolsItem(String toolsItem) {
+ this.tools.add(toolsItem);
+ return this;
+ }
+
+ /**
+ * The AI coding tools the user used on that day, for example Claude Code,
+ * Cursor, or GitHub Copilot. Known tools are normalized to a canonical name (
+ * claude_code, cursor, copilot), and other values are
+ * converted to snake case. Entries must not be empty.
+ *
+ * @return tools
+ */
+ @JsonProperty(JSON_PROPERTY_TOOLS)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public List getTools() {
+ return tools;
+ }
+
+ public void setTools(List tools) {
+ this.tools = tools;
+ }
+
+ public AIImpactUserActivityAttributes userEmail(String userEmail) {
+ this.userEmail = userEmail;
+ return this;
+ }
+
+ /**
+ * The email address of the user. It is case-insensitive and is matched against the email
+ * addresses of commit authors.
+ *
+ * @return userEmail
+ */
+ @JsonProperty(JSON_PROPERTY_USER_EMAIL)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public String getUserEmail() {
+ return userEmail;
+ }
+
+ public void setUserEmail(String userEmail) {
+ this.userEmail = userEmail;
+ }
+
+ /** Return true if this AIImpactUserActivityAttributes object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ AIImpactUserActivityAttributes aiImpactUserActivityAttributes =
+ (AIImpactUserActivityAttributes) o;
+ return Objects.equals(this.day, aiImpactUserActivityAttributes.day)
+ && Objects.equals(this.isActive, aiImpactUserActivityAttributes.isActive)
+ && Objects.equals(this.models, aiImpactUserActivityAttributes.models)
+ && Objects.equals(this.tools, aiImpactUserActivityAttributes.tools)
+ && Objects.equals(this.userEmail, aiImpactUserActivityAttributes.userEmail);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(day, isActive, models, tools, userEmail);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class AIImpactUserActivityAttributes {\n");
+ sb.append(" day: ").append(toIndentedString(day)).append("\n");
+ sb.append(" isActive: ").append(toIndentedString(isActive)).append("\n");
+ sb.append(" models: ").append(toIndentedString(models)).append("\n");
+ sb.append(" tools: ").append(toIndentedString(tools)).append("\n");
+ sb.append(" userEmail: ").append(toIndentedString(userEmail)).append("\n");
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityData.java b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityData.java
new file mode 100644
index 00000000000..016e6eeabd7
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityData.java
@@ -0,0 +1,131 @@
+/*
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
+ * Copyright 2019-Present Datadog, Inc.
+ */
+
+package com.datadog.api.client.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.Objects;
+
+/** A single daily AI tool activity entry. */
+@JsonPropertyOrder({
+ AIImpactUserActivityData.JSON_PROPERTY_ATTRIBUTES,
+ AIImpactUserActivityData.JSON_PROPERTY_TYPE
+})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class AIImpactUserActivityData {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_ATTRIBUTES = "attributes";
+ private AIImpactUserActivityAttributes attributes;
+
+ public static final String JSON_PROPERTY_TYPE = "type";
+ private AIImpactUserActivityType type = AIImpactUserActivityType.AI_IMPACT_USER_ACTIVITY;
+
+ public AIImpactUserActivityData() {}
+
+ @JsonCreator
+ public AIImpactUserActivityData(
+ @JsonProperty(required = true, value = JSON_PROPERTY_ATTRIBUTES)
+ AIImpactUserActivityAttributes attributes,
+ @JsonProperty(required = true, value = JSON_PROPERTY_TYPE) AIImpactUserActivityType type) {
+ this.attributes = attributes;
+ this.unparsed |= attributes.unparsed;
+ this.type = type;
+ this.unparsed |= !type.isValid();
+ }
+
+ public AIImpactUserActivityData attributes(AIImpactUserActivityAttributes attributes) {
+ this.attributes = attributes;
+ this.unparsed |= attributes.unparsed;
+ return this;
+ }
+
+ /**
+ * Daily AI coding tool activity for a single user. Each entry reports whether the user was active
+ * on a given day and which AI tools and models they used.
+ *
+ * @return attributes
+ */
+ @JsonProperty(JSON_PROPERTY_ATTRIBUTES)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public AIImpactUserActivityAttributes getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(AIImpactUserActivityAttributes attributes) {
+ this.attributes = attributes;
+ if (attributes != null) {
+ this.unparsed |= attributes.unparsed;
+ }
+ }
+
+ public AIImpactUserActivityData type(AIImpactUserActivityType type) {
+ this.type = type;
+ this.unparsed |= !type.isValid();
+ return this;
+ }
+
+ /**
+ * JSON:API type for AI Impact user activity entries.
+ *
+ * @return type
+ */
+ @JsonProperty(JSON_PROPERTY_TYPE)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public AIImpactUserActivityType getType() {
+ return type;
+ }
+
+ public void setType(AIImpactUserActivityType type) {
+ if (!type.isValid()) {
+ this.unparsed = true;
+ }
+ this.type = type;
+ }
+
+ /** Return true if this AIImpactUserActivityData object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ AIImpactUserActivityData aiImpactUserActivityData = (AIImpactUserActivityData) o;
+ return Objects.equals(this.attributes, aiImpactUserActivityData.attributes)
+ && Objects.equals(this.type, aiImpactUserActivityData.type);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(attributes, type);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class AIImpactUserActivityData {\n");
+ sb.append(" attributes: ").append(toIndentedString(attributes)).append("\n");
+ sb.append(" type: ").append(toIndentedString(type)).append("\n");
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityRequest.java b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityRequest.java
new file mode 100644
index 00000000000..f09de890b4a
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityRequest.java
@@ -0,0 +1,109 @@
+/*
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
+ * Copyright 2019-Present Datadog, Inc.
+ */
+
+package com.datadog.api.client.v2.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/** Request to send daily AI tool activity for one or more users. */
+@JsonPropertyOrder({AIImpactUserActivityRequest.JSON_PROPERTY_DATA})
+@jakarta.annotation.Generated(
+ value = "https://github.com/DataDog/datadog-api-client-java/blob/master/.generator")
+public class AIImpactUserActivityRequest {
+ @JsonIgnore public boolean unparsed = false;
+ public static final String JSON_PROPERTY_DATA = "data";
+ private List data = new ArrayList<>();
+
+ public AIImpactUserActivityRequest() {}
+
+ @JsonCreator
+ public AIImpactUserActivityRequest(
+ @JsonProperty(required = true, value = JSON_PROPERTY_DATA)
+ List data) {
+ this.data = data;
+ for (AIImpactUserActivityData item : data) {
+ this.unparsed |= item.unparsed;
+ }
+ }
+
+ public AIImpactUserActivityRequest data(List data) {
+ this.data = data;
+ for (AIImpactUserActivityData item : data) {
+ this.unparsed |= item.unparsed;
+ }
+ return this;
+ }
+
+ public AIImpactUserActivityRequest addDataItem(AIImpactUserActivityData dataItem) {
+ this.data.add(dataItem);
+ this.unparsed |= dataItem.unparsed;
+ return this;
+ }
+
+ /**
+ * A batch of daily AI tool activity entries. A batch must contain between 1 and 1,000 entries.
+ *
+ * @return data
+ */
+ @JsonProperty(JSON_PROPERTY_DATA)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ if (data != null) {
+ for (AIImpactUserActivityData item : data) {
+ this.unparsed |= item.unparsed;
+ }
+ }
+ }
+
+ /** Return true if this AIImpactUserActivityRequest object is equal to o. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ AIImpactUserActivityRequest aiImpactUserActivityRequest = (AIImpactUserActivityRequest) o;
+ return Objects.equals(this.data, aiImpactUserActivityRequest.data);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(data);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class AIImpactUserActivityRequest {\n");
+ sb.append(" data: ").append(toIndentedString(data)).append("\n");
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
diff --git a/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityType.java b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityType.java
new file mode 100644
index 00000000000..007abb21f82
--- /dev/null
+++ b/src/main/java/com/datadog/api/client/v2/model/AIImpactUserActivityType.java
@@ -0,0 +1,57 @@
+/*
+ * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
+ * This product includes software developed at Datadog (https://www.datadoghq.com/).
+ * Copyright 2019-Present Datadog, Inc.
+ */
+
+package com.datadog.api.client.v2.model;
+
+import com.datadog.api.client.ModelEnum;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/** JSON:API type for AI Impact user activity entries. */
+@JsonSerialize(using = AIImpactUserActivityType.AIImpactUserActivityTypeSerializer.class)
+public class AIImpactUserActivityType extends ModelEnum {
+
+ private static final Set allowedValues =
+ new HashSet(Arrays.asList("ai_impact_user_activity"));
+
+ public static final AIImpactUserActivityType AI_IMPACT_USER_ACTIVITY =
+ new AIImpactUserActivityType("ai_impact_user_activity");
+
+ AIImpactUserActivityType(String value) {
+ super(value, allowedValues);
+ }
+
+ public static class AIImpactUserActivityTypeSerializer
+ extends StdSerializer {
+ public AIImpactUserActivityTypeSerializer(Class t) {
+ super(t);
+ }
+
+ public AIImpactUserActivityTypeSerializer() {
+ this(null);
+ }
+
+ @Override
+ public void serialize(
+ AIImpactUserActivityType value, JsonGenerator jgen, SerializerProvider provider)
+ throws IOException, JsonProcessingException {
+ jgen.writeObject(value.value);
+ }
+ }
+
+ @JsonCreator
+ public static AIImpactUserActivityType fromValue(String value) {
+ return new AIImpactUserActivityType(value);
+ }
+}
diff --git a/src/test/resources/com/datadog/api/client/v2/api/ai_impact.feature b/src/test/resources/com/datadog/api/client/v2/api/ai_impact.feature
new file mode 100644
index 00000000000..ee04200c6b9
--- /dev/null
+++ b/src/test/resources/com/datadog/api/client/v2/api/ai_impact.feature
@@ -0,0 +1,20 @@
+@endpoint(ai-impact) @endpoint(ai-impact-v2)
+Feature: AI Impact
+ Send AI coding tool usage data to measure the impact of AI tools on
+ software delivery.
+
+ Background:
+ Given a valid "apiKeyAuth" key in the system
+ And an instance of "AIImpact" API
+ And new "CreateAIImpactUserActivity" request
+ And body with value {"data": [{"attributes": {"day": "2026-05-26", "is_active": true, "models": ["claude-sonnet-4.5", "gpt-5"], "tools": ["Claude Code", "Cursor"], "user_email": "user@example.com"}, "type": "ai_impact_user_activity"}]}
+
+ @generated @skip @team:ddoghq/ci-app-backend
+ Scenario: Send AI tool user activity returns "Bad Request: the batch is empty, has more than 1,000 entries, or contains an invalid entry." response
+ When the request is sent
+ Then the response status is 400 Bad Request: the batch is empty, has more than 1,000 entries, or contains an invalid entry.
+
+ @generated @skip @team:ddoghq/ci-app-backend
+ Scenario: Send AI tool user activity returns "OK" response
+ When the request is sent
+ Then the response status is 200 OK
diff --git a/src/test/resources/com/datadog/api/client/v2/api/undo.json b/src/test/resources/com/datadog/api/client/v2/api/undo.json
index c7e0bfc8bb7..b54343dc540 100644
--- a/src/test/resources/com/datadog/api/client/v2/api/undo.json
+++ b/src/test/resources/com/datadog/api/client/v2/api/undo.json
@@ -368,6 +368,12 @@
"type": "safe"
}
},
+ "CreateAIImpactUserActivity": {
+ "tag": "AI Impact",
+ "undo": {
+ "type": "idempotent"
+ }
+ },
"ListAnnotations": {
"tag": "Annotations",
"undo": {