diff --git a/cms/envs/common.py b/cms/envs/common.py
index 6aff9c2546f499460b8cb9880d5878317aa7f046..b3d6bf1687006ee73784842f4354f9bfcc160afb 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -36,7 +36,7 @@ import lms.envs.common
 # Although this module itself may not use these imported variables, other dependent modules may.
 from lms.envs.common import (
     USE_TZ, TECH_SUPPORT_EMAIL, PLATFORM_NAME, BUGS_EMAIL, DOC_STORE_CONFIG, DATA_DIR, ALL_LANGUAGES, WIKI_ENABLED,
-    update_module_store_settings, ASSET_IGNORE_REGEX, COPYRIGHT_YEAR,
+    update_module_store_settings, ASSET_IGNORE_REGEX, COPYRIGHT_YEAR, PARENTAL_CONSENT_AGE_LIMIT,
     # The following PROFILE_IMAGE_* settings are included as they are
     # indirectly accessed through the email opt-in API, which is
     # technically accessible through the CMS via legacy URLs.
diff --git a/cms/envs/test.py b/cms/envs/test.py
index ddc48208b451d32b0bd75657e515d95efa7777de..2d10aaad4947a46f1077152869b8285dcb97db64 100644
--- a/cms/envs/test.py
+++ b/cms/envs/test.py
@@ -249,6 +249,9 @@ FEATURES['USE_MICROSITES'] = True
 # the one in lms/envs/test.py
 FEATURES['ENABLE_DISCUSSION_SERVICE'] = False
 
+# Enable a parental consent age limit for testing
+PARENTAL_CONSENT_AGE_LIMIT = 13
+
 # Enable content libraries code for the tests
 FEATURES['ENABLE_CONTENT_LIBRARIES'] = True
 
diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py
index a42a06fee56af26963197bccb54db3fc9f05b166..ff8d294d6a3319e725697f10ab32a0f647be17ea 100644
--- a/common/djangoapps/student/models.py
+++ b/common/djangoapps/student/models.py
@@ -28,6 +28,7 @@ from django.contrib.auth.hashers import make_password
 from django.contrib.auth.signals import user_logged_in, user_logged_out
 from django.db import models, IntegrityError
 from django.db.models import Count
+from django.db.models.signals import pre_save
 from django.dispatch import receiver, Signal
 from django.core.exceptions import ObjectDoesNotExist
 from django.utils.translation import ugettext_noop
@@ -278,6 +279,50 @@ class UserProfile(models.Model):
         self.set_meta(meta)
         self.save()
 
+    def requires_parental_consent(self, date=None, age_limit=None, default_requires_consent=True):
+        """Returns true if this user requires parental consent.
+
+        Args:
+            date (Date): The date for which consent needs to be tested (defaults to now).
+            age_limit (int): The age limit at which parental consent is no longer required.
+                This defaults to the value of the setting 'PARENTAL_CONTROL_AGE_LIMIT'.
+            default_requires_consent (bool): True if users require parental consent if they
+                have no specified year of birth (default is True).
+
+        Returns:
+             True if the user requires parental consent.
+        """
+        if age_limit is None:
+            age_limit = getattr(settings, 'PARENTAL_CONSENT_AGE_LIMIT', None)
+            if age_limit is None:
+                return False
+
+        # Return True if either:
+        # a) The user has a year of birth specified and that year is fewer years in the past than the limit.
+        # b) The user has no year of birth specified and the default is to require consent.
+        #
+        # Note: we have to be conservative using the user's year of birth as their birth date could be
+        # December 31st. This means that if the number of years since their birth year is exactly equal
+        # to the age limit then we have to assume that they might still not be old enough.
+        year_of_birth = self.year_of_birth
+        if year_of_birth is None:
+            return default_requires_consent
+        if date is None:
+            date = datetime.now(UTC)
+        return date.year - year_of_birth <= age_limit    # pylint: disable=maybe-no-member
+
+
+@receiver(pre_save, sender=UserProfile)
+def user_profile_pre_save_callback(sender, **kwargs):
+    """
+    Ensure consistency of a user profile before saving it.
+    """
+    user_profile = kwargs['instance']
+
+    # Remove profile images for users who require parental consent
+    if user_profile.requires_parental_consent() and user_profile.has_profile_image:
+        user_profile.has_profile_image = False
+
 
 class UserSignupSource(models.Model):
     """
diff --git a/common/djangoapps/student/tests/test_enrollment.py b/common/djangoapps/student/tests/test_enrollment.py
index 6cf29170fce88a3902fbd8747ceb071ce736c88b..2334c99b9593ca032efa1de4e50b2dd4192fe538 100644
--- a/common/djangoapps/student/tests/test_enrollment.py
+++ b/common/djangoapps/student/tests/test_enrollment.py
@@ -194,7 +194,7 @@ class EnrollmentTest(UrlResetMixin, ModuleStoreTestCase):
         """Change the student's enrollment status in a course.
 
         Args:
-            action (string): The action to perform (either "enroll" or "unenroll")
+            action (str): The action to perform (either "enroll" or "unenroll")
 
         Keyword Args:
             course_id (unicode): If provided, use this course ID.  Otherwise, use the
diff --git a/common/djangoapps/student/tests/test_parental_controls.py b/common/djangoapps/student/tests/test_parental_controls.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a3623cf6c2e89c0eb7803e0ea6f917b4a0ac02e
--- /dev/null
+++ b/common/djangoapps/student/tests/test_parental_controls.py
@@ -0,0 +1,86 @@
+"""Unit tests for parental controls."""
+
+import datetime
+from django.test import TestCase
+from django.test.utils import override_settings
+
+from student.models import UserProfile
+from student.tests.factories import UserFactory
+
+
+class ProfileParentalControlsTest(TestCase):
+    """Unit tests for requires_parental_consent."""
+
+    password = "test"
+
+    def setUp(self):
+        super(ProfileParentalControlsTest, self).setUp()
+        self.user = UserFactory.create(password=self.password)
+        self.profile = UserProfile.objects.get(id=self.user.id)
+
+    def set_year_of_birth(self, year_of_birth):
+        """
+        Helper method that creates a mock profile for the specified user.
+        """
+        self.profile.year_of_birth = year_of_birth
+        self.profile.save()
+
+    def test_no_year_of_birth(self):
+        """Verify the behavior for users with no specified year of birth."""
+        self.assertTrue(self.profile.requires_parental_consent())
+        self.assertTrue(self.profile.requires_parental_consent(default_requires_consent=True))
+        self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=False))
+
+    @override_settings(PARENTAL_CONSENT_AGE_LIMIT=None)
+    def test_no_parental_controls(self):
+        """Verify the behavior for all users when parental controls are not enabled."""
+        self.assertFalse(self.profile.requires_parental_consent())
+        self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=True))
+        self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=False))
+
+        # Verify that even a child does not require parental consent
+        current_year = datetime.datetime.now().year
+        self.set_year_of_birth(current_year - 10)
+        self.assertFalse(self.profile.requires_parental_consent())
+
+    def test_adult_user(self):
+        """Verify the behavior for an adult."""
+        current_year = datetime.datetime.now().year
+        self.set_year_of_birth(current_year - 20)
+        self.assertFalse(self.profile.requires_parental_consent())
+        self.assertTrue(self.profile.requires_parental_consent(age_limit=21))
+
+    def test_child_user(self):
+        """Verify the behavior for a child."""
+        current_year = datetime.datetime.now().year
+
+        # Verify for a child born 13 years agp
+        self.set_year_of_birth(current_year - 13)
+        self.assertTrue(self.profile.requires_parental_consent())
+        self.assertTrue(self.profile.requires_parental_consent(date=datetime.date(current_year, 12, 31)))
+        self.assertFalse(self.profile.requires_parental_consent(date=datetime.date(current_year + 1, 1, 1)))
+
+        # Verify for a child born 14 years ago
+        self.set_year_of_birth(current_year - 14)
+        self.assertFalse(self.profile.requires_parental_consent())
+        self.assertFalse(self.profile.requires_parental_consent(date=datetime.date(current_year, 1, 1)))
+
+    def test_profile_image(self):
+        """Verify that a profile's image obeys parental controls."""
+
+        # Verify that an image cannot be set for a user with no year of birth set
+        self.profile.has_profile_image = True
+        self.profile.save()
+        self.assertFalse(self.profile.has_profile_image)
+
+        # Verify that an image can be set for an adult user
+        current_year = datetime.datetime.now().year
+        self.set_year_of_birth(current_year - 20)
+        self.profile.has_profile_image = True
+        self.profile.save()
+        self.assertTrue(self.profile.has_profile_image)
+
+        # verify that a user's profile image is removed when they switch to requiring parental controls
+        self.set_year_of_birth(current_year - 10)
+        self.profile.save()
+        self.assertFalse(self.profile.has_profile_image)
diff --git a/lms/envs/common.py b/lms/envs/common.py
index d399640d35444ebbb21f23061a32f0398ebf50d6..dbcbceb85e1c7ef23a7a81229bda920b45f66cf8 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -987,6 +987,12 @@ EDXNOTES_INTERFACE = {
     'url': 'http://localhost:8120/api/v1',
 }
 
+########################## Parental controls config  #######################
+
+# The age at which a learner no longer requires parental consent, or None
+# if parental consent is never required.
+PARENTAL_CONSENT_AGE_LIMIT = 13
+
 ################################# Jasmine ##################################
 JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
 
@@ -1544,7 +1550,7 @@ BULK_EMAIL_RETRY_DELAY_BETWEEN_SENDS = 0.02
 ############################# Email Opt In ####################################
 
 # Minimum age for organization-wide email opt in
-EMAIL_OPTIN_MINIMUM_AGE = 13
+EMAIL_OPTIN_MINIMUM_AGE = PARENTAL_CONSENT_AGE_LIMIT
 
 ############################## Video ##########################################
 
diff --git a/lms/envs/test.py b/lms/envs/test.py
index 7658867fef29635bf0bb98627e6e88827f829256..58e1e7fef41043fd217968d731334d05ce7780b9 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -74,6 +74,9 @@ FEATURES['ENABLE_COMBINED_LOGIN_REGISTRATION'] = True
 # Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
 WIKI_ENABLED = True
 
+# Enable a parental consent age limit for testing
+PARENTAL_CONSENT_AGE_LIMIT = 13
+
 # Makes the tests run much faster...
 SOUTH_TESTS_MIGRATE = False  # To disable migrations and use syncdb instead
 
diff --git a/openedx/core/djangoapps/user_api/accounts/api.py b/openedx/core/djangoapps/user_api/accounts/api.py
index 7913aecd18e018457beb6c9cf589ab4e41684f52..009b5424898fb31339fc2a37e196c2b8be845549 100644
--- a/openedx/core/djangoapps/user_api/accounts/api.py
+++ b/openedx/core/djangoapps/user_api/accounts/api.py
@@ -104,7 +104,7 @@ def update_account_settings(requesting_user, update, username=None):
         requesting_user (User): The user requesting to modify account information. Only the user with username
             'username' has permissions to modify account information.
         update (dict): The updated account field values.
-        username (string): Optional username specifying which account should be updated. If not specified,
+        username (str): Optional username specifying which account should be updated. If not specified,
             `requesting_user.username` is assumed.
 
     Raises:
@@ -372,9 +372,9 @@ def request_password_change(email, orig_host, is_secure):
     Users must confirm the password change before we update their information.
 
     Args:
-        email (string): An email address
-        orig_host (string): An originating host, extracted from a request with get_host
-        is_secure (Boolean): Whether the request was made with HTTPS
+        email (str): An email address
+        orig_host (str): An originating host, extracted from a request with get_host
+        is_secure (bool): Whether the request was made with HTTPS
 
     Returns:
         None
diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_helpers.py b/openedx/core/djangoapps/user_api/accounts/tests/test_helpers.py
index af8e2150e98eb200341ca3d89c7faa974024b22a..92abeaff01ed717d0d9239307afc6d3e678ee749 100644
--- a/openedx/core/djangoapps/user_api/accounts/tests/test_helpers.py
+++ b/openedx/core/djangoapps/user_api/accounts/tests/test_helpers.py
@@ -9,9 +9,11 @@ from unittest import skipUnless
 from django.conf import settings
 from django.test import TestCase
 
-from openedx.core.djangoapps.user_api.accounts.helpers import get_profile_image_url_for_user
 from student.tests.factories import UserFactory
 
+from ...models import UserProfile
+from ..helpers import get_profile_image_url_for_user
+
 
 @ddt
 @patch('openedx.core.djangoapps.user_api.accounts.helpers._PROFILE_IMAGE_SIZES', [50, 10])
@@ -27,6 +29,10 @@ class ProfileImageUrlTestCase(TestCase):
         super(ProfileImageUrlTestCase, self).setUp()
         self.user = UserFactory()
 
+        # Ensure that parental controls don't apply to this user
+        self.user.profile.year_of_birth = 1980
+        self.user.profile.save()
+
     def verify_url(self, user, pixels, filename):
         """
         Helper method to verify that we're correctly generating profile
diff --git a/openedx/core/djangoapps/user_api/helpers.py b/openedx/core/djangoapps/user_api/helpers.py
index b939a41b770470f270f3b7de7c368f868d2e2cf5..8fc9b6c69b466075919d8870c026d57c36e34546 100644
--- a/openedx/core/djangoapps/user_api/helpers.py
+++ b/openedx/core/djangoapps/user_api/helpers.py
@@ -308,7 +308,7 @@ class FormDescription(object):
         Field properties not in `OVERRIDE_FIELD_PROPERTIES` will be ignored.
 
         Arguments:
-            field_name (string): The name of the field to override.
+            field_name (str): The name of the field to override.
 
         Keyword Args:
             Same as to `add_field()`.
diff --git a/openedx/core/djangoapps/user_api/models.py b/openedx/core/djangoapps/user_api/models.py
index f8f94648c0f9155baa88f2dcad6dde70915f55ac..e3642fa2e6825dc9da23d601e621c2a62b5c351d 100644
--- a/openedx/core/djangoapps/user_api/models.py
+++ b/openedx/core/djangoapps/user_api/models.py
@@ -35,7 +35,7 @@ class UserPreference(models.Model):
 
         Arguments:
             user (User): The user whose preference should be set.
-            preference_key (string): The key for the user preference.
+            preference_key (str): The key for the user preference.
 
         Returns:
             The user preference value, or None if one is not set.
diff --git a/openedx/core/djangoapps/user_api/preferences/api.py b/openedx/core/djangoapps/user_api/preferences/api.py
index 447282a4bd05276b15651ed1a7ee39cfad24a45d..2c40f8515e7b9efba9694f0bc51a73e92ba81187 100644
--- a/openedx/core/djangoapps/user_api/preferences/api.py
+++ b/openedx/core/djangoapps/user_api/preferences/api.py
@@ -1,22 +1,17 @@
 """
 API for managing user preferences.
 """
-import datetime
 import logging
-import string
 import analytics
 from eventtracking import tracker
-from pytz import UTC
 
 from django.conf import settings
-from django.contrib.auth.models import User
 from django.core.exceptions import ObjectDoesNotExist
 from django.db import IntegrityError
 from django.utils.translation import ugettext as _
+from student.models import User, UserProfile
 from django.utils.translation import ugettext_noop
 
-from student.models import UserProfile
-
 from ..errors import (
     UserAPIInternalError, UserAPIRequestError, UserNotFound, UserNotAuthorized,
     PreferenceValidationError, PreferenceUpdateError
@@ -35,7 +30,7 @@ def get_user_preference(requesting_user, preference_key, username=None):
     Args:
         requesting_user (User): The user requesting the user preferences. Only the user with username
             `username` or users with "is_staff" privileges can access the preferences.
-        preference_key (string): The key for the user preference.
+        preference_key (str): The key for the user preference.
         username (str): Optional username for which to look up the preferences. If not specified,
             `requesting_user.username` is assumed.
 
@@ -92,7 +87,7 @@ def update_user_preferences(requesting_user, update, username=None):
             Some notes:
                 Values are expected to be strings. Non-string values will be converted to strings.
                 Null values for a preference will be treated as a request to delete the key in question.
-        username (string): Optional username specifying which account should be updated. If not specified,
+        username (str): Optional username specifying which account should be updated. If not specified,
             `requesting_user.username` is assumed.
 
     Raises:
@@ -148,9 +143,9 @@ def set_user_preference(requesting_user, preference_key, preference_value, usern
     Arguments:
         requesting_user (User): The user requesting to modify account information. Only the user with username
             'username' has permissions to modify account information.
-        preference_key (string): The key for the user preference.
-        preference_value (string): The value to be stored. Non-string values will be converted to strings.
-        username (string): Optional username specifying which account should be updated. If not specified,
+        preference_key (str): The key for the user preference.
+        preference_value (str): The value to be stored. Non-string values will be converted to strings.
+        username (str): Optional username specifying which account should be updated. If not specified,
             `requesting_user.username` is assumed.
 
     Raises:
@@ -182,8 +177,8 @@ def delete_user_preference(requesting_user, preference_key, username=None):
     Arguments:
         requesting_user (User): The user requesting to delete the preference. Only the user with username
             'username' has permissions to delete their own preference.
-        preference_key (string): The key for the user preference.
-        username (string): Optional username specifying which account should be updated. If not specified,
+        preference_key (str): The key for the user preference.
+        username (str): Optional username specifying which account should be updated. If not specified,
             `requesting_user.username` is assumed.
 
     Returns:
@@ -218,7 +213,7 @@ def delete_user_preference(requesting_user, preference_key, username=None):
 
 
 @intercept_errors(UserAPIInternalError, ignore_errors=[UserAPIRequestError])
-def update_email_opt_in(user, org, optin):
+def update_email_opt_in(user, org, opt_in):
     """Updates a user's preference for receiving org-wide emails.
 
     Sets a User Org Tag defining the choice to opt in or opt out of organization-wide
@@ -227,48 +222,48 @@ def update_email_opt_in(user, org, optin):
     Arguments:
         user (User): The user to set a preference for.
         org (str): The org is used to determine the organization this setting is related to.
-        optin (Boolean): True if the user is choosing to receive emails for this organization. If the user is not
-            the correct age to receive emails, email-optin is set to False regardless.
+        opt_in (bool): True if the user is choosing to receive emails for this organization.
+            If the user requires parental consent then email-optin is set to False regardless.
 
     Returns:
         None
 
+    Raises:
+         UserNotFound: no user profile exists for the specified user.
     """
-    # Avoid calling get_account_settings because it introduces circularity for many callers who need both
-    # preferences and account information.
+    preference, _ = UserOrgTag.objects.get_or_create(
+        user=user, org=org, key='email-optin'
+    )
+
+    # If the user requires parental consent, then don't allow opt-in
     try:
         user_profile = UserProfile.objects.get(user=user)
     except ObjectDoesNotExist:
         raise UserNotFound()
-
-    year_of_birth = user_profile.year_of_birth
-    of_age = (
-        year_of_birth is None or  # If year of birth is not set, we assume user is of age.
-        datetime.datetime.now(UTC).year - year_of_birth >  # pylint: disable=maybe-no-member
-        getattr(settings, 'EMAIL_OPTIN_MINIMUM_AGE', 13)
-    )
-
+    if user_profile.requires_parental_consent(
+        age_limit=getattr(settings, 'EMAIL_OPTIN_MINIMUM_AGE', 13),
+        default_requires_consent=False,
+    ):
+        opt_in = False
+
+    # Update the preference and save it
+    preference.value = str(opt_in)
     try:
-        preference, _ = UserOrgTag.objects.get_or_create(
-            user=user, org=org, key='email-optin'
-        )
-        preference.value = str(optin and of_age)
         preference.save()
-
         if settings.FEATURES.get('SEGMENT_IO_LMS') and settings.SEGMENT_IO_LMS_KEY:
-            _track_update_email_opt_in(user.id, org, optin)
-
+            _track_update_email_opt_in(user.id, org, opt_in)
     except IntegrityError as err:
         log.warn(u"Could not update organization wide preference due to IntegrityError: {}".format(err.message))
 
 
+
 def _track_update_email_opt_in(user_id, organization, opt_in):
     """Track an email opt-in preference change.
 
     Arguments:
         user_id (str): The ID of the user making the preference change.
         organization (str): The organization whose emails are being opted into or out of by the user.
-        opt_in (Boolean): Whether the user has chosen to opt-in to emails from the organization.
+        opt_in (bool): Whether the user has chosen to opt-in to emails from the organization.
 
     Returns:
         None
@@ -317,8 +312,8 @@ def create_user_preference_serializer(user, preference_key, preference_value):
 
     Arguments:
         user (User): The user whose preference is being serialized.
-        preference_key (string): The key for the user preference.
-        preference_value (string): The value to be stored. Non-string values will be converted to strings.
+        preference_key (str): The key for the user preference.
+        preference_value (str): The value to be stored. Non-string values will be converted to strings.
 
     Returns:
         A serializer that can be used to save the user preference.
@@ -344,8 +339,8 @@ def validate_user_preference_serializer(serializer, preference_key, preference_v
 
     Arguments:
         serializer (UserPreferenceSerializer): The serializer to be validated.
-        preference_key (string): The key for the user preference.
-        preference_value (string): The value to be stored. Non-string values will be converted to strings.
+        preference_key (str): The key for the user preference.
+        preference_value (str): The value to be stored. Non-string values will be converted to strings.
 
     Raises:
         PreferenceValidationError: the supplied key and/or value for a user preference are invalid.
diff --git a/openedx/core/djangoapps/user_api/preferences/tests/test_api.py b/openedx/core/djangoapps/user_api/preferences/tests/test_api.py
index 13d05c64926c231ac492fff08df5361733c90502..3791bc33c421154a2c1d817f691a8f3194c1c6c4 100644
--- a/openedx/core/djangoapps/user_api/preferences/tests/test_api.py
+++ b/openedx/core/djangoapps/user_api/preferences/tests/test_api.py
@@ -344,6 +344,13 @@ class UpdateEmailOptInTests(ModuleStoreTestCase):
         result_obj = UserOrgTag.objects.get(user=user, org=course.id.org, key='email-optin')
         self.assertEqual(result_obj.value, u"True")
 
+    def test_update_email_optin_anonymous_user(self):
+        """Verify that the API raises an exception for a user with no profile."""
+        course = CourseFactory.create()
+        no_profile_user, __ = User.objects.get_or_create(username="no_profile_user", password=self.PASSWORD)
+        with self.assertRaises(UserNotFound):
+            update_email_opt_in(no_profile_user, course.id.org, True)
+
     @ddt.data(
         # Check that a 27 year old can opt-in, then out.
         (27, True, False, u"False"),
diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py
index 89e52fe34e80b7dbfb6ce6fbe1574c2d82adadda..d1844b119fdc9b8219700594a8467d7d8077d146 100644
--- a/openedx/core/djangoapps/user_api/views.py
+++ b/openedx/core/djangoapps/user_api/views.py
@@ -309,7 +309,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -339,7 +339,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -372,7 +372,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -409,7 +409,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -434,7 +434,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a dropdown menu on the registration
@@ -457,7 +457,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a dropdown menu on the registration
@@ -480,7 +480,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a dropdown menu on the registration
@@ -504,7 +504,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -525,7 +525,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This phrase appears above a field on the registration form
@@ -548,7 +548,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a field on the registration form
@@ -568,7 +568,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This label appears above a dropdown menu on the registration
@@ -604,7 +604,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Separate terms of service and honor code checkboxes
@@ -658,7 +658,7 @@ class RegistrationView(APIView):
             form_desc: A form description
 
         Keyword Arguments:
-            required (Boolean): Whether this field is required; defaults to True
+            required (bool): Whether this field is required; defaults to True
 
         """
         # Translators: This is a legal document users must agree to