diff --git a/Pipfile b/Pipfile
index c3380be7ec881ca1b942f39363ad73d4f93a3a78..830c70e828ea94de913153e67d7e8b437d5688f8 100644
--- a/Pipfile
+++ b/Pipfile
@@ -10,6 +10,7 @@ pyrabbit = "*"
 flask = "*"
 flask-restful = "*"
 marshmallow = "*"
+bson = "*"
 
 [dev-packages]
 
diff --git a/Pipfile.lock b/Pipfile.lock
index 3cd34d20a17d9f6dc7710a03cfa563ac973834bb..6bfa164eac8b2c1023b1195ad342d66842e4f891 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "b71ec6300f7c04a8d222991089770e4384941bf5553cfa12031330227ad043cb"
+            "sha256": "6197445b839f98b90944ea771c7c0f63db31f0e455b325be3435fa2d17a89517"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -31,6 +31,13 @@
             ],
             "version": "==9.0.1"
         },
+        "bson": {
+            "hashes": [
+                "sha256:d6511b2ab051139a9123c184de1a04227262173ad593429d21e443d6462d6590"
+            ],
+            "index": "pypi",
+            "version": "==0.5.10"
+        },
         "click": {
             "hashes": [
                 "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
@@ -70,6 +77,14 @@
             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
             "version": "==0.21.0"
         },
+        "importlib-metadata": {
+            "hashes": [
+                "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab",
+                "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"
+            ],
+            "markers": "python_version < '3.10'",
+            "version": "==5.0.0"
+        },
         "itsdangerous": {
             "hashes": [
                 "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
@@ -142,11 +157,11 @@
         },
         "marshmallow": {
             "hashes": [
-                "sha256:35e02a3a06899c9119b785c12a22f4cda361745d66a71ab691fd7610202ae104",
-                "sha256:6804c16114f7fce1f5b4dadc31f4674af23317fcc7f075da21e35c1a35d781f7"
+                "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78",
+                "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"
             ],
             "index": "pypi",
-            "version": "==3.18.0"
+            "version": "==3.19.0"
         },
         "packaging": {
             "hashes": [
@@ -187,6 +202,14 @@
             "index": "pypi",
             "version": "==1.1.0"
         },
+        "python-dateutil": {
+            "hashes": [
+                "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
+                "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+            "version": "==2.8.2"
+        },
         "pytz": {
             "hashes": [
                 "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427",
@@ -217,6 +240,14 @@
             ],
             "markers": "python_version >= '3.7'",
             "version": "==2.2.2"
+        },
+        "zipp": {
+            "hashes": [
+                "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1",
+                "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"
+            ],
+            "markers": "python_version >= '3.7'",
+            "version": "==3.10.0"
         }
     },
     "develop": {}
diff --git a/api.py b/api.py
index 41e02f074cdc3fb9e7ae850a3c306c00770dc308..825c204f582d2371c6ac5487f587976f411bfea7 100644
--- a/api.py
+++ b/api.py
@@ -3,6 +3,8 @@ from flask_restful import Api
 from endpoints.hello import HelloWorld
 from endpoints.clients import Client, ClientList
 from endpoints.receive import Receive
+from endpoints.send import Send
+from endpoints.notify import Notify
 
 app = Flask(__name__)
 api = Api(app)
@@ -11,6 +13,8 @@ api.add_resource(HelloWorld, "/")
 api.add_resource(ClientList, "/client")
 api.add_resource(Client, "/client/<client_id>")
 api.add_resource(Receive, "/receive")
+api.add_resource(Send, "/send")
+api.add_resource(Notify, "/notify")
 
 if __name__ == "__main__":
     app.run(debug=True)
diff --git a/endpoints/notify.py b/endpoints/notify.py
index c5f420630ef357d4afa3c276bbc50bd06b8d3e3b..8c683859c6ee75bc112b7bb95d035a5450bee1d2 100644
--- a/endpoints/notify.py
+++ b/endpoints/notify.py
@@ -1,28 +1,39 @@
 from flask_restful import Resource, reqparse, abort, fields, marshal_with
+from marshmallow import Schema, field
 import json
 
+class NotifySchema(Schema):
+    client_id = fields.Str(required=True)
+    secret = fields.Str(required=True)
+    body = fields.Str(required=True)
 
 class Notify(Resource):
-    def setup_request_parser(self):
-        parser = reqparse.RequestParser()
-        parser.add_argument(
-            "client_id", type=str, help="A unique name to identify the client"
-        )
-        parser.add_argument(
-            "secret", type=str, help="A human friendly name to identify the client"
-        )
-        parser.add_argument("content", type=str, help="The message")
-        self.parser = parser
+    clients = None
+    schema = None
 
-    def parse(self):
-        return self.parser.parse_args()
+    def __init__(self):
+        self.schema = ReceiveSchema()
+        with open("clients.json", "r") as clients_file:
+            self.clients = json.load(clients_file)
 
-    def put(self, client_id):
-        args = clients_file.parse()
+    def post(self):
+        errors = self.schema.validate(request.args)
+        if errors:
+            abort(400, str(errors))
 
-        client = clients_file.find(client_id)
-        if not client:
-            abort(404, message="No client with id: {}".format(client_id))
-        else:
-            client = clients_file.update(args)
-        return client, 201
+        messages = []
+        allow = False
+        body = request.args.get("body")
+        client_id = request.args.get("client_id")
+        notify_queue = client_id + "-notify"
+        if client_id in self.clients:
+            client = self.clients.get(client_id)
+            if request.args.get("secret") == client.get("secret"):
+                allow = True
+
+        if allow:
+            connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
+            channel = connection.channel()
+            channel.queue_declare(queue=notify_queue, durable=True)
+            channel.basic_publish(exchange="", routing_key=notify_queue, body=body)
+            deliver_connection.close()
diff --git a/endpoints/receive.py b/endpoints/receive.py
index 75e027606c3817b22d8526722feeac08cb734daf..6567b0d1eb8cdca6a2faf7fcc605d43d1a3219ec 100644
--- a/endpoints/receive.py
+++ b/endpoints/receive.py
@@ -4,7 +4,7 @@ import pika
 import json
 
 
-class ReceiveSchema(Schema):
+class ReceiveQuerySchema(Schema):
     client_id = fields.Str(required=True)
     secret = fields.Str(required=True)
     max_messages = fields.Int(required=False)
@@ -15,7 +15,7 @@ class Receive(Resource):
     schema = None
 
     def __init__(self):
-        self.schema = ReceiveSchema()
+        self.schema = ReceiveQuerySchema()
         with open("clients.json", "r") as clients_file:
             self.clients = json.load(clients_file)
 
diff --git a/endpoints/send.py b/endpoints/send.py
index 70353c9f4fc8a193afb504907e83a1f4a45e2be5..31e38d96548d45fa8190846d6f2505233f80556d 100644
--- a/endpoints/send.py
+++ b/endpoints/send.py
@@ -1,29 +1,45 @@
 from flask_restful import Resource, reqparse, abort, fields, marshal_with
+from marshmallow import Schema, field
 import json
 
+class SendSchema(Schema):
+    client_id = fields.Str(required=True)
+    secret = fields.Str(required=True)
+    body = fields.Str(required=True)
+    topic = fields.Str(required=True)
 
 class Send(Resource):
-    def setup_request_parser(self):
-        parser = reqparse.RequestParser()
-        parser.add_argument(
-            "client_id", type=str, help="A unique name to identify the client"
-        )
-        parser.add_argument(
-            "secret", type=str, help="A human friendly name to identify the client"
-        )
-        parser.add_argument("topic", type=str, help="Publisher topic")
-        parser.add_argument("content", type=str, help="The message")
-        self.parser = parser
+    clients = None
+    schema = None
 
-    def parse(self):
-        return self.parser.parse_args()
+    def __init__(self):
+        self.schema = ReceiveSchema()
+        with open("clients.json", "r") as clients_file:
+            self.clients = json.load(clients_file)
 
-    def put(self, client_id):
-        args = clients_file.parse()
+    def post(self):
+        errors = self.schema.validate(request.args)
+        if errors:
+            abort(400, str(errors))
 
-        client = clients_file.find(client_id)
-        if not client:
-            abort(404, message="No client with id: {}".format(client_id))
-        else:
-            client = clients_file.update(args)
-        return client, 201
+        messages = []
+        allow = False
+        body = request.args.get("body")
+        topic = request.args.get("topic")
+        client_id = request.args.get("client_id")
+        outbox_queue = client_id + "-outbox"
+        if client_id in self.clients:
+            client = self.clients.get(client_id)
+            if request.args.get("secret") == client.get("secret"):
+                allow = True
+
+        if allow:
+            connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
+            channel = connection.channel()
+            channel.queue_declare(queue=notify_queue, durable=True)
+            message = {
+                'topic': topic,
+                'message': body,
+            }
+            channel.basic_publish(exchange="", routing_key=notify_queue, body=message)
+            deliver_connection.close()