diff --git a/scipost_django/api/urls.py b/scipost_django/api/urls.py
index c14d8845822210608bb0c7d49863b7aadace8e69..6b2f24c73bc7259be32cdc669763c73bbaa08eb7 100644
--- a/scipost_django/api/urls.py
+++ b/scipost_django/api/urls.py
@@ -55,6 +55,4 @@ urlpatterns += [
         name='omniauth_userinfo'
     ),
     path('finances/', include('finances.api.urls')),
-    path('deprec/journals/', include('journals.api.urls')), # TODO remove
-
 ]
diff --git a/scipost_django/journals/api/serializers/publication.py b/scipost_django/journals/api/serializers/publication.py
index de9a56f77e89dc4026f00c79f249701e3299cb88..6413fc042f7418d06a6bbf03684fd7b13d2b75cb 100644
--- a/scipost_django/journals/api/serializers/publication.py
+++ b/scipost_django/journals/api/serializers/publication.py
@@ -14,10 +14,10 @@ class PublicationPublicSerializer(DynamicFieldsModelSerializer):
     class Meta:
         model = Publication
         fields = [
+            'url',
             'title',
             'author_list',
             'abstract',
             'doi_label',
             'publication_date',
-            'url'
         ]
diff --git a/scipost_django/journals/api/serializers_deprec.py b/scipost_django/journals/api/serializers_deprec.py
deleted file mode 100644
index b4f1e64659ecb91a6819a97d70c2840d7ba03f8f..0000000000000000000000000000000000000000
--- a/scipost_django/journals/api/serializers_deprec.py
+++ /dev/null
@@ -1,78 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-from rest_framework import serializers
-
-from organizations.api.serializers import OrganizationPublicSerializer
-from ..models import Publication, OrgPubFraction
-
-
-class StringListField(serializers.ListField):
-    child = serializers.CharField()
-
-
-class PublicationSerializer(serializers.BaseSerializer):
-    title = serializers.CharField(max_length=512)
-    authors = StringListField()
-    doi = serializers.CharField(max_length=256)
-    publication_date = serializers.DateField()
-    journal_name = serializers.CharField(max_length=128)
-    issn = serializers.CharField(max_length=16)
-    volume = serializers.IntegerField()
-    issue = serializers.IntegerField()
-    url = serializers.URLField()
-    pdf_url = serializers.URLField()
-
-    def to_representation(self, instance):
-        """
-        Convert publication information to a JSON format.
-        """
-        authors = []
-        for author in instance.authors.all():
-            authors.append('%s, %s' % (author.profile.last_name,
-                                       author.profile.first_name))
-        rep = {
-            'title': instance.title,
-            'authors': authors,
-            'doi': instance.doi_string,
-            'publication_date': instance.publication_date.strftime('%Y/%m/%d'),
-            'journal_name': str(instance.get_journal()),
-            'issn': instance.get_journal().issn,
-        }
-        if instance.in_issue:
-            if instance.in_issue.in_volume:
-                rep['volume'] = instance.in_issue.in_volume.number
-            rep['issue'] = instance.in_issue.number
-        rep['url'] = 'https://scipost.org%s' % instance.get_absolute_url()
-        rep['pdf_url'] = 'https://scipost.org%s/pdf' % instance.get_absolute_url()
-        return rep
-
-
-class OrgPubFractionSerializer(serializers.ModelSerializer):
-    """
-    Read-only ModelSerializer for OrgPubFraction.
-
-    Takes optional `fields` argument specifying which fields should be displayed.
-    """
-    organization = OrganizationPublicSerializer()
-    publication = PublicationSerializer()
-
-    class Meta:
-        model = OrgPubFraction
-        fields = ['organization', 'publication', 'fraction']
-        read_only_fields = ['organization', 'publication', 'fraction']
-
-    def __init__(self, *args, **kwargs):
-        # Don't pass the 'fields' arg up to the superclass
-        fields = kwargs.pop('fields', None)
-
-        # Instantiate the superclass normally
-        super(OrgPubFractionSerializer, self).__init__(*args, **kwargs)
-
-        if fields is not None:
-            # Drop any fields that are not specified in the `fields` argument.
-            allowed = set(fields)
-            existing = set(self.fields)
-            for field_name in existing - allowed:
-                self.fields.pop(field_name)
diff --git a/scipost_django/journals/api/urls.py b/scipost_django/journals/api/urls.py
deleted file mode 100644
index 408023fca42366c6395a98c5f406dcb999f02405..0000000000000000000000000000000000000000
--- a/scipost_django/journals/api/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-from django.urls import path
-
-from journals.api import views as api_views
-
-
-urlpatterns = [
-
-    path( # /api/journals/publications
-        'publications',
-        api_views.PublicationListAPIView.as_view(),
-        name='publications'
-    ),
-    path( # /api/journals/publications/<doi_label>
-        'publications/<str:doi_label>',
-        api_views.PublicationRetrieveAPIView.as_view(),
-        name='publication-detail'
-    ),
-
-    path( # /api/journals/pubfractions
-        'pubfractions',
-        api_views.OrgPubFractionListAPIView.as_view(),
-        name='pubfractions'
-    ),
-
-]
diff --git a/scipost_django/journals/api/views.py b/scipost_django/journals/api/views.py
deleted file mode 100644
index 9e07141233e1ca8ca0ffb35e336b2fe2aadd1bed..0000000000000000000000000000000000000000
--- a/scipost_django/journals/api/views.py
+++ /dev/null
@@ -1,45 +0,0 @@
-__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
-__license__ = "AGPL v3"
-
-
-from rest_framework.generics import ListAPIView, RetrieveAPIView
-
-from django.db.models import Sum
-
-from ..models import Publication, OrgPubFraction
-from .serializers_deprec import PublicationSerializer, OrgPubFractionSerializer
-
-
-class PublicationListAPIView(ListAPIView):
-    serializer_class = PublicationSerializer
-    lookup_field = 'doi_label'
-
-    def get_queryset(self):
-        queryset = Publication.objects.published().order_by('-publication_date')
-        doi = self.request.query_params.get('doi', None)
-        if doi:
-            queryset = queryset.filter(doi_label__icontains=doi)
-        return queryset
-
-class PublicationRetrieveAPIView(RetrieveAPIView):
-    queryset = Publication.objects.published()
-    serializer_class = PublicationSerializer
-    lookup_url_kwarg = 'doi_label'
-    lookup_field = 'doi_label'
-
-
-class OrgPubFractionListAPIView(ListAPIView):
-    serializer_class = OrgPubFractionSerializer
-
-    def get_queryset(self):
-        queryset = OrgPubFraction.objects.all()
-        org_id = self.request.query_params.get('org_id', None)
-        if org_id is not None:
-            queryset = queryset.filter(organization__pk=org_id)
-        year = self.request.query_params.get('year', None)
-        if year is not None:
-            queryset = queryset.filter(publication__publication_date__startswith=year)
-        journal = self.request.query_params.get('journal', None)
-        if journal is not None:
-            queryset = queryset.filter(publication__doi_label__istartswith=journal + '.')
-        return queryset
diff --git a/scipost_django/journals/api/viewsets/publication.py b/scipost_django/journals/api/viewsets/publication.py
index b7094a5fb9dfc9ab876989b30b6da195747b50cc..2e5e798ee990bcc2ffca4f9fdd98083451ebc15c 100644
--- a/scipost_django/journals/api/viewsets/publication.py
+++ b/scipost_django/journals/api/viewsets/publication.py
@@ -10,6 +10,7 @@ from rest_framework.permissions import AllowAny
 from api.viewsets.mixins import FilteringOptionsActionMixin
 
 from journals.models import Publication
+from journals.regexes import PUBLICATION_DOI_LABEL_REGEX
 from journals.api.filtersets import PublicationPublicAPIFilterSet
 from journals.api.serializers import PublicationPublicSerializer
 
@@ -20,6 +21,8 @@ class PublicationPublicAPIViewSet(
     queryset = Publication.objects.published()
     permission_classes = [AllowAny,]
     serializer_class = PublicationPublicSerializer
+    lookup_field = 'doi_label'
+    lookup_value_regex = PUBLICATION_DOI_LABEL_REGEX
     search_fields = ['title', 'author_list', 'abstract', 'doi_label']
     ordering_fields = ['publication_date',]
     filterset_class = PublicationPublicAPIFilterSet
diff --git a/scipost_django/submissions/api/filtersets/__init__.py b/scipost_django/submissions/api/filtersets/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..c92618b40daaeea58c3c84f39b25a2565f5f5160
--- /dev/null
+++ b/scipost_django/submissions/api/filtersets/__init__.py
@@ -0,0 +1,5 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from .submission import SubmissionPublicAPIFilterSet
diff --git a/scipost_django/submissions/api/filtersets/submission.py b/scipost_django/submissions/api/filtersets/submission.py
new file mode 100644
index 0000000000000000000000000000000000000000..d291b4631e18c6296197cefbe42b2979e67b3512
--- /dev/null
+++ b/scipost_django/submissions/api/filtersets/submission.py
@@ -0,0 +1,25 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django_filters import rest_framework as df_filters
+
+from submissions.models import Submission
+
+
+class SubmissionPublicAPIFilterSet(df_filters.FilterSet):
+    class Meta:
+        model = Submission
+        fields = {
+            'title': ['icontains', 'contains', 'istartswith', 'iregex', 'regex'],
+            'author_list': ['icontains', 'contains', 'iregex', 'regex'],
+            'abstract': ['icontains', 'contains', 'iregex', 'regex'],
+            'submission_date': [
+                'date__year', 'date__month', 'date__exact',
+                'date__year__gte', 'date__year__lte', 'date__year__range',
+                'date__gte', 'date__lte', 'date__range'
+            ],
+            'acad_field__name': ['icontains',],
+            'specialties__name': ['icontains',],
+            'topics__name': ['icontains',],
+        }