diff --git a/backend/.gitignore b/backend/.gitignore
index 0321231027fe3a867d47cd620a82adc7d1ce4832..86ca4a4842208f80247e2f5f30648fa73444dabe 100644
--- a/backend/.gitignore
+++ b/backend/.gitignore
@@ -7,6 +7,7 @@ __pycache__
 MANIFEST
 .coverage
 cache/
+.mypy_cache/
 
 # Django specific
 dist/
diff --git a/backend/core/migrations/0001_initial.py b/backend/core/migrations/0001_initial.py
index 7fd6cdada7a80ed66d0adb09f55bb01c58a93272..5f840961f0accd6d68d03bb079d421e7f0322bcd 100644
--- a/backend/core/migrations/0001_initial.py
+++ b/backend/core/migrations/0001_initial.py
@@ -2,6 +2,8 @@
 # Generated by Django 1.11.7 on 2017-11-04 19:10
 from __future__ import unicode_literals
 
+from typing import List, Text
+
 import django.db.models.deletion
 from django.conf import settings
 from django.db import migrations, models
@@ -13,8 +15,7 @@ class Migration(migrations.Migration):
 
     initial = True
 
-    dependencies = [
-    ]
+    dependencies: List[Text] = []
 
     operations = [
         migrations.CreateModel(
diff --git a/backend/core/models.py b/backend/core/models.py
index c76e76e29491540a64d478f53c7447393e507a3a..76b024601d0fb85b549519d734f700d63d1ad2b6 100644
--- a/backend/core/models.py
+++ b/backend/core/models.py
@@ -6,6 +6,8 @@ See docstring of the individual models for information on the setup of the
 database.
 '''
 
+from typing import Union, Dict
+
 from collections import OrderedDict
 from random import randrange, sample
 from string import ascii_lowercase
@@ -15,7 +17,7 @@ from django.contrib.auth.models import AbstractUser
 from django.db import models
 from django.db.models import Value as V
 from django.db.models import (BooleanField, Case, Count, F, IntegerField, Q,
-                              Sum, When)
+                              QuerySet, Sum, When)
 from django.db.models.functions import Coalesce
 
 
@@ -28,7 +30,7 @@ def random_matrikel_no() -> str:
     return str(10_000_000 + randrange(90_000_000))
 
 
-def get_annotated_tutor_list():
+def get_annotated_tutor_list() -> QuerySet:
     """All tutor accounts are annotate with a field that includes the number of
     feedback that tutor has collaborated in.
 
@@ -105,7 +107,7 @@ class SubmissionType(models.Model):
         verbose_name_plural = "SubmissionType Set"
 
     @classmethod
-    def get_annotated_feedback_count(cls):
+    def get_annotated_feedback_count(cls) -> QuerySet:
         """ Annotates submission lists with counts
 
         The following fields are annotated:
@@ -146,7 +148,7 @@ class UserAccount(AbstractUser):
     fullname = models.CharField('full name', max_length=70, blank=True)
     is_admin = models.BooleanField(default=False)
 
-    def get_associated_user(self):
+    def get_associated_user(self) -> models.Model:
         """ Returns the user type that is associated with this user obj """
         return \
             (hasattr(self, 'student') and self.student) or \
@@ -162,6 +164,7 @@ class Tutor(models.Model):
     def get_feedback_count(self) -> int:
         return self.feedback_list.count()
 
+
 class Reviewer(models.Model):
     user = models.OneToOneField(
         get_user_model(), unique=True,
@@ -197,7 +200,7 @@ class Student(models.Model):
         get_user_model(), unique=True,
         on_delete=models.CASCADE, related_name='student')
 
-    def score_per_submission(self):
+    def score_per_submission(self) -> Dict[str, int]:
         """ TODO: get rid of it and use an annotation.
 
         Returns:
@@ -214,7 +217,7 @@ class Student(models.Model):
         })
 
     @classmethod
-    def get_overall_score_annotated_submission_list(cls):
+    def get_overall_score_annotated_submission_list(cls) -> QuerySet:
         """Can be used to quickly annotate a user with the necessary information
         on the overall score of a student and if he does not need any more
         correction.
@@ -331,7 +334,7 @@ class Submission(models.Model):
         )
 
     @classmethod
-    def assign_tutor(cls, tutor, slug=None) -> bool:
+    def assign_tutor(cls, tutor: Tutor, slug: str=None) -> bool:
         """Assigns a tutor to a submission
 
         A submission is not assigned to the specified tutor in the case
@@ -493,14 +496,14 @@ class Feedback(models.Model):
     def __str__(self) -> str:
         return 'Feedback for {}'.format(self.of_submission)
 
-    def is_full_score(self):
+    def is_full_score(self) -> bool:
         return self.of_submission.type.full_score == self.score
 
-    def get_full_score(self):
+    def get_full_score(self) -> int:
         return self.of_submission.type.full_score
 
     @classmethod
-    def get_open_feedback(cls, user):
+    def get_open_feedback(cls, user: Union[Tutor, Reviewer]) -> QuerySet:
         """For a user, returns the feedback that is up for reassignment that
         does not belong to the user.
 
@@ -523,7 +526,7 @@ class Feedback(models.Model):
         )
 
     @classmethod
-    def tutor_unfinished_feedback(cls, user):
+    def tutor_unfinished_feedback(cls, user: Union[Tutor, Reviewer]):
         """Gets only the feedback that is assigned and not accepted. A tutor
         should have only one feedback assigned that is not accepted
 
@@ -541,7 +544,7 @@ class Feedback(models.Model):
         )
         return tutor_feedback[0] if tutor_feedback else None
 
-    def tutor_assigned_feedback(cls, user):
+    def tutor_assigned_feedback(cls, user: Union[Tutor, Reviewer]):
         """Gets all feedback that is assigned to the tutor including
         all status cases.
 
@@ -557,7 +560,7 @@ class Feedback(models.Model):
         tutor_feedback = cls.objects.filter(of_tutor=user)
         return tutor_feedback
 
-    def finalize_feedback(self, user):
+    def finalize_feedback(self, user: Union[Tutor, Reviewer]):
         """Used to mark feedback as accepted (reviewed).
 
         Parameters
@@ -569,17 +572,7 @@ class Feedback(models.Model):
         self.of_reviewer = user
         self.save()
 
-    def unfinalize_feedback(self):
-        """Used to mark feedback as accepted (reviewed)
-
-        This makes it uneditable by the tutor.
-        """
-
-        self.origin = Feedback.MANUAL
-        self.of_reviewer = None
-        self.save()
-
-    def reassign_to_tutor(self, user):
+    def reassign_to_tutor(self, user: Union[Tutor, Reviewer]):
         """When a tutor does not want to correct some task they can pass it
         along to another tutor who will accept the request.
 
diff --git a/backend/core/permissions.py b/backend/core/permissions.py
index 65c83d6b78777fb276eb9a9ae60a43e269b3f59b..29b60731037a3d58727b44826b189de4b8f6217e 100644
--- a/backend/core/permissions.py
+++ b/backend/core/permissions.py
@@ -1,13 +1,15 @@
 from rest_framework import permissions
 
 from core.models import Reviewer, Student, Tutor
+from django.http import HttpRequest
+from django.views import View
 
 
 class IsUserGenericPermission(permissions.BasePermission):
     """ Generic class that encapsulates how to identify someone
     as a member of a user Group """
 
-    def has_permission(self, request, view):
+    def has_permission(self, request: HttpRequest, view: View) -> bool:
         """ required by BasePermission. Check if user is instance of model"""
         assert self.model is not None, (
             "'%s' has to include a `model` attribute"
diff --git a/backend/core/serializers.py b/backend/core/serializers.py
index 60c095f5c89a0b592f3a67ec5d41b84e3b786faf..afccb1bb6212bc3edd35c18680e022f464fb028e 100644
--- a/backend/core/serializers.py
+++ b/backend/core/serializers.py
@@ -51,7 +51,7 @@ class TutorSerializer(serializers.ModelSerializer):
     feedback_count = serializers.IntegerField(source='get_feedback_count',
                                               read_only=True)
 
-    def create(self, validated_data):
+    def create(self, validated_data) -> Tutor:
         log.info("Crating tutor from data %s", validated_data)
         return user_factory.make_tutor(
             username=validated_data['user']['username'])
diff --git a/backend/core/views.py b/backend/core/views.py
index bffb8caf2f16d2e0c65ec5292b318155a9f98c66..4470a4ab59e360f0ef30fa6c37d1f850e4cf6aac 100644
--- a/backend/core/views.py
+++ b/backend/core/views.py
@@ -5,7 +5,7 @@ import logging
 
 from rest_framework import generics
 
-from core.models import ExamType, Tutor
+from core.models import ExamType, Tutor, Student
 from core.permissions import IsReviewer, IsStudent
 from core.serializers import ExamSerializer, StudentSerializer, TutorSerializer
 
@@ -17,7 +17,7 @@ class StudentApiView(generics.RetrieveAPIView):
     permission_classes = (IsStudent,)
     serializer_class = StudentSerializer
 
-    def get_object(self):
+    def get_object(self) -> Student:
         """ The object in question is the student associated with the requests
         user. Since the permission IsStudent is satisfied the member exists """
         return self.request.user.student