diff --git a/program/filters.py b/program/filters.py
index dc2c841a7caa055563f9665b630d4c3dc45bcaf6..7819371e93ca0e4512f1c964ddefebcafbc0fc24 100644
--- a/program/filters.py
+++ b/program/filters.py
@@ -280,3 +280,25 @@ class ActiveFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
         fields = [
             "is_active",
         ]
+
+
+class PlayoutFilterSet(filters.FilterSet):
+    start = filters.DateFilter(
+        field_name="start",
+        lookup_expr="gte",
+        help_text="Returns timeslots that start at or after the specified datetime "
+        "(default: today).",
+    )
+    end = filters.DateFilter(
+        field_name="end",
+        lookup_expr="lte",
+        help_text="Returns timeslots that end at or before the specified datetime "
+        "(default: one week after start date).",
+    )
+    include_virtual = filters.BooleanFilter(
+        field_name="include_virtual", help_text="Include virtual timeslots (default: false)."
+    )
+
+    class Meta:
+        model = models.TimeSlot
+        fields = ["start", "end", "include_virtual"]
diff --git a/program/views.py b/program/views.py
index ae8accb6e4821f0c54e2b7d645fde0d0ef987587..b70e0d78c41c7103bdcb2ca424ba5b0bc5ff606e 100644
--- a/program/views.py
+++ b/program/views.py
@@ -157,6 +157,7 @@ class APIDayScheduleViewSet(
     viewsets.GenericViewSet,
 ):
     queryset = TimeSlot.objects.all()
+    serializer_class = TimeSlotSerializer
 
     def list(self, request, year=None, month=None, day=None):
         # datetime.combine returns a timezone naive datetime object
@@ -187,11 +188,7 @@ class APIDayScheduleViewSet(
     list=extend_schema(
         summary="List scheduled playout.",
         description=(
-            "Returns a list of the scheduled playout."
-            "Expects parameters `start` (date), `end` (date), and `includeVirtual` (boolean)."
-            "- `start` is today by default."
-            "- `end` is one week after the start date by default."
-            "- `includeVirtual` is false by default."
+            "Returns a list of the scheduled playout. "
             "The schedule will include virtual timeslots to fill unscheduled gaps if requested."
         ),
     ),
@@ -201,6 +198,9 @@ class APIPlayoutViewSet(
     viewsets.GenericViewSet,
 ):
     queryset = TimeSlot.objects.all()
+    serializer_class = TimeSlotSerializer
+    filter_backends = [DjangoFilterBackend]
+    filterset_class = filters.PlayoutFilterSet
 
     def list(self, request, *args, **kwargs):
         """