diff --git a/scipost_django/api/urls.py b/scipost_django/api/urls.py
index 83fbc8ae39e4c5378970d948762be1b62718a111..96f31b84cb154a7ceb73b2c7ce035842f243b6bd 100644
--- a/scipost_django/api/urls.py
+++ b/scipost_django/api/urls.py
@@ -6,6 +6,10 @@ from django.urls import include, path
 
 from rest_framework import routers
 
+
+# colleges
+from colleges.api.viewsets import FellowshipPublicAPIViewSet
+
 # journals
 from journals.api.viewsets import (
     PublicationPublicAPIViewSet,
@@ -51,6 +55,10 @@ router.register("search/submissions", SubmissionPublicSearchAPIViewSet)
 # publicly-accessible routes
 #############################
 
+# colleges
+router.register("colleges/fellowships", FellowshipPublicAPIViewSet)
+
+
 # journals
 router.register("publications", PublicationPublicAPIViewSet)
 router.register("pubfractions", PubFractionPublicAPIViewSet)
diff --git a/scipost_django/colleges/api/filtersets.py b/scipost_django/colleges/api/filtersets.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c7c9d67ac8f28be2a0c3ebe0ba12ac62505400d
--- /dev/null
+++ b/scipost_django/colleges/api/filtersets.py
@@ -0,0 +1,48 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django_filters import rest_framework as df_filters
+
+from colleges.models import Fellowship
+
+
+class FellowshipPublicAPIFilterSet(df_filters.FilterSet):
+    class Meta:
+        model = Fellowship
+        fields = {
+            "contributor__profile__last_name": [
+                "icontains",
+                "contains",
+                "istartswith",
+                "startswith",
+            ],
+            "contributor__profile__affiliations__organization__country": [
+                "icontains",
+            ],
+            "college__name": [
+                "icontains",
+            ],
+            "start_date": [
+                "year",
+                "month",
+                "exact",
+                "year__gte",
+                "year__lte",
+                "year__range",
+                "gte",
+                "lte",
+                "range",
+            ],
+            "until_date": [
+                "year",
+                "month",
+                "exact",
+                "year__gte",
+                "year__lte",
+                "year__range",
+                "gte",
+                "lte",
+                "range",
+            ],
+        }
diff --git a/scipost_django/colleges/api/serializers.py b/scipost_django/colleges/api/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..eef7616046206e73a5f71de32639f180eacd1b31
--- /dev/null
+++ b/scipost_django/colleges/api/serializers.py
@@ -0,0 +1,26 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from rest_framework import serializers
+
+from api.serializers import DynamicFieldsModelSerializer
+
+from colleges.models import Fellowship
+
+from scipost.api.serializers import ContributorPublicAPISerializer
+
+class FellowshipPublicAPISerializer(DynamicFieldsModelSerializer):
+    contributor = ContributorPublicAPISerializer()
+    college = serializers.StringRelatedField()
+
+    class Meta:
+        model = Fellowship
+        fields = [
+            "contributor",
+            "college",
+            "start_date",
+            "until_date",
+            "status",
+            "guest",
+        ]
diff --git a/scipost_django/colleges/api/viewsets.py b/scipost_django/colleges/api/viewsets.py
new file mode 100644
index 0000000000000000000000000000000000000000..b524817cdc397f6726f1aca71102b524a50ff8f1
--- /dev/null
+++ b/scipost_django/colleges/api/viewsets.py
@@ -0,0 +1,30 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from api.viewsets.base import ExtraFilteredReadOnlyModelViewSet
+from api.viewsets.mixins import FilteringOptionsActionMixin
+
+from colleges.models import Fellowship
+from colleges.api.filtersets import FellowshipPublicAPIFilterSet
+from colleges.api.serializers import FellowshipPublicAPISerializer
+
+
+class FellowshipPublicAPIViewSet(
+    FilteringOptionsActionMixin, ExtraFilteredReadOnlyModelViewSet
+):
+    queryset = Fellowship.objects.all()
+    serializer_class = FellowshipPublicAPISerializer
+    search_fields = [
+        "first_name",
+        "last_name",
+    ]
+    ordering_fields = [
+        "last_name",
+        "acad_field",
+    ]
+    filterset_class = FellowshipPublicAPIFilterSet
+    default_filtering_fields = [
+        "last_name__icontains",
+        "profile__affiliations__country__name__icontains",
+    ]
diff --git a/scipost_django/profiles/api/serializers.py b/scipost_django/profiles/api/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..384d14657ef4bf38fc456a31c8e17e5da86c6ccb
--- /dev/null
+++ b/scipost_django/profiles/api/serializers.py
@@ -0,0 +1,46 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from rest_framework import serializers
+
+from api.serializers import DynamicFieldsModelSerializer
+
+from profiles.models import Profile, Affiliation
+
+from organizations.api.serializers import OrganizationPublicSerializer
+
+
+class AffiliationPublicAPISerializer(DynamicFieldsModelSerializer):
+    organization = OrganizationPublicSerializer() #serializers.StringRelatedField()
+
+    class Meta:
+        model = Affiliation
+        fields = [
+            "organization",
+            "category",
+            "date_from",
+            "date_until",
+        ]
+
+
+class ProfilePublicAPISerializer(DynamicFieldsModelSerializer):
+    title = serializers.CharField(source="get_title_display")
+    acad_field = serializers.StringRelatedField()
+    specialties = serializers.StringRelatedField(many=True)
+    topics = serializers.StringRelatedField(many=True)
+    affiliations = AffiliationPublicAPISerializer(many=True)
+
+    class Meta:
+        model = Profile
+        fields = [
+            "title",
+            "first_name",
+            "last_name",
+            "orcid_id",
+            "webpage",
+            "acad_field",
+            "specialties",
+            "topics",
+            "affiliations",
+        ]
diff --git a/scipost_django/scipost/api/serializers.py b/scipost_django/scipost/api/serializers.py
new file mode 100644
index 0000000000000000000000000000000000000000..63e3728d0974ac0082840018ac1cbb16935d3c01
--- /dev/null
+++ b/scipost_django/scipost/api/serializers.py
@@ -0,0 +1,21 @@
+__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from rest_framework import serializers
+
+from api.serializers import DynamicFieldsModelSerializer
+
+from scipost.models import Contributor
+
+from profiles.api.serializers import ProfilePublicAPISerializer
+
+
+class ContributorPublicAPISerializer(DynamicFieldsModelSerializer):
+    profile = ProfilePublicAPISerializer()
+
+    class Meta:
+        model = Contributor
+        fields = [
+            "profile",
+        ]