diff --git a/pom.xml b/pom.xml
index 348f7f3..c39bd86 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
     <artifactId>twitter-api-java-sdk</artifactId>
     <packaging>jar</packaging>
     <name>twitter-api-java-sdk</name>
-    <version>2.0.3</version>
+    <version>2.0.4</version>
     <url>https://github.com/twitterdev/twitter-api-java-sdk</url>
     <description>Twitter API v2 available endpoints</description>
     <scm>
diff --git a/src/main/java/com/twitter/clientlib/api/DmApi.java b/src/main/java/com/twitter/clientlib/api/DmApi.java
new file mode 100644
index 0000000..68ad24a
--- /dev/null
+++ b/src/main/java/com/twitter/clientlib/api/DmApi.java
@@ -0,0 +1,304 @@
+package com.twitter.clientlib.api;
+
+import com.google.gson.reflect.TypeToken;
+import com.twitter.clientlib.*;
+import com.twitter.clientlib.model.DmEvent;
+import com.twitter.clientlib.model.Get2DmEventsResponse;
+import com.twitter.clientlib.model.ReplyToDmConversationResponse;
+import okhttp3.Call;
+
+import java.lang.reflect.Type;
+import java.util.*;
+
+public class DmApi extends ApiCommon {
+
+    public class APIfindDmEventsRequest {
+        private Set<String> tweetFields;
+        private Set<String> expansions;
+        private Set<String> mediaFields;
+        private Set<String> userFields;
+        private Set<String> dmEventsFields;
+        private Set<String> dmEventTypes;
+        private Integer maxResults;
+        private String paginationToken;
+        private final Set<String> tweetFieldsAll = new HashSet<>(Arrays.asList("attachments", "author_id", "context_annotations", "conversation_id", "created_at", "edit_controls", "edit_history_tweet_ids", "entities", "geo", "id", "in_reply_to_user_id", "lang", "non_public_metrics", "organic_metrics", "possibly_sensitive", "promoted_metrics", "public_metrics", "referenced_tweets", "reply_settings", "source", "text", "withheld"));
+        private final Set<String> mediaFieldsAll = new HashSet<>(Arrays.asList("alt_text", "duration_ms", "height", "media_key", "non_public_metrics", "organic_metrics", "preview_image_url", "promoted_metrics", "public_metrics", "type", "url", "variants", "width"));
+        private final Set<String> userFieldsAll = new HashSet<>(Arrays.asList("created_at", "description", "entities", "id", "location", "name", "pinned_tweet_id", "profile_image_url", "protected", "public_metrics", "url", "username", "verified", "withheld"));
+        private final Set<String> expansionsAll = new HashSet<>(Arrays.asList("attachments.media_keys", "referenced_tweets.id", "sender_id", "participant_ids"));
+        private final Set<String> dmEventsFieldsAll = new HashSet<>(Arrays.asList("id", "text", "event_type", "created_at", "dm_conversation_id", "sender_id", "participant_ids", "referenced_tweets", "attachments"));
+        private final Set<String> dmEventTypesAll = new HashSet<>(Arrays.asList("MessageCreate", "ParticipantsJoin", "ParticipantsLeave"));
+
+        private boolean isExclude = false;
+
+        public APIfindDmEventsRequest excludeInputFields() {
+            isExclude = true;
+            return this;
+        }
+
+        public APIfindDmEventsRequest tweetFields(Set<String> tweetFields) {
+            this.tweetFields = tweetFields;
+            return this;
+        }
+
+        public APIfindDmEventsRequest expansions(Set<String> expansions) {
+            this.expansions = expansions;
+            return this;
+        }
+
+        public APIfindDmEventsRequest mediaFields(Set<String> mediaFields) {
+            this.mediaFields = mediaFields;
+            return this;
+        }
+
+        public APIfindDmEventsRequest userFields(Set<String> userFields) {
+            this.userFields = userFields;
+            return this;
+        }
+
+        public APIfindDmEventsRequest dmEventsFields(Set<String> dmEventsFields) {
+            this.dmEventsFields = dmEventsFields;
+            return this;
+        }
+
+        public APIfindDmEventsRequest dmEventTypes(Set<String> dmEventTypes) {
+            this.dmEventTypes = dmEventTypes;
+            return this;
+        }
+
+        public APIfindDmEventsRequest maxResults(Integer maxResults) {
+            this.maxResults = maxResults;
+            return this;
+        }
+
+        public APIfindDmEventsRequest paginationToken(String paginationToken) {
+            this.paginationToken = paginationToken;
+            return this;
+        }
+
+        public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException {
+            return findDmEventsCall(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventTypes, maxResults, paginationToken, _callback);
+        }
+
+        public Get2DmEventsResponse execute() throws ApiException {
+            tweetFields = getFields("tweetFields", isExclude, tweetFields, tweetFieldsAll);
+            expansions = getFields("expansions", isExclude, expansions, expansionsAll);
+            mediaFields = getFields("mediaFields", isExclude, mediaFields, mediaFieldsAll);
+            userFields = getFields("userFields", isExclude, userFields, userFieldsAll);
+            dmEventsFields = getFields("dm_event.fields", isExclude, dmEventsFields, dmEventsFieldsAll);
+            dmEventTypes = getFields("event_types", isExclude, dmEventTypes, dmEventTypesAll);
+
+            ApiResponse<Get2DmEventsResponse> localVarResp = findDmEventsCallWithHttpInfo(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventTypes, maxResults, paginationToken);
+            return localVarResp.getData();
+        }
+
+        public Get2DmEventsResponse execute(Integer retries) throws ApiException {
+            Get2DmEventsResponse localVarResp;
+            try{
+                localVarResp = execute();
+            } catch (ApiException e) {
+                if(handleRateLimit(e, retries)) {
+                    return execute(retries - 1);
+                } else {
+                    throw e;
+                }
+            }
+            return localVarResp;
+        }
+
+        public ApiResponse<Get2DmEventsResponse> executeWithHttpInfo() throws ApiException {
+            return findDmEventsCallWithHttpInfo(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventTypes, maxResults, paginationToken);
+        }
+
+        public okhttp3.Call executeAsync(final ApiCallback<Get2DmEventsResponse> _callback) throws ApiException {
+            return findDmEventsCallAsync(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventTypes, maxResults, paginationToken, _callback);
+        }
+    }
+
+    private Call findDmEventsCall(Set<String> tweetFields, Set<String> expansions, Set<String> mediaFields, Set<String> userFields, Set<String> dmEventsFields, Set<String> dmEventsTypes, Integer maxResults, String paginationToken, ApiCallback callback) throws ApiException {
+        Object localVarPostBody = null;
+
+        String localVarPath = "/2/dm_events";
+
+        List<Pair> localVarQueryParams = new ArrayList<Pair>();
+        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
+        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
+        Map<String, String> localVarCookieParams = new HashMap<String, String>();
+        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
+
+        if (tweetFields != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "tweet.fields", tweetFields));
+        }
+
+        if (expansions != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "expansions", expansions));
+        }
+
+        if (mediaFields != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "media.fields", mediaFields));
+        }
+
+        if (userFields != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "user.fields", userFields));
+        }
+
+        if (dmEventsFields != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "dm_event.fields", dmEventsFields));
+        }
+
+        if (dmEventsTypes != null) {
+            localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("csv", "event_types", dmEventsTypes));
+        }
+
+        if (maxResults != null) {
+            localVarQueryParams.addAll(localVarApiClient.parameterToPair("max_results", maxResults));
+        }
+
+        if (paginationToken != null) {
+            localVarQueryParams.addAll(localVarApiClient.parameterToPair("pagination_token", paginationToken));
+        }
+
+        final String[] localVarAccepts = {
+            "application/json", "application/problem+json"
+        };
+        final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+        if (localVarAccept != null) {
+            localVarHeaderParams.put("Accept", localVarAccept);
+        }
+
+        String[] localVarAuthNames = new String[] { "OAuth2UserToken", "UserToken" };
+        return localVarApiClient.buildCall(localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, reduceAuthNames(localVarAuthNames), callback);
+    }
+
+    private Call findDmEventsValidateBeforeCall(Set<String> tweetFields, Set<String> expansions, Set<String> mediaFields, Set<String> userFields, Set<String> dmEventsFields, Set<String> dmEventsTypes, Integer maxResults, String paginationToken, final ApiCallback _callback) throws ApiException {
+        okhttp3.Call localVarCall = findDmEventsCall(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventsTypes, maxResults, paginationToken, _callback);
+        return localVarCall;
+    }
+
+    private ApiResponse<Get2DmEventsResponse> findDmEventsCallWithHttpInfo(Set<String> tweetFields, Set<String> expansions, Set<String> mediaFields, Set<String> userFields, Set<String> dmEventsFields, Set<String> dmEventsTypes, Integer maxResults, String paginationToken) throws ApiException {
+        okhttp3.Call localVarCall = findDmEventsValidateBeforeCall(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventsTypes, maxResults, paginationToken, null);
+        try {
+            Type localVarReturnType = new TypeToken<Get2DmEventsResponse>(){}.getType();
+            return localVarApiClient.execute(localVarCall, localVarReturnType);
+        } catch (ApiException e) {
+            e.setErrorObject(localVarApiClient.getJSON().getGson().fromJson(e.getResponseBody(), new TypeToken<com.twitter.clientlib.model.ProblemOrError>(){}.getType()));
+            throw e;
+        }
+    }
+
+    private okhttp3.Call findDmEventsCallAsync(Set<String> tweetFields, Set<String> expansions, Set<String> mediaFields, Set<String> userFields, Set<String> dmEventsFields, Set<String> dmEventsTypes, Integer maxResults, String paginationToken, final ApiCallback<Get2DmEventsResponse> _callback) throws ApiException {
+
+        okhttp3.Call localVarCall = findDmEventsValidateBeforeCall(tweetFields, expansions, mediaFields, userFields, dmEventsFields, dmEventsTypes, maxResults, paginationToken, _callback);
+        Type localVarReturnType = new TypeToken<Get2DmEventsResponse>(){}.getType();
+        localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback);
+        return localVarCall;
+    }
+
+    public APIfindDmEventsRequest findDmEvents() {
+        return new APIfindDmEventsRequest();
+    }
+
+    public APIreplyToDmConversationRequest replyToDmConversation(String conversationId, String text) {
+        return new APIreplyToDmConversationRequest(conversationId, text);
+    }
+
+    private Call replyToDmConversationValidateBeforeCall(String id, String text, ApiCallback _callback) throws ApiException {
+        if (id == null) {
+            throw new ApiException("Missing the required parameter 'id' when calling replyToDmConversation(Async)");
+        }
+
+        if (text == null) {
+            throw new ApiException("Missing the required parameter 'text' when calling replyToDmConversation(Async)");
+        }
+
+        okhttp3.Call localVarCall = replyToDmConversationCall(id, text, _callback);
+        return localVarCall;
+    }
+
+    private ApiResponse<ReplyToDmConversationResponse> replyToDmConversationWithHttpInfo(String id, String text) throws ApiException {
+        okhttp3.Call localVarCall = replyToDmConversationValidateBeforeCall(id, text, null);
+        Type localVarReturnType = new TypeToken<ReplyToDmConversationResponse>(){}.getType();
+        return localVarApiClient.execute(localVarCall, localVarReturnType);
+    }
+
+    private Call replyToDmConversationCallAsync(String id, String text, ApiCallback<ReplyToDmConversationResponse> callback) throws ApiException {
+        okhttp3.Call localVarCall = replyToDmConversationValidateBeforeCall(id, text, callback);
+        Type localVarReturnType = new TypeToken<ReplyToDmConversationResponse>(){}.getType();
+        localVarApiClient.executeAsync(localVarCall, localVarReturnType, callback);
+        return localVarCall;
+    }
+
+    private Call replyToDmConversationCall(String id, String text, ApiCallback _callback) throws ApiException {
+        Object localVarPostBody = new DmEvent(text);
+
+        String localVarPath = "/2/dm_conversations/{id}/messages"
+            .replaceAll("\\{" + "id" + "\\}", localVarApiClient.escapeString(id.toString()));
+
+        List<Pair> localVarQueryParams = new ArrayList<Pair>();
+        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
+        Map<String, String> localVarHeaderParams = new HashMap<String, String>();
+        Map<String, String> localVarCookieParams = new HashMap<String, String>();
+        Map<String, Object> localVarFormParams = new HashMap<String, Object>();
+
+        final String[] localVarAccepts = {
+            "application/json"
+        };
+        final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
+        if (localVarAccept != null) {
+            localVarHeaderParams.put("Accept", localVarAccept);
+        }
+
+        final String[] localVarContentTypes = {
+            "application/json"
+        };
+        final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
+        if (localVarContentType != null) {
+            localVarHeaderParams.put("Content-Type", localVarContentType);
+        }
+
+        String[] localVarAuthNames = new String[] { "OAuth2UserToken", "UserToken" };
+        return localVarApiClient.buildCall(localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, reduceAuthNames(localVarAuthNames), _callback);
+    }
+
+    public class APIreplyToDmConversationRequest {
+
+        private final String id;
+        private final String text;
+
+        public APIreplyToDmConversationRequest(String conversationId, String text) {
+            this.id = conversationId;
+            this.text = text;
+        }
+
+        public okhttp3.Call buildCall(final ApiCallback _callback) throws ApiException {
+            return replyToDmConversationCall(id, text, _callback);
+        }
+
+        public ReplyToDmConversationResponse execute() throws ApiException {
+            ApiResponse<ReplyToDmConversationResponse> localVarResp = replyToDmConversationWithHttpInfo(id, text);
+            return localVarResp.getData();
+        }
+
+        public ReplyToDmConversationResponse execute(Integer retries) throws ApiException {
+            ReplyToDmConversationResponse localVarResp;
+            try{
+                localVarResp = execute();
+            } catch (ApiException e) {
+                if(handleRateLimit(e, retries)) {
+                    return execute(retries - 1);
+                } else {
+                    throw e;
+                }
+            }
+            return localVarResp;
+        }
+
+        public ApiResponse<ReplyToDmConversationResponse> executeWithHttpInfo() throws ApiException {
+            return replyToDmConversationWithHttpInfo(id, text);
+        }
+
+        public okhttp3.Call executeAsync(final ApiCallback<ReplyToDmConversationResponse> _callback) throws ApiException {
+            return replyToDmConversationCallAsync(id, text, _callback);
+        }
+    }
+
+}
diff --git a/src/main/java/com/twitter/clientlib/api/TweetsApi.java b/src/main/java/com/twitter/clientlib/api/TweetsApi.java
index f726eb7..4a8284b 100644
--- a/src/main/java/com/twitter/clientlib/api/TweetsApi.java
+++ b/src/main/java/com/twitter/clientlib/api/TweetsApi.java
@@ -22,69 +22,17 @@
 
 package com.twitter.clientlib.api;
 
+import com.google.gson.reflect.TypeToken;
 import com.twitter.clientlib.ApiCallback;
-import com.twitter.clientlib.ApiClient;
-import com.twitter.clientlib.auth.*;
 import com.twitter.clientlib.ApiException;
 import com.twitter.clientlib.ApiResponse;
-import com.twitter.clientlib.Configuration;
 import com.twitter.clientlib.Pair;
-import com.twitter.clientlib.ProgressRequestBody;
-import com.twitter.clientlib.ProgressResponseBody;
-
-import com.github.scribejava.core.model.OAuth2AccessToken;
-import com.google.gson.reflect.TypeToken;
-
-import java.io.IOException;
-import java.util.HashSet;
-
-
-import com.twitter.clientlib.model.AddOrDeleteRulesRequest;
-import com.twitter.clientlib.model.AddOrDeleteRulesResponse;
-import com.twitter.clientlib.model.Error;
-import com.twitter.clientlib.model.FilteredStreamingTweetResponse;
-import com.twitter.clientlib.model.Get2ListsIdTweetsResponse;
-import com.twitter.clientlib.model.Get2SpacesIdBuyersResponse;
-import com.twitter.clientlib.model.Get2SpacesIdTweetsResponse;
-import com.twitter.clientlib.model.Get2TweetsCountsAllResponse;
-import com.twitter.clientlib.model.Get2TweetsCountsRecentResponse;
-import com.twitter.clientlib.model.Get2TweetsIdQuoteTweetsResponse;
-import com.twitter.clientlib.model.Get2TweetsIdResponse;
-import com.twitter.clientlib.model.Get2TweetsResponse;
-import com.twitter.clientlib.model.Get2TweetsSample10StreamResponse;
-import com.twitter.clientlib.model.Get2TweetsSearchAllResponse;
-import com.twitter.clientlib.model.Get2TweetsSearchRecentResponse;
-import com.twitter.clientlib.model.Get2UsersIdLikedTweetsResponse;
-import com.twitter.clientlib.model.Get2UsersIdMentionsResponse;
-import com.twitter.clientlib.model.Get2UsersIdTimelinesReverseChronologicalResponse;
-import com.twitter.clientlib.model.Get2UsersIdTweetsResponse;
-import java.time.OffsetDateTime;
-import com.twitter.clientlib.model.Problem;
-import com.twitter.clientlib.model.RulesLookupResponse;
-import java.util.Set;
-import com.twitter.clientlib.model.StreamingTweetResponse;
-import com.twitter.clientlib.model.TweetCreateRequest;
-import com.twitter.clientlib.model.TweetCreateResponse;
-import com.twitter.clientlib.model.TweetDeleteResponse;
-import com.twitter.clientlib.model.TweetHideRequest;
-import com.twitter.clientlib.model.TweetHideResponse;
-import com.twitter.clientlib.model.UsersLikesCreateRequest;
-import com.twitter.clientlib.model.UsersLikesCreateResponse;
-import com.twitter.clientlib.model.UsersLikesDeleteResponse;
-import com.twitter.clientlib.model.UsersRetweetsCreateRequest;
-import com.twitter.clientlib.model.UsersRetweetsCreateResponse;
-import com.twitter.clientlib.model.UsersRetweetsDeleteResponse;
+import com.twitter.clientlib.model.*;
 
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Arrays;
 import java.io.InputStream;
-import javax.ws.rs.core.GenericType;
-
-import org.apache.commons.lang3.StringUtils;
+import java.lang.reflect.Type;
+import java.time.OffsetDateTime;
+import java.util.*;
 
 public class TweetsApi extends ApiCommon {
 
diff --git a/src/main/java/com/twitter/clientlib/api/TwitterApi.java b/src/main/java/com/twitter/clientlib/api/TwitterApi.java
index a20b38f..d672b7c 100644
--- a/src/main/java/com/twitter/clientlib/api/TwitterApi.java
+++ b/src/main/java/com/twitter/clientlib/api/TwitterApi.java
@@ -42,6 +42,7 @@ public class TwitterApi {
   private final SpacesApi spaces = new SpacesApi();
   private final TweetsApi tweets = new TweetsApi();
   private final UsersApi users = new UsersApi();
+  private final DmApi dm = new DmApi();
   private ApiClient localVarApiClient = new ApiClient();
 
   public TwitterApi(TwitterCredentialsBearer credentials) {
@@ -84,6 +85,7 @@ private void initApis() {
     spaces.setClient(localVarApiClient);
     tweets.setClient(localVarApiClient);
     users.setClient(localVarApiClient);
+    dm.setClient(localVarApiClient);
   }
 
   public BookmarksApi bookmarks() {
@@ -107,6 +109,9 @@ public TweetsApi tweets() {
   public UsersApi users() {
     return users;
   }
+  public DmApi dm() {
+    return dm;
+  }
 
   public OAuth2AccessToken refreshToken() throws ApiException {
     return localVarApiClient.refreshToken();
diff --git a/src/main/java/com/twitter/clientlib/model/DmEvent.java b/src/main/java/com/twitter/clientlib/model/DmEvent.java
new file mode 100644
index 0000000..61205a5
--- /dev/null
+++ b/src/main/java/com/twitter/clientlib/model/DmEvent.java
@@ -0,0 +1,103 @@
+package com.twitter.clientlib.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.time.OffsetDateTime;
+
+public class DmEvent {
+
+    @SerializedName("id")
+    private String id;
+
+    @SerializedName("sender_id")
+    private String senderId;
+
+    @SerializedName("event_type")
+    private String eventType; // TODO enum
+
+    @SerializedName("text")
+    private String text;
+
+    @SerializedName("dm_conversation_id")
+    private String dmConversationId;
+
+    @SerializedName("created_at")
+    private OffsetDateTime createdAt;
+
+    public DmEvent() {
+
+    }
+
+    public DmEvent(String text) {
+        this.text = text;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getSenderId() {
+        return senderId;
+    }
+
+    public void setSenderId(String senderId) {
+        this.senderId = senderId;
+    }
+
+    public String getEventType() {
+        return eventType;
+    }
+
+    public void setEventType(String eventType) {
+        this.eventType = eventType;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getDmConversationId() {
+        return dmConversationId;
+    }
+
+    public void setDmConversationId(String dmConversationId) {
+        this.dmConversationId = dmConversationId;
+    }
+
+    public OffsetDateTime getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(OffsetDateTime createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class DmEvent {\n");
+        sb.append("    id: ").append(toIndentedString(id)).append("\n");
+        sb.append("    senderId: ").append(toIndentedString(senderId)).append("\n");
+        sb.append("    eventType: ").append(toIndentedString(eventType)).append("\n");
+        sb.append("    text: ").append(toIndentedString(text)).append("\n");
+        sb.append("    dmConversationId: ").append(toIndentedString(dmConversationId)).append("\n");
+        sb.append("    createdAt: ").append(toIndentedString(createdAt)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private String toIndentedString(Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+}
diff --git a/src/main/java/com/twitter/clientlib/model/Get2DmEventsResponse.java b/src/main/java/com/twitter/clientlib/model/Get2DmEventsResponse.java
new file mode 100644
index 0000000..54f11d4
--- /dev/null
+++ b/src/main/java/com/twitter/clientlib/model/Get2DmEventsResponse.java
@@ -0,0 +1,132 @@
+package com.twitter.clientlib.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class Get2DmEventsResponse {
+
+    public static final String SERIALIZED_NAME_DATA = "data";
+    @SerializedName(SERIALIZED_NAME_DATA)
+    private List<DmEvent> data = null;
+
+    public static final String SERIALIZED_NAME_ERRORS = "errors";
+    @SerializedName(SERIALIZED_NAME_ERRORS)
+    private List<Problem> errors = null;
+
+    public static final String SERIALIZED_NAME_INCLUDES = "includes";
+    @SerializedName(SERIALIZED_NAME_INCLUDES)
+    private Expansions includes;
+
+    public static final String SERIALIZED_NAME_META = "meta";
+    @SerializedName(SERIALIZED_NAME_META)
+    private Get2TweetsSearchAllResponseMeta meta;
+
+    public Get2DmEventsResponse() {
+
+    }
+
+    public Get2DmEventsResponse data(List<DmEvent> data) {
+        this.data = data;
+        return this;
+    }
+
+    public Get2DmEventsResponse addDataItem(DmEvent dataItem) {
+        if (this.data == null) {
+            this.data = new ArrayList<>();
+        }
+        this.data.add(dataItem);
+        return this;
+    }
+
+    public List<DmEvent> getData() {
+        return data;
+    }
+
+    public void setData(List<DmEvent> data) {
+        this.data = data;
+    }
+
+    public Get2DmEventsResponse errors(List<Problem> errors) {
+        this.errors = errors;
+        return this;
+    }
+
+    public Get2DmEventsResponse addErrorsItem(Problem errorsItem) {
+        if (this.errors == null) {
+            this.errors = new ArrayList<>();
+        }
+        this.errors.add(errorsItem);
+        return this;
+    }
+
+    public List<Problem> getErrors() {
+        return errors;
+    }
+
+    public void setErrors(List<Problem> errors) {
+        this.errors = errors;
+    }
+
+    public Get2DmEventsResponse includes(Expansions includes) {
+        this.includes = includes;
+        return this;
+    }
+
+    public Expansions getIncludes() {
+        return includes;
+    }
+
+    public void setIncludes(Expansions includes) {
+        this.includes = includes;
+    }
+
+    public Get2DmEventsResponse meta(Get2TweetsSearchAllResponseMeta meta) {
+        this.meta = meta;
+        return this;
+    }
+
+    public Get2TweetsSearchAllResponseMeta getMeta() {
+        return meta;
+    }
+
+    public void setMeta(Get2TweetsSearchAllResponseMeta meta) {
+        this.meta = meta;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Get2DmEventsResponse get2DmEventsResponse = (Get2DmEventsResponse) o;
+        return Objects.equals(this.data, get2DmEventsResponse.data) &&
+                Objects.equals(this.errors, get2DmEventsResponse.errors) &&
+                Objects.equals(this.includes, get2DmEventsResponse.includes) &&
+                Objects.equals(this.meta, get2DmEventsResponse.meta);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class Get2DmEventsResponse {\n");
+        sb.append("    data: ").append(toIndentedString(data)).append("\n");
+        sb.append("    errors: ").append(toIndentedString(errors)).append("\n");
+        sb.append("    includes: ").append(toIndentedString(includes)).append("\n");
+        sb.append("    meta: ").append(toIndentedString(meta)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private String toIndentedString(Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+}
diff --git a/src/main/java/com/twitter/clientlib/model/NewDmEvent.java b/src/main/java/com/twitter/clientlib/model/NewDmEvent.java
new file mode 100644
index 0000000..2506bb2
--- /dev/null
+++ b/src/main/java/com/twitter/clientlib/model/NewDmEvent.java
@@ -0,0 +1,28 @@
+package com.twitter.clientlib.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class NewDmEvent {
+
+    @SerializedName("dm_conversation_id")
+    private String dmConversationId;
+
+    @SerializedName("dm_event_id")
+    private String dmEventId;
+
+    public String getDmConversationId() {
+        return dmConversationId;
+    }
+
+    public void setDmConversationId(String dmConversationId) {
+        this.dmConversationId = dmConversationId;
+    }
+
+    public String getDmEventId() {
+        return dmEventId;
+    }
+
+    public void setDmEventId(String dmEventId) {
+        this.dmEventId = dmEventId;
+    }
+}
diff --git a/src/main/java/com/twitter/clientlib/model/ReplyToDmConversationResponse.java b/src/main/java/com/twitter/clientlib/model/ReplyToDmConversationResponse.java
new file mode 100644
index 0000000..de00d26
--- /dev/null
+++ b/src/main/java/com/twitter/clientlib/model/ReplyToDmConversationResponse.java
@@ -0,0 +1,17 @@
+package com.twitter.clientlib.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class ReplyToDmConversationResponse {
+
+    @SerializedName("data")
+    private NewDmEvent data;
+
+    public NewDmEvent getData() {
+        return data;
+    }
+
+    public void setData(NewDmEvent data) {
+        this.data = data;
+    }
+}