diff --git a/lms/djangoapps/course_home_api/__init__.py b/lms/djangoapps/course_home_api/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lms/djangoapps/course_home_api/dates/v1/__init__.py b/lms/djangoapps/course_home_api/dates/v1/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lms/djangoapps/course_home_api/dates/v1/serializers.py b/lms/djangoapps/course_home_api/dates/v1/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..d142ca0982de5c583cd438ade7ef9f0c48829939
--- /dev/null
+++ b/lms/djangoapps/course_home_api/dates/v1/serializers.py
@@ -0,0 +1,43 @@
+"""
+Dates Tab Serializers. Represents the relevant dates for a Course.
+"""
+
+
+from rest_framework import serializers
+
+from lms.djangoapps.courseware.date_summary import VerificationDeadlineDate
+
+
+class DateSummarySerializer(serializers.Serializer):
+    """
+    Serializer for Date Summary Objects.
+    """
+    date = serializers.DateTimeField()
+    date_type = serializers.CharField()
+    description = serializers.CharField()
+    learner_has_access = serializers.SerializerMethodField()
+    link = serializers.SerializerMethodField()
+    title = serializers.CharField()
+
+    def get_learner_has_access(self, block):
+        learner_is_verified = self.context.get('learner_is_verified', False)
+        block_is_verified = (getattr(block, 'contains_gated_content', False) or
+                             isinstance(block, VerificationDeadlineDate))
+        return (not block_is_verified) or learner_is_verified
+
+    def get_link(self, block):
+        if block.link:
+            request = self.context.get('request')
+            return request.build_absolute_uri(block.link)
+        return ''
+
+
+class DatesTabSerializer(serializers.Serializer):
+    """
+    Serializer for the Dates Tab
+    """
+    course_date_blocks = DateSummarySerializer(many=True)
+    display_reset_dates_text = serializers.BooleanField()
+    learner_is_verified = serializers.BooleanField()
+    user_timezone = serializers.CharField()
+    verified_upgrade_link = serializers.URLField()
diff --git a/lms/djangoapps/course_home_api/dates/v1/tests/__init__.py b/lms/djangoapps/course_home_api/dates/v1/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lms/djangoapps/course_home_api/dates/v1/tests/test_views.py b/lms/djangoapps/course_home_api/dates/v1/tests/test_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..604765fe1520e69fc6755feb2824daf5e642055c
--- /dev/null
+++ b/lms/djangoapps/course_home_api/dates/v1/tests/test_views.py
@@ -0,0 +1,54 @@
+"""
+Tests for Dates Tab API in the Course Home API
+"""
+
+
+import ddt
+
+from django.urls import reverse
+
+from course_modes.models import CourseMode
+from lms.djangoapps.course_home_api.tests.utils import BaseCourseHomeTests
+from student.models import CourseEnrollment
+
+
+@ddt.ddt
+class DatesTabTestViews(BaseCourseHomeTests):
+    """
+    Tests for the Dates Tab API
+    """
+    @classmethod
+    def setUpClass(cls):
+        BaseCourseHomeTests.setUpClass()
+        cls.url = reverse('course-home-dates-tab', args=[cls.course.id])
+
+    @ddt.data(CourseMode.AUDIT, CourseMode.VERIFIED)
+    def test_get_authenticated_enrolled_user(self, enrollment_mode):
+        CourseEnrollment.enroll(self.user, self.course.id, enrollment_mode)
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 200)
+
+        # Pulling out the date blocks to check learner has access. The Verification Deadline Date
+        # should not be accessible to the audit learner, but accessible to the verified learner.
+        date_blocks = response.data.get('course_date_blocks')
+        if enrollment_mode == CourseMode.AUDIT:
+            self.assertFalse(response.data.get('learner_is_verified'))
+            self.assertTrue(any(block.get('learner_has_access') is False for block in date_blocks))
+        else:
+            self.assertTrue(response.data.get('learner_is_verified'))
+            self.assertTrue(all(block.get('learner_has_access') for block in date_blocks))
+
+    def test_get_authenticated_user_not_enrolled(self):
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 200)
+        self.assertFalse(response.data.get('learner_is_verified'))
+
+    def test_get_unauthenticated_user(self):
+        self.client.logout()
+        response = self.client.get(self.url)
+        self.assertEqual(response.status_code, 403)
+
+    def test_get_unknown_course(self):
+        url = reverse('course-home-dates-tab', args=['course-v1:unknown+course+2T2020'])
+        response = self.client.get(url)
+        self.assertEqual(response.status_code, 404)
diff --git a/lms/djangoapps/course_home_api/dates/v1/views.py b/lms/djangoapps/course_home_api/dates/v1/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a55fdd923fc8a6866085d9bff9d5ed3c6c4c1c7
--- /dev/null
+++ b/lms/djangoapps/course_home_api/dates/v1/views.py
@@ -0,0 +1,90 @@
+"""
+Dates Tab Views
+"""
+
+
+from rest_framework.generics import RetrieveAPIView
+from rest_framework.permissions import IsAuthenticated
+from rest_framework.response import Response
+
+from edx_django_utils import monitoring as monitoring_utils
+from opaque_keys.edx.keys import CourseKey
+
+from lms.djangoapps.courseware.context_processor import user_timezone_locale_prefs
+from lms.djangoapps.courseware.courses import get_course_date_blocks, get_course_with_access
+from lms.djangoapps.courseware.date_summary import TodaysDate, verified_upgrade_deadline_link
+from lms.djangoapps.course_home_api.dates.v1.serializers import DatesTabSerializer
+from openedx.core.djangoapps.enrollments.api import get_enrollment
+from openedx.features.course_experience.utils import reset_deadlines_banner_should_display
+
+
+class DatesTabView(RetrieveAPIView):
+    """
+    **Use Cases**
+
+        Request details for the Dates Tab
+
+    **Example Requests**
+
+        GET api/course_home/v1/dates/{course_key}
+
+    **Response Values**
+
+        Body consists of the following fields:
+
+        course_date_blocks: List of serialized DateSummary objects. Each serialization has the following fields:
+            date: (datetime) The date time corresponding for the event
+            date_type: (str) The type of date (ex. course-start-date, assignment-due-date, etc.)
+            description: (str) The description for the date event
+            learner_has_access: (bool) Indicates if the learner has access to the date event
+            link: (str) An absolute link to content related to the date event
+                (ex. verified link or link to assignment)
+            title: (str) The title of the date event
+        display_reset_dates_text: (bool) Indicates whether the reset dates banner should be shown
+            for the given user
+        learner_is_verified: (bool) Indicates if the user is verified in the course
+        user_timezone: (str) The user's preferred timezone
+        verified_upgrade_link: (str) The link for upgrading to the Verified track in a course
+
+    **Returns**
+
+        * 200 on success with above fields.
+        * 403 if the user is not authenticated.
+        * 404 if the course is not available or cannot be seen.
+    """
+
+    permission_classes = (IsAuthenticated,)
+    serializer_class = DatesTabSerializer
+
+    def get(self, request, course_key_string):
+        # Enable NR tracing for this view based on course
+        monitoring_utils.set_custom_metric('course_id', course_key_string)
+        monitoring_utils.set_custom_metric('user_id', request.user.id)
+        monitoring_utils.set_custom_metric('is_staff', request.user.is_staff)
+
+        course_key = CourseKey.from_string(course_key_string)
+        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False)
+        blocks = get_course_date_blocks(course, request.user, request, include_access=True, include_past_dates=True)
+        display_reset_dates_text = reset_deadlines_banner_should_display(course_key, request)
+
+        learner_is_verified = False
+        enrollment = get_enrollment(request.user.username, course_key_string)
+        if enrollment:
+            learner_is_verified = enrollment.get('mode') == 'verified'
+
+        # User locale settings
+        user_timezone_locale = user_timezone_locale_prefs(request)
+        user_timezone = user_timezone_locale['user_timezone']
+
+        data = {
+            'course_date_blocks': [block for block in blocks if not isinstance(block, TodaysDate)],
+            'display_reset_dates_text': display_reset_dates_text,
+            'learner_is_verified': learner_is_verified,
+            'user_timezone': user_timezone,
+            'verified_upgrade_link': verified_upgrade_deadline_link(request.user, course=course),
+        }
+        context = self.get_serializer_context()
+        context['learner_is_verified'] = learner_is_verified
+        serializer = self.get_serializer_class()(data, context=context)
+
+        return Response(serializer.data)
diff --git a/lms/djangoapps/course_home_api/tests/__init__.py b/lms/djangoapps/course_home_api/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lms/djangoapps/course_home_api/tests/utils.py b/lms/djangoapps/course_home_api/tests/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..1fd56f4e496eab5f2a5faa56db10f351ea0eebda
--- /dev/null
+++ b/lms/djangoapps/course_home_api/tests/utils.py
@@ -0,0 +1,68 @@
+"""
+Base classes or util functions for use in Course Home API tests
+"""
+
+
+import unittest
+
+from datetime import datetime
+from django.conf import settings
+
+from course_modes.models import CourseMode
+from course_modes.tests.factories import CourseModeFactory
+from lms.djangoapps.verify_student.models import VerificationDeadline
+from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
+from student.tests.factories import UserFactory
+from xmodule.modulestore.django import modulestore
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, SharedModuleStoreTestCase
+from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory
+
+
+@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+class BaseCourseHomeTests(SharedModuleStoreTestCase):
+    """
+    Base class for Course Home API tests.
+
+    Creates a course to
+    """
+    MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
+
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+        cls.store = modulestore()
+        cls.course = CourseFactory.create(
+            start=datetime(2020, 1, 1),
+            end=datetime(2028, 1, 1),
+            enrollment_start=datetime(2020, 1, 1),
+            enrollment_end=datetime(2028, 1, 1),
+            emit_signals=True,
+            modulestore=cls.store,
+        )
+        chapter = ItemFactory(parent=cls.course, category='chapter')
+        ItemFactory(parent=chapter, category='sequential', display_name='sequence')
+
+        CourseModeFactory(course_id=cls.course.id, mode_slug=CourseMode.AUDIT)
+        CourseModeFactory(
+            course_id=cls.course.id,
+            mode_slug=CourseMode.VERIFIED,
+            expiration_datetime=datetime(2028, 1, 1)
+        )
+        VerificationDeadline.objects.create(course_key=cls.course.id, deadline=datetime(2028, 1, 1))
+
+        cls.user = UserFactory(
+            username='student',
+            email='user@example.com',
+            password='foo',
+            is_staff=False
+        )
+        CourseOverviewFactory.create(run='1T2020')
+
+    @classmethod
+    def tearDownClass(cls):
+        super().tearDownClass()
+        cls.store.delete_course(cls.course.id, cls.user.id)
+
+    def setUp(self):
+        super().setUp()
+        self.client.login(username=self.user.username, password='foo')
diff --git a/lms/djangoapps/course_home_api/urls.py b/lms/djangoapps/course_home_api/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..07753b3330f0eaa9d12ce48b501099e792f68c5c
--- /dev/null
+++ b/lms/djangoapps/course_home_api/urls.py
@@ -0,0 +1,20 @@
+"""
+Contains all the URLs for the Course Home
+"""
+
+
+from django.conf import settings
+from django.urls import re_path
+
+from lms.djangoapps.course_home_api.dates.v1 import views
+
+urlpatterns = []
+
+# Dates Tab URLs
+urlpatterns += [
+    re_path(
+        r'v1/dates/{}'.format(settings.COURSE_KEY_PATTERN),
+        views.DatesTabView.as_view(),
+        name='course-home-dates-tab'
+    ),
+]
diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py
index 40e8261c2df030ac9ad1b894a6e9619a5dd1f1fd..3836ed9fc105e1624ab690542b2d0748e3c10e21 100644
--- a/lms/djangoapps/courseware/courses.py
+++ b/lms/djangoapps/courseware/courses.py
@@ -6,7 +6,7 @@ courseware.
 
 import logging
 from collections import defaultdict, namedtuple
-from datetime import datetime, timedelta
+from datetime import datetime
 
 import pytz
 import six
@@ -60,7 +60,6 @@ from openedx.core.lib.api.view_utils import LazySequence
 from openedx.features.course_duration_limits.access import AuditExpiredError
 from openedx.features.course_experience import RELATIVE_DATES_FLAG
 from static_replace import replace_static_urls
-from student.models import CourseEnrollment
 from survey.utils import SurveyRequiredAccessError, check_survey_required_and_unanswered
 from util.date_utils import strftime_localized
 from xmodule.modulestore.django import modulestore
@@ -503,6 +502,7 @@ def get_course_assignment_date_blocks(course, user, request, num_return=None,
         date_block.contains_gated_content = assignment.contains_gated_content
         date_block.complete = assignment.complete
         date_block.past_due = assignment.past_due
+        date_block.link = assignment.url
         date_block.set_title(assignment.title, link=assignment.url)
         date_blocks.append(date_block)
     date_blocks = sorted((b for b in date_blocks if b.is_enabled or include_past_dates), key=date_block_key_fn)
@@ -534,7 +534,7 @@ def get_course_assignments(course_key, user, request, include_access=False):
                 subsection_key, 'contains_gated_content', False)
             title = block_data.get_xblock_field(subsection_key, 'display_name', _('Assignment'))
 
-            url = None
+            url = ''
             start = block_data.get_xblock_field(subsection_key, 'start')
             assignment_released = not start or start < now
             if assignment_released:
diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py
index 822ea730af742037544dd22d2275ec00167d77bb..49a41c3d20ea1fbae0ae17f7e27380e4125ea089 100644
--- a/lms/djangoapps/courseware/date_summary.py
+++ b/lms/djangoapps/courseware/date_summary.py
@@ -57,6 +57,10 @@ class DateSummary(object):
         """
         return ''
 
+    @property
+    def date_type(self):
+        return 'event'
+
     @property
     def title(self):
         """The title of this summary."""
@@ -226,6 +230,10 @@ class TodaysDate(DateSummary):
     def date(self):
         return self.current_time
 
+    @property
+    def date_type(self):
+        return 'todays-date'
+
     @property
     def title(self):
         return 'current_datetime'
@@ -242,6 +250,10 @@ class CourseStartDate(DateSummary):
     def date(self):
         return self.course.start
 
+    @property
+    def date_type(self):
+        return 'course-start-date'
+
     def register_alerts(self, request, course):
         """
         Registers an alert if the course has not started yet.
@@ -305,6 +317,10 @@ class CourseEndDate(DateSummary):
 
         return self.course.end
 
+    @property
+    def date_type(self):
+        return 'course-end-date'
+
     def register_alerts(self, request, course):
         """
         Registers an alert if the end date is approaching.
@@ -344,6 +360,7 @@ class CourseAssignmentDate(DateSummary):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.assignment_date = None
+        self.assignment_link = ''
         self.assignment_title = None
         self.assignment_title_html = None
         self.contains_gated_content = False
@@ -358,6 +375,18 @@ class CourseAssignmentDate(DateSummary):
     def date(self, date):
         self.assignment_date = date
 
+    @property
+    def date_type(self):
+        return 'assignment-due-date'
+
+    @property
+    def link(self):
+        return self.assignment_link
+
+    @link.setter
+    def link(self, link):
+        self.assignment_link = link
+
     @property
     def title(self):
         return self.assignment_title
@@ -387,6 +416,10 @@ class CourseExpiredDate(DateSummary):
             return
         return get_user_course_expiration_date(self.user, self.course)
 
+    @property
+    def date_type(self):
+        return 'course-expired-date'
+
     @property
     def description(self):
         return _('You lose all access to this course, including your progress.')
@@ -428,6 +461,10 @@ class CertificateAvailableDate(DateSummary):
     def date(self):
         return self.course.certificate_available_date
 
+    @property
+    def date_type(self):
+        return 'certificate-available-date'
+
     @property
     def has_certificate_modes(self):
         return any([
@@ -499,6 +536,10 @@ class VerifiedUpgradeDeadlineDate(DateSummary):
         else:
             return None
 
+    @property
+    def date_type(self):
+        return 'verified-upgrade-deadline'
+
     @property
     def title(self):
         dynamic_deadline = self._dynamic_deadline()
@@ -635,6 +676,10 @@ class VerificationDeadlineDate(DateSummary):
     def date(self):
         return VerificationDeadline.deadline_for_course(self.course_id)
 
+    @property
+    def date_type(self):
+        return 'verification-deadline-date'
+
     @lazy
     def is_enabled(self):
         if self.date is None:
diff --git a/lms/templates/courseware/dates.html b/lms/templates/courseware/dates.html
index 6b13518f958fa7a9a31bf014013daa3b6edc5e63..c4a4bdab83a92d011d185f977190727eff6e63ae 100644
--- a/lms/templates/courseware/dates.html
+++ b/lms/templates/courseware/dates.html
@@ -35,7 +35,7 @@ from openedx.core.djangolib.markup import HTML, Text
                         </div>
                     </div>
                 % endif
-                <% has_locked_assignments = any(hasattr(block, 'contains_gated_content') and block.contains_gated_content for block in course_date_blocks if isinstance(block, CourseAssignmentDate)) %>
+                <% has_locked_assignments = any(hasattr(block, 'contains_gated_content') and block.contains_gated_content for block in course_date_blocks) %>
                 % if has_locked_assignments and verified_upgrade_link:
                     <div class="dates-banner">
                         <div class="dates-banner-text banner-has-button">
diff --git a/lms/urls.py b/lms/urls.py
index 6e6c1943a70719d7935a31e451bccaf2d0c18955..0d4727be174cf36c96b9f87191f34fd1e0009187 100644
--- a/lms/urls.py
+++ b/lms/urls.py
@@ -999,3 +999,8 @@ if 'openedx.testing.coverage_context_listener' in settings.INSTALLED_APPS:
     ]
 
 urlpatterns.extend(plugin_urls.get_patterns(plugin_constants.ProjectType.LMS))
+
+# Course Home API urls
+urlpatterns += [
+    url(r'^api/course_home/', include('lms.djangoapps.course_home_api.urls')),
+]