diff --git a/WEB-INF/src/controleur/API.java b/WEB-INF/src/controleur/API.java
new file mode 100644
index 0000000000000000000000000000000000000000..689f2c78bed263a5879f20c7f32d0fa9c08c4390
--- /dev/null
+++ b/WEB-INF/src/controleur/API.java
@@ -0,0 +1,136 @@
+package controleur;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import modele.dao.DaoFollower;
+import modele.dao.DaoMessage;
+import modele.dao.DaoThread;
+import modele.dto.Message;
+import modele.dto.Thread;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+@WebServlet("/api/threads/*")
+public class API extends HttpServlet {
+    ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
+    DaoFollower daoFollower = new DaoFollower();
+    DaoThread daoThread = new DaoThread();
+    DaoMessage daoMessage = new DaoMessage();
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        resp.setContentType("application/json;charset=UTF-8");
+        PrintWriter out = resp.getWriter();
+
+        String username = (String) req.getSession().getAttribute("username");
+        // vérification de l'authentification
+        if(username  == null){
+            resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            out.close();
+            return ;
+        }
+
+        String info = req.getPathInfo();
+
+        // Si aucune information n'est renseigné, on renvoie tous les threads du user
+        if (info == null || info.equals("/")) {
+            List<Thread> threads = daoFollower.findThreadsByUsername(username);
+            out.println(objectMapper.writeValueAsString(threads));
+            out.close();
+            return;
+        }
+
+        String[] splits = info.split("/");
+
+        // Vérifie la longueur de la requête
+        if(splits.length > 4){
+            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            out.close();
+            return;
+        }
+
+        int idThread;
+
+        // Récupère l'id et vérifie que c'est un entier
+        try {
+            idThread = Integer.parseInt(splits[1]);
+        } catch (NumberFormatException e){
+            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            out.close();
+            return;
+        }
+
+        Thread thread = daoThread.findById(idThread);
+        // Vérifie que le thread existe
+        if(thread == null) {
+            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+            out.close();
+            return;
+        }
+
+        // Vérifie que l'utilisateur à accès au thread
+        if(!daoFollower.userIsInThread(username, idThread)){
+            resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            out.close();
+            return;
+        }
+
+        // Lorsque la longueur de la requete est 2, renvoie les informations du thread
+        if(splits.length == 2) {
+            out.println(objectMapper.writeValueAsString(thread));
+            out.close();
+            return;
+        }
+
+        // Vérifie que le 3eme argument est "messages"
+        if(!splits[2].equals("messages")){
+            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            out.close();
+            return;
+        }
+
+        List<Message> messages = daoMessage.findByThreadId(idThread);
+        // Lorsque la longueur de la requete est 3, renvoie tous les messages du thread
+        if (splits.length == 3){
+            out.println(objectMapper.writeValueAsString(messages));
+            out.close();
+            return ;
+        }
+
+        int idMessage;
+        // Récupère l'id et vérifie que c'est un entier
+        try {
+            idMessage = Integer.parseInt(splits[3]);
+        } catch (NumberFormatException e){
+            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            out.close();
+            return;
+        }
+
+        Message message = daoMessage.findById(idMessage);
+        // Vérifie que le message existe
+        if(message == null) {
+            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+            out.close();
+            return;
+        }
+
+        // Vérifie que le message appartient au thread
+        if(message.getId_thread() != idThread){
+            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+            out.close();
+            return ;
+        }
+
+        out.println(objectMapper.writeValueAsString(message));
+        out.close();
+    }
+}
diff --git a/WEB-INF/src/modele/dao/DaoMessage.java b/WEB-INF/src/modele/dao/DaoMessage.java
index 51446f11d0dc918102dfd831dcb93040cc2b2806..a3079384badf66aee29e2277d7c37437704f5020 100644
--- a/WEB-INF/src/modele/dao/DaoMessage.java
+++ b/WEB-INF/src/modele/dao/DaoMessage.java
@@ -8,6 +8,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import modele.dto.Message;
+import modele.dto.Thread;
 import utils.DS;
 
 public class DaoMessage {
@@ -27,6 +28,21 @@ public class DaoMessage {
         return res;
     }
 
+    public Message findById(int idMessage) {
+        DS bdd = DS.getInstance();
+        try (Connection con = bdd.getConnection()) {
+            PreparedStatement ps = con.prepareStatement("SELECT * FROM messages WHERE id_message = ?");
+            ps.setInt(1, idMessage);
+            ResultSet rs = ps.executeQuery();
+            if (rs.next()) {
+                return new Message(rs.getInt("id_message"), rs.getString("sender"), rs.getInt("id_thread"), rs.getString("message"), rs.getTimestamp("time").toLocalDateTime());
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+        return null;
+    }
+
     public List<Message> findByThreadId(int idThread) {
         DS bdd = DS.getInstance();
         List<Message> res = new ArrayList<>();
diff --git a/WEB-INF/src/modele/dto/Message.java b/WEB-INF/src/modele/dto/Message.java
index 81491c4f7bb9bb9238455b5961ad9ca8e810a892..8464edc60b070e12dc8a2dde3fb2c3d419e64643 100644
--- a/WEB-INF/src/modele/dto/Message.java
+++ b/WEB-INF/src/modele/dto/Message.java
@@ -1,5 +1,7 @@
 package modele.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+
 import java.time.LocalDateTime;
 
 public class Message {
@@ -7,6 +9,8 @@ public class Message {
     String sender;
     int id_thread;
     String message;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy '-' HH':'mm:ss")
     LocalDateTime time;
     
     public Message(int id_message, String sender, int id_thread, String message, LocalDateTime time) {
diff --git a/WEB-INF/src/modele/dto/Thread.java b/WEB-INF/src/modele/dto/Thread.java
index 327e35222574ba0c5a496fb84447260edd5fa6ee..c68dca31f20c2717e18919cd2c9a3a4393344848 100644
--- a/WEB-INF/src/modele/dto/Thread.java
+++ b/WEB-INF/src/modele/dto/Thread.java
@@ -1,11 +1,14 @@
 package modele.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+
 import java.time.LocalDate;
 
 public class Thread {
     int id_thread;
     String creator;
     String name;
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
     LocalDate date;
     
     public Thread(int id_thread, String creator, String name, LocalDate date) {