diff --git a/docs/tutorial.rst b/docs/how-to-guide.rst
similarity index 100%
rename from docs/tutorial.rst
rename to docs/how-to-guide.rst
diff --git a/docs/index.rst b/docs/index.rst
index 626a0b774f67c40c03a2b120a637dbdf8c57344a..102cf4c7a04b1fb519bf612db1361af5054a9390 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -7,7 +7,8 @@ Welcome to CoolAMQP's documentation!
 
     whatsnew
     cluster
-    tutorial
+    tutorials/send_and_receive
+    how-to-guide
     caveats
     frames
     basics
diff --git a/docs/tutorials/send_and_receive.rst b/docs/tutorials/send_and_receive.rst
new file mode 100644
index 0000000000000000000000000000000000000000..f8d2fe73559aa8a6e86ec0ba612a901a41b1985c
--- /dev/null
+++ b/docs/tutorials/send_and_receive.rst
@@ -0,0 +1,59 @@
+Send and receive
+================
+
+In this tutorial we'll learn how to declare a named queue and send a message to it with acknowledgement:
+
+First we need to connect to the server. Let's assume you have configured a virtual host called /vhost
+
+.. code-block:: python
+
+    from coolamqp.cluster import Cluster
+    from coolamqp.objects import NodeDefinition
+
+    nd = NodeDefinition('amqp://127.0.0.1:5672/vhost', user='test', password='test', heartbeat=30)
+    c = Cluster(nd)
+    c.start()
+
+Then we'll need to declare a queue:
+
+
+.. code-block:: python
+    from coolamqp.objects import Queue
+
+    queue = Queue('my-named-queue')
+    c.declare(queue).result()
+
+You'll be calling :code:`result()` on most of CoolAMQP's calls, as they return futures that complete when the task is done.
+Now let's try subscribing to this queue:
+
+.. code-block:: python
+
+    def handle_message(msg):
+        print(msg.body.tobytes().encode('utf-8'))
+        msg.ack()
+
+    cons, fut = c.consume(queue, no_ack=False, on_message=handle_message)
+    fut.result()
+
+Notice the :code:`tobytes()`. This is because CoolAMQP by default returns most of it's received bytes as memoryviews,
+for speed's sake.
+
+Also, your message handler is executed within the CoolAMQP's connection thread, so don't block for too long.
+
+Now it's time to send a message:
+
+.. code-block:: python
+
+    from coolamqp.objects import Message
+    c.publish(Message(b'my bag of bytes'), confirm=True).result()
+
+Without the confirm flag, publish would not return the future.
+
+Congratulations, you've just send and received a message! Now it's time to do some cleanup. First, we cancel the consumer,
+and then disconnect from the server
+
+.. code-block:: python
+
+    cons.cancel().result()
+    c.shutdown()
+