diff --git a/crates/teloxide-core/src/payloads/codegen.rs b/crates/teloxide-core/src/payloads/codegen.rs
index f3503a1b..03bb9957 100644
--- a/crates/teloxide-core/src/payloads/codegen.rs
+++ b/crates/teloxide-core/src/payloads/codegen.rs
@@ -223,6 +223,11 @@ fn params(params: impl Iterator<Item = impl Borrow<Param>>) -> String {
                 {
                     "\n            #[serde(flatten)]"
                 }
+                Type::ArrayOf(b) if **b == Type::RawTy("MessageId".to_string()) =>
+                {
+                    "\n            #[serde(with = \
+                     \"crate::types::vec_msg_id_as_vec_int\")]"
+                }
                 _ => "",
             };
             let with = match ty {
diff --git a/crates/teloxide-core/src/payloads/copy_messages.rs b/crates/teloxide-core/src/payloads/copy_messages.rs
index 90a4cd90..87b6c915 100644
--- a/crates/teloxide-core/src/payloads/copy_messages.rs
+++ b/crates/teloxide-core/src/payloads/copy_messages.rs
@@ -17,6 +17,7 @@ impl_payload! {
             /// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`)
             pub from_chat_id: Recipient [into],
             /// Identifiers of 1-100 messages in the chat _from\_chat\_id_ to copy. The identifiers must be specified in a strictly increasing order.
+            #[serde(with = "crate::types::vec_msg_id_as_vec_int")]
             pub message_ids: Vec<MessageId> [collect],
         }
         optional {
diff --git a/crates/teloxide-core/src/payloads/delete_messages.rs b/crates/teloxide-core/src/payloads/delete_messages.rs
index f8306c03..e28e04ae 100644
--- a/crates/teloxide-core/src/payloads/delete_messages.rs
+++ b/crates/teloxide-core/src/payloads/delete_messages.rs
@@ -14,6 +14,7 @@ impl_payload! {
             /// Identifiers of 1-100 messages to delete. See [`DeleteMessage`] for limitations on which messages can be deleted
             ///
             /// [`DeleteMessage`]: crate::payloads::DeleteMessage
+            #[serde(with = "crate::types::vec_msg_id_as_vec_int")]
             pub message_ids: Vec<MessageId> [collect],
         }
     }
diff --git a/crates/teloxide-core/src/payloads/forward_messages.rs b/crates/teloxide-core/src/payloads/forward_messages.rs
index e191725b..e0ff6a23 100644
--- a/crates/teloxide-core/src/payloads/forward_messages.rs
+++ b/crates/teloxide-core/src/payloads/forward_messages.rs
@@ -16,6 +16,7 @@ impl_payload! {
             /// Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`)
             pub from_chat_id: Recipient [into],
             /// A JSON-serialized list of 1-100 identifiers of messages in the chat _from\_chat\_id_ to forward. The identifiers must be specified in a strictly increasing order.
+            #[serde(with = "crate::types::vec_msg_id_as_vec_int")]
             pub message_ids: Vec<MessageId> [collect],
         }
         optional {
diff --git a/crates/teloxide-core/src/types.rs b/crates/teloxide-core/src/types.rs
index 3d10253b..465869d6 100644
--- a/crates/teloxide-core/src/types.rs
+++ b/crates/teloxide-core/src/types.rs
@@ -546,3 +546,35 @@ pub(crate) mod option_msg_id_as_int {
         }
     }
 }
+
+pub(crate) mod vec_msg_id_as_vec_int {
+    use crate::types::MessageId;
+
+    use serde::{ser::SerializeSeq, Serializer};
+
+    pub(crate) fn serialize<S>(msg_ids: &Vec<MessageId>, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut seq = serializer.serialize_seq(Some(msg_ids.len()))?;
+        for e in msg_ids {
+            seq.serialize_element(&e.0)?;
+        }
+        seq.end()
+    }
+
+    #[test]
+    fn test() {
+        #[derive(serde::Serialize)]
+        struct Struct {
+            #[serde(with = "crate::types::vec_msg_id_as_vec_int")]
+            msg_ids: Vec<MessageId>,
+        }
+
+        {
+            let s = Struct {msg_ids: vec![MessageId(1), MessageId(2)]};
+            let json = serde_json::to_string(&s).unwrap();
+            assert_eq!(json, "{\"msg_ids\":[1,2]}");
+        }
+    }
+}