diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py
index dba1c9ce4ec41f6c1b208863ea4e9bcca89eda6f..22ce2a8c6a2177c56f91887abf8d0586e6041683 100644
--- a/arkindex/documents/api/elements.py
+++ b/arkindex/documents/api/elements.py
@@ -15,11 +15,11 @@ from arkindex.documents.serializers.elements import (
 )
 from arkindex.documents.serializers.light import PageLightSerializer, RegionLightSerializer
 from arkindex.documents.serializers.ml import TranscriptionSerializer
-from arkindex.project.mixins import CorpusACLMixin, NestedCorpusMixin
+from arkindex.project.mixins import CorpusACLMixin
 from arkindex.project.pagination import PageNumberPagination
 from arkindex.project.permissions import IsVerified, IsVerifiedOrReadOnly
 
-from .filters import PageFilter
+from .filters import ElementsMLClassFilter
 
 
 classifications_prefetch = Prefetch(
@@ -33,8 +33,11 @@ class ElementsList(CorpusACLMixin, ListAPIView):
     List documents using pagination
     """
     serializer_class = ElementSlimSerializer
+    queryset = Element.objects.all()
+    filter_backends = (filters.DjangoFilterBackend,)
+    filterset_class = ElementsMLClassFilter
 
-    def get_queryset(self):
+    def filter_queryset(self, queryset):
         filters = {
             'type': self.request.query_params.get('type', ElementType.Volume),
         }
@@ -48,9 +51,14 @@ class ElementsList(CorpusACLMixin, ListAPIView):
             filters['corpus'] = self.get_corpus(self.request.query_params['corpus'])
         else:
             filters['corpus__in'] = Corpus.objects.readable(self.request.user)
+
         if 'name' in self.request.query_params:
             filters['name__icontains'] = self.request.query_params['name']
-        return Element.objects.filter(**filters).prefetch_related('corpus').order_by('corpus', 'type', 'name')
+
+        return super().filter_queryset(queryset) \
+            .filter(**filters) \
+            .prefetch_related('corpus') \
+            .order_by('corpus', 'type', 'name')
 
 
 class ElementRetrieve(RetrieveUpdateAPIView):
@@ -151,24 +159,6 @@ class CorpusRetrieve(RetrieveUpdateDestroyAPIView):
             self.permission_denied(request, message='You do not have write access to this corpus.')
 
 
-class CorpusPages(NestedCorpusMixin, ListAPIView):
-    """
-    List all pages in a corpus
-    """
-    serializer_class = PageLightSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filterset_class = PageFilter
-
-    def get_queryset(self):
-        return Page.objects.filter(corpus=self.corpus)
-
-    def filter_queryset(self, queryset):
-        return Page.objects.filter(pk__in=super().filter_queryset(queryset)) \
-                           .select_related('zone__image__server') \
-                           .prefetch_related(classifications_prefetch) \
-                           .order_by('paths__ordering')
-
-
 class PageDetails(RetrieveAPIView):
     """
     Get details for a specific page
diff --git a/arkindex/documents/api/entities.py b/arkindex/documents/api/entities.py
index 537ddf2d8322cf9079ba886bcea4020de522e9b7..35580f144b930c9796cb55dcdd72a99a56e5e3c1 100644
--- a/arkindex/documents/api/entities.py
+++ b/arkindex/documents/api/entities.py
@@ -17,7 +17,7 @@ from arkindex.documents.serializers.ml import MLClassSerializer
 from arkindex.project.mixins import NestedCorpusMixin
 from arkindex.project.permissions import IsVerified
 from django.db.models import Q
-from .filters import MLClassFilter
+from .filters import CorpusMLClassFilter
 
 
 class CorpusRoles(CorpusACLMixin, ListCreateAPIView):
@@ -53,7 +53,7 @@ class CorpusMLClassList(NestedCorpusMixin, ListAPIView):
     """
     serializer_class = MLClassSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filterset_class = MLClassFilter
+    filterset_class = CorpusMLClassFilter
     action = 'ListCorpus'  # For OpenAPI operationId -> ListCorpusMLClass
 
     def get_queryset(self):
diff --git a/arkindex/documents/api/filters.py b/arkindex/documents/api/filters.py
index 6fbad6638fff18dcf1626cceb046cf3cf4d4d0f2..6e15172faf9c945168cdd4d53d17e5ce7ab182d0 100644
--- a/arkindex/documents/api/filters.py
+++ b/arkindex/documents/api/filters.py
@@ -9,7 +9,7 @@ class MLClassVolumeChoiceFilter(filters.ModelChoiceFilter):
         return Element.objects.filter(type=ElementType.Volume, corpus=request.corpus)
 
 
-class MLClassFilter(filters.FilterSet):
+class CorpusMLClassFilter(filters.FilterSet):
     volume = MLClassVolumeChoiceFilter(method='filter_volume', label='Volume')
 
     def filter_volume(self, queryset, name, value):
@@ -20,7 +20,7 @@ class MLClassFilter(filters.FilterSet):
         fields = ['volume']
 
 
-class PageFilter(filters.FilterSet):
+class ElementsMLClassFilter(filters.FilterSet):
     ml_class = filters.ModelChoiceFilter(
         queryset=MLClass.objects.all(), field_name='classifications__ml_class', label='Class')
     ml_class_unvalidated = filters.BooleanFilter(
@@ -34,5 +34,5 @@ class PageFilter(filters.FilterSet):
         return base_qs.exclude(num_validated=0)
 
     class Meta:
-        model = Page
+        model = Element
         fields = ['ml_class', 'ml_class_unvalidated']
diff --git a/arkindex/documents/tests/test_corpus.py b/arkindex/documents/tests/test_corpus.py
index a8b456634f980b7cdc2685c6c75b6fc9c78f78e9..93da6b18b6df9de52292ab1d2946e953896f7564 100644
--- a/arkindex/documents/tests/test_corpus.py
+++ b/arkindex/documents/tests/test_corpus.py
@@ -2,7 +2,7 @@ from django.contrib.auth.models import AnonymousUser
 from django.urls import reverse
 from rest_framework import status
 
-from arkindex.documents.models import Corpus, DataSource, Element, ElementType, MLClass, Page
+from arkindex.documents.models import Corpus, Element, ElementType
 from arkindex.project.tests import FixtureAPITestCase
 
 
@@ -174,58 +174,3 @@ class TestCorpus(FixtureAPITestCase):
     def test_delete_requires_login(self):
         response = self.client.delete(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_private.id}))
         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
-
-    def test_pages_list(self):
-        self.client.force_login(self.user)
-        response = self.client.get(reverse('api:corpus-pages', kwargs={'pk': self.corpus_public.id}))
-        self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(response.data['count'], 6)
-        self.assertEqual(len(response.data['results']), 6)
-        self.assertIsNone(response.data['next'])
-        self.assertIsNone(response.data['previous'])
-
-        # Add a class to filter with: without classification, must not return any result
-        text = MLClass.objects.create(name='text', corpus=self.corpus_public)
-        response = self.client.get(
-            reverse('api:corpus-pages', kwargs={'pk': self.corpus_public.id}), {'ml_class': text.id})
-        self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertDictEqual(response.json(), {
-            "count": 0,
-            "number": 1,
-            "next": None,
-            "previous": None,
-            "results": []
-        })
-
-        # Add a classification: must return one result
-        page = Page.objects.get(name='Volume 1, page 1v')
-        page.classifications.create(
-            source=DataSource.objects.get(slug='test'),
-            ml_class=text,
-        )
-        response = self.client.get(
-            reverse('api:corpus-pages', kwargs={'pk': self.corpus_public.id}),
-            {'ml_class': text.id},
-        )
-        self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertDictEqual(response.json(), {
-            "count": 1,
-            "number": 1,
-            "next": None,
-            "previous": None,
-            "results": [{
-                'id': str(page.id),
-                'type': 'page',
-                'name': 'Volume 1, page 1v',
-                'image': {
-                    'id': str(page.zone.image_id),
-                    'path': 'img2',
-                    's3_url': None,
-                    'width': 1000,
-                    'height': 1000,
-                    'url': 'http://server/img2',
-                    'status': 'unchecked'
-                },
-                }
-            ]
-        })
diff --git a/arkindex/project/api_v1.py b/arkindex/project/api_v1.py
index 5849a2cf3425c317b3e6e1e139d8dd6d8ff361a5..741526c72b0cdf30f30bcd601cbf248ab4cf69b0 100644
--- a/arkindex/project/api_v1.py
+++ b/arkindex/project/api_v1.py
@@ -3,7 +3,7 @@ from django.views.generic.base import RedirectView
 
 from arkindex.documents.api.elements import (
     ElementsList, RelatedElementsList, ElementRetrieve, ElementPages,
-    CorpusList, CorpusRetrieve, CorpusPages, ActEdit, PageDetails, SurfaceDetails,
+    CorpusList, CorpusRetrieve, ActEdit, PageDetails, SurfaceDetails,
     ElementTranscriptions, ElementsCreate, ElementRegions, RegionDetails, RegionCreate,
     ElementNeighbors,
 )
@@ -61,7 +61,6 @@ api = [
     path('corpus/', CorpusList.as_view(), name='corpus'),
     path('corpus/<uuid:pk>/', CorpusRetrieve.as_view(), name='corpus-retrieve'),
     path('corpus/<uuid:pk>/classes/', CorpusMLClassList.as_view(), name='corpus-classes'),
-    path('corpus/<uuid:pk>/pages/', CorpusPages.as_view(), name='corpus-pages'),
     path('corpus/<uuid:pk>/roles/', CorpusRoles.as_view(), name='corpus-roles'),
 
     # Moderation
diff --git a/openapi/patch.yml b/openapi/patch.yml
index af51cb86853821b09843ec577552b7984a64e267..a4bc3f7b754439c3335f0a1283de1e67c5faf370 100644
--- a/openapi/patch.yml
+++ b/openapi/patch.yml
@@ -116,13 +116,6 @@ paths:
       description: List all available classes in a corpus
       tags:
         - ml
-  /api/v1/corpus/{id}/pages/:
-    get:
-      operationId: ListCorpusPages
-      description: List all pages in all volumes of a corpus
-      security: []
-      tags:
-        - elements
   /api/v1/corpus/{id}/roles/:
     get:
       operationId: ListCorpusRoles