diff --git a/patchwork/tests/api/test_notes.py b/patchwork/tests/api/test_notes.py
new file mode 100644
index 0000000..fc2d2e3
--- /dev/null
+++ b/patchwork/tests/api/test_notes.py
@@ -0,0 +1,232 @@
+# Patchwork - automated patch tracking system
+# Copyright (C) 2018 Red Hat
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from django.test import override_settings
+from django.urls import reverse
+from rest_framework import status
+
+from patchwork.models import Note
+from patchwork.tests.api import utils
+from patchwork.tests.utils import create_patch
+from patchwork.tests.utils import create_maintainer
+from patchwork.tests.utils import create_person
+from patchwork.tests.utils import create_project
+from patchwork.tests.utils import create_note
+from patchwork.tests.utils import create_user
+
+
+@override_settings(ENABLE_REST_API=True)
+class TestPatchNotes(utils.APITestCase):
+    def setUp(self):
+        super(TestPatchNotes, self).setUp()
+        self.project = create_project()
+        self.user = create_maintainer(self.project)
+        self.patch = create_patch(project=self.project)
+
+    def check_for_expected(self, instance, response_data):
+        self.assertEqual(instance.id, response_data['id'])
+        self.assertEqual(instance.patch.id, response_data['patch']['id'])
+        self.assertEqual(
+            instance.submitter.id, response_data['submitter']['id']
+        )
+
+    def test_create_note(self):
+        start_num = Note.objects.count()
+        url = reverse(
+            'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+        )
+        data = {'content': 'New note'}
+        self.client.authenticate(user=self.user)
+        resp = self.client.post(url, data=data)
+        end_num = Note.objects.count()
+
+        self.assertEqual(status.HTTP_201_CREATED, resp.status_code)
+        self.assertEqual(start_num + 1, end_num)
+
+    def test_get_note_as_maintainer(self):
+        """Retrieve patch note with an user that is a maintainer."""
+        person = create_person(user=self.user)
+        note = create_note(patch=self.patch, submitter=person)
+
+        self.client.authenticate(user=self.user)
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        resp = self.client.get(url)
+
+        self.assertEqual(status.HTTP_200_OK, resp.status_code)
+        self.check_for_expected(note, resp.data)
+
+    def test_get_note_as_non_maintainer(self):
+        """Retrieve patch note with an user that is not a maintainer."""
+        person = create_person()
+        note = create_note(patch=self.patch)
+
+        self.client.authenticate(user=person.user)
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        resp = self.client.get(url)
+
+        self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+    def test_get_note_public(self):
+        """Retrieve public patch note with an user that is not a maintainer."""
+        person = create_person(user=self.user)
+        note = create_note(patch=self.patch, maintainer_only=False)
+
+        self.client.authenticate(user=person.user)
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        resp = self.client.get(url)
+
+        self.assertEqual(status.HTTP_200_OK, resp.status_code)
+        self.check_for_expected(note, resp.data)
+
+    def test_get_note_list_as_maintainer(self):
+        """Retrieve notes from a patch note with an user that is a maintainer."""
+        person = create_person(user=self.user)
+        create_note(patch=self.patch, submitter=person)
+        create_note(patch=self.patch, submitter=person, maintainer_only=False)
+
+        self.client.authenticate(user=self.user)
+        url = reverse(
+            'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+        )
+        resp = self.client.get(url)
+
+        self.assertEqual(status.HTTP_200_OK, resp.status_code)
+        self.assertEqual(len(resp.data), 2)
+
+    def test_get_note_list_as_non_maintainer(self):
+        """Retrieve notes from a patch note with an user that is not a maintainer."""
+        person = create_person(user=self.user)
+        create_note(patch=self.patch, submitter=person)
+        public_note = create_note(
+            patch=self.patch, submitter=person, maintainer_only=False
+        )
+        not_maintainer = create_user()
+
+        self.client.authenticate(user=not_maintainer)
+        url = reverse(
+            'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+        )
+        resp = self.client.get(url)
+
+        self.assertEqual(status.HTTP_200_OK, resp.status_code)
+        self.assertEqual(len(resp.data), 1)
+        self.assertEqual(resp.data[0]['id'], public_note.id)
+
+    def test_edit_note_as_maintainer(self):
+        """Edit patch note with an user that is a maintainer."""
+        person = create_person(user=self.user)
+        note = create_note(patch=self.patch, submitter=person)
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        data = {'content': 'New content'}
+        self.client.authenticate(user=person.user)
+        resp = self.client.patch(url, data=data)
+
+        self.assertEqual(status.HTTP_200_OK, resp.status_code)
+        self.check_for_expected(note, resp.data)
+        self.assertNotEqual(note.content, resp.data['content'])
+        self.assertNotEqual(note.last_modified, resp.data['last_modified'])
+
+    def test_edit_note_as_non_maintainer(self):
+        """Edit patch note with an user that is not a maintainer."""
+        person = create_person()
+        note = create_note(patch=self.patch)
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        data = {'content': 'New content'}
+        self.client.authenticate(user=person.user)
+        resp = self.client.patch(url, data=data)
+
+        self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+    def test_edit_note_public(self):
+        """Edit public patch note with an user that is a maintainerwith an user that is not a maintainer."""
+        person = create_person()
+        note = create_note(patch=self.patch, maintainer_only=False)
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        data = {'content': 'New content'}
+        self.client.authenticate(user=person.user)
+        resp = self.client.patch(url, data=data)
+
+        self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+    def test_delete_note_as_maintainer(self):
+        """Delete patch note with an user that is a maintainer."""
+        person = create_person(user=self.user)
+        note = create_note(patch=self.patch, submitter=person)
+        start_num = Note.objects.count()
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+
+        self.client.authenticate(user=person.user)
+        resp = self.client.delete(url)
+        end_num = Note.objects.count()
+
+        self.assertEqual(status.HTTP_204_NO_CONTENT, resp.status_code)
+        self.assertEqual(start_num - 1, end_num)
+
+    def test_delete_note_as_non_maintainer(self):
+        """Delete patch note with an user that is not a maintainer."""
+        person = create_person()
+        note = create_note(patch=self.patch)
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+
+        self.client.authenticate(user=person.user)
+        resp = self.client.delete(url)
+
+        self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+    def test_delete_note_public(self):
+        """Delete public patch note with an user that is a maintainerwith an user that is not a maintainer."""
+        person = create_person()
+        note = create_note(patch=self.patch, maintainer_only=False)
+
+        url = reverse(
+            'api-patch-note-detail',
+            kwargs={'patch_id': self.patch.id, 'note_id': note.id},
+        )
+        self.client.authenticate(user=person.user)
+        resp = self.client.delete(url)
+
+        self.assertEqual(status.HTTP_403_FORBIDDEN, resp.status_code)
+
+    def test_notes_in_patch(self):
+        url = reverse('api-patch-detail', kwargs={'pk': self.patch.id})
+        self.client.authenticate(user=self.user)
+        resp = self.client.get(url)
+
+        correct_path = reverse(
+            'api-patch-note-list', kwargs={'patch_id': self.patch.id}
+        )
+        self.assertEqual(
+            resp.data.get('notes'),
+            f'http://example.com{correct_path}',
+        )
diff --git a/patchwork/tests/utils.py b/patchwork/tests/utils.py
index 4f40489..3fbb689 100644
--- a/patchwork/tests/utils.py
+++ b/patchwork/tests/utils.py
@@ -15,6 +15,7 @@ from patchwork.models import Bundle
 from patchwork.models import Check
 from patchwork.models import Cover
 from patchwork.models import CoverComment
+from patchwork.models import Note
 from patchwork.models import Patch
 from patchwork.models import PatchComment
 from patchwork.models import PatchRelation
@@ -270,6 +271,17 @@ def create_patch_comment(**kwargs):
     return PatchComment.objects.create(**values)
 
 
+def create_note(**kwargs):
+    """Create 'Note' object."""
+    values = {
+        'submitter': create_person() if 'submitter' not in kwargs else None,
+        'content': 'Note content',
+    }
+    values.update(kwargs)
+
+    return Note.objects.create(**values)
+
+
 def create_check(**kwargs):
     """Create 'Check' object."""
     values = {
