diff --git a/program/serializers.py b/program/serializers.py
index 8ec1d8236ef1de75566dc79009ed887240ee7f49..21f4b476a61245ad29cb7a1d4d3782a2b0982b5b 100644
--- a/program/serializers.py
+++ b/program/serializers.py
@@ -30,6 +30,7 @@ from program.models import (
     FundingCategory,
     Host,
     HostLink,
+    Image,
     Language,
     LicenseType,
     LinkType,
@@ -209,6 +210,55 @@ class ThumbnailsMixin:
         return thumbnails
 
 
+class ImageSerializer(serializers.ModelSerializer):
+    thumbnails = serializers.SerializerMethodField()
+
+    @staticmethod
+    def get_thumbnails(instance) -> List[str]:
+        """Returns thumbnails"""
+        thumbnails = []
+
+        if instance.image.name and THUMBNAIL_SIZES:
+            for size in THUMBNAIL_SIZES:
+                thumbnails.append(instance.image.crop[size].name)
+
+        return thumbnails
+
+    class Meta:
+        model = Image
+        read_only_fields = (
+            "height",
+            "id",
+            "ppoi",
+            "thumbnails",
+            "width",
+        )
+        fields = (
+            "alt_text",
+            "credits",
+            "image",
+        ) + read_only_fields
+
+    def create(self, validated_data):
+        """Create and return a new Image instance, given the validated data."""
+
+        image = Image.objects.create(**validated_data | self.context)
+        image.save()
+
+        return image
+
+    def update(self, instance, validated_data):
+        """Update and return an existing Image instance, given the validated data."""
+
+        # Only alt_text and credits can be updated.
+        instance.alt_text = validated_data.get("alt_text", instance.alt_text)
+        instance.credits = validated_data.get("credits", instance.credits)
+
+        instance.save()
+
+        return instance
+
+
 class HostSerializer(ThumbnailsMixin, serializers.ModelSerializer):
     links = HostLinkSerializer(many=True, required=False)
     thumbnails = serializers.SerializerMethodField()