diff --git a/NEWS.rst b/NEWS.rst
index 4b0be37db05267313cd46a7273894cea1a5c12e3_TkVXUy5yc3Q=..e5335ca39b434593d9edac27183266de97d62bfd_TkVXUy5yc3Q= 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -6,6 +6,8 @@
 
 Heavy refactor of the module to use common message and envelope models.
 
+Added new request mode.
+
 16.0.1.0.2
 ----------
 
diff --git a/README.rst b/README.rst
index 4b0be37db05267313cd46a7273894cea1a5c12e3_UkVBRE1FLnJzdA==..e5335ca39b434593d9edac27183266de97d62bfd_UkVBRE1FLnJzdA== 100644
--- a/README.rst
+++ b/README.rst
@@ -30,6 +30,12 @@
 actually emit the data (all this module does is store it in a table and
 send a signal to that external component).
 
+The module also allows sending requests.
+To handle responses, the method queue_response_handling from the model
+`xbus.emitter.job` must be implemented.
+Note that the requests are received in a different transaction than the one they are
+sent in.
+
 Setup
 -----
 
diff --git a/models/xbus_emitter.py b/models/xbus_emitter.py
index 4b0be37db05267313cd46a7273894cea1a5c12e3_bW9kZWxzL3hidXNfZW1pdHRlci5weQ==..e5335ca39b434593d9edac27183266de97d62bfd_bW9kZWxzL3hidXNfZW1pdHRlci5weQ== 100644
--- a/models/xbus_emitter.py
+++ b/models/xbus_emitter.py
@@ -38,8 +38,8 @@
     )
 
     @returns("xbus.emitter.job")
-    def emit_envelopes(self, envelopes: models.Model):
+    def emit_envelopes(self, envelopes: models.Model, request: bool = False):
         """Emit the envelopes with the provided emitter. It can only be done with a
          single emitter.
 
         :param envelopes: Envelopes to send.
@@ -42,7 +42,8 @@
         """Emit the envelopes with the provided emitter. It can only be done with a
          single emitter.
 
         :param envelopes: Envelopes to send.
+        :param request: True if the emission is a request.
 
         :return: The new jobs. Odoo "xbus.emitter.job" record set.
         :rtype: models.Model
@@ -54,6 +55,7 @@
             {
                 "emitter_id": self.id,
                 "envelope_id": envelope.id,
+                "is_request": request,
             }
             for envelope in envelopes
         ]
@@ -70,9 +72,13 @@
 
         return emitter_jobs
 
+    # It is best to create envelope and their messages with create rather than using
+    # this method. If new fields are added, this method will probably be unable to
+    # handle them without changes.
+    # Code will also avoid the potential issues in this method, making it more robust.
     @returns("xbus.emitter.job")
     def emit(
         self,
         messages_content: list[
             tuple[str, bytes | None, bytes, Collection[models.Model] | None]
         ],
@@ -73,9 +79,11 @@
     @returns("xbus.emitter.job")
     def emit(
         self,
         messages_content: list[
             tuple[str, bytes | None, bytes, Collection[models.Model] | None]
         ],
+        request: bool = False,
+        comment: str = "emit",
     ):
         """Create an envelope and messages for each emitter and send them.
 
@@ -84,6 +92,8 @@
         message type. The second one is the optional header. The third one is the body.
         The fourth one is an optional record set, to indicate a link between the message
         and those record sets.
+        :param request: True if the emission is a request.
+        :param comment: comment for the envelope
 
         :return: The new jobs. Odoo "xbus.emitter.job" record set.
         :rtype: models.Model
@@ -102,9 +112,10 @@
         # Create one envelope by emitter
         envelopes = list(
             self.env["xbus.envelope"].create(
-                [{"comment": "emit", "message_ids": messages_values.copy()}] * len(self)
+                [{"comment": comment, "message_ids": messages_values.copy()}]
+                * len(self)
             )
         )
         # Then send them
         jobs = self.env["xbus.emitter.job"]
         for emitter in self:
@@ -106,9 +117,9 @@
             )
         )
         # Then send them
         jobs = self.env["xbus.emitter.job"]
         for emitter in self:
-            jobs |= emitter.emit_envelopes(envelopes.pop())
+            jobs |= emitter.emit_envelopes(envelopes.pop(), request)
         return jobs
 
     def _send_notifications(self):
diff --git a/models/xbus_emitter_job.py b/models/xbus_emitter_job.py
index 4b0be37db05267313cd46a7273894cea1a5c12e3_bW9kZWxzL3hidXNfZW1pdHRlcl9qb2IucHk=..e5335ca39b434593d9edac27183266de97d62bfd_bW9kZWxzL3hidXNfZW1pdHRlcl9qb2IucHk= 100644
--- a/models/xbus_emitter_job.py
+++ b/models/xbus_emitter_job.py
@@ -94,9 +94,23 @@
     date_sent = fields.Datetime(string="Envelope Sending Date", readonly=True)
     date_done = fields.Datetime(string="Process Termination Date", readonly=True)
 
+    is_request = fields.Boolean(string="Request")
+
+    response_envelope_id = fields.Many2one(
+        string="Response Envelope",
+        comodel_name="xbus.envelope",
+        index=True,
+        ondelete="cascade",
+        readonly=True,
+    )
+
+    # This field is not to be updated by Odoo, it should be False then xbus-odoo updates
+    # it. It is required so that the field is set as not null in the database.
+    response_acked = fields.Boolean(readonly=True, default=False, required=True)
+
     _sql_constraints = (
         (
             "envelope_uniq_per_emitter",
             "unique(emitter_id, envelope_id)",
             "An envelope can only be emitted by a single emitter",
         ),
@@ -97,8 +111,13 @@
     _sql_constraints = (
         (
             "envelope_uniq_per_emitter",
             "unique(emitter_id, envelope_id)",
             "An envelope can only be emitted by a single emitter",
         ),
+        (
+            "response_only_for_requests",
+            "check((not is_request and response_envelope_id is null) or is_request)",
+            "A response can only be given to a request",
+        ),
     )
 
@@ -103,5 +122,20 @@
     )
 
+    def notify_response(self):
+        """Called to indicate a response was received"""
+        self.invalidate_recordset(["response_envelope_id"])
+        self.filtered(lambda job: job.is_request).queue_response_handling()
+        return True
+
+    def queue_response_handling(self):
+        """When handling response, this method must be implemented."""
+        # This method should finish quickly and delegate the actual work for later.
+        # One way to do that is to use the queue_job module from OCA:
+        # https://github.com/OCA/queue
+        # Another is to define a new model, store the data in it and use a cron job to
+        # handle the responses.
+        raise NotImplementedError  # pragma: no cover
+
     @api.model
     @api.autovacuum
     def _gc_jobs(self):
diff --git a/tests/test_xbus_emitter_job.py b/tests/test_xbus_emitter_job.py
index 4b0be37db05267313cd46a7273894cea1a5c12e3_dGVzdHMvdGVzdF94YnVzX2VtaXR0ZXJfam9iLnB5..e5335ca39b434593d9edac27183266de97d62bfd_dGVzdHMvdGVzdF94YnVzX2VtaXR0ZXJfam9iLnB5 100644
--- a/tests/test_xbus_emitter_job.py
+++ b/tests/test_xbus_emitter_job.py
@@ -18,4 +18,5 @@
 #
 ##############################################################################
 
+import uuid
 from datetime import datetime, timedelta
@@ -21,6 +22,7 @@
 from datetime import datetime, timedelta
+from unittest import mock
 
 from odoo import Command
 
 from odoo.addons.xbus_common.tests.modelcase import ModelCase
 
@@ -22,8 +24,10 @@
 
 from odoo import Command
 
 from odoo.addons.xbus_common.tests.modelcase import ModelCase
 
+from ..models.xbus_emitter_job import XbusEmitterJob
+
 
 def past_dt(time_delta):
     return (datetime.now() - time_delta).replace(microsecond=0)
@@ -123,3 +127,37 @@
         klass._gc_jobs()  # pylint: disable=protected-access
 
         self.assertEqual(3, len(klass.search([])))
+
+    def test_notify_response(self):
+        jobs = self.env.ref("xbus_emitter.xbus_emitter_demo_1").emit_envelopes(
+            self.envelopes[0], True
+        )
+
+        # simulate external writing (xbus-odoo) of the response
+        uid = str(uuid.uuid4())
+        self.cr.execute(
+            "INSERT INTO xbus_envelope (comment, uid) VALUES ('response', %s) "
+            "RETURNING id",
+            (uid,),
+        )
+        envelope_id = self.cr.fetchall()[0][0]
+        uid = str(uuid.uuid4())
+        self.cr.execute(
+            "INSERT INTO xbus_message (envelope_id, uid, type, header, body) VALUES "
+            "(%s, %s, %s, %s, %s) RETURNING id",
+            (envelope_id, uid, "test_1", None, b"{'body': 'value'}"),
+        )
+        self.cr.execute(
+            "UPDATE xbus_emitter_job SET response_envelope_id=%s WHERE id IN %s",
+            (envelope_id, tuple(jobs.ids)),
+        )
+
+        # notify_response would be called by xbus-odoo
+        with mock.patch.object(
+            XbusEmitterJob,
+            "queue_response_handling",
+            autospec=True,
+        ):
+            rpc_reply = jobs.notify_response()
+            self.assertTrue(rpc_reply)
+            XbusEmitterJob.queue_response_handling.assert_called_once()