diff --git a/api.go b/api.go
index 78979f7794c544d44f1eccd5837ba63dc20bfa56..e4bfea25a098b41333644ada5ec021cf3ce4e35d 100644
--- a/api.go
+++ b/api.go
@@ -294,6 +294,42 @@ func registerAPI() {
 		context.JSON(http.StatusOK, instance.ImageSnowflake(flake))
 	})
 
+	router.GET("/api/image/snowflake/:flake/file", func(context *gin.Context) {
+		flake := context.Param("flake")
+		if _, err := strconv.Atoi(flake); err != nil {
+			context.JSON(http.StatusBadRequest, gin.H{
+				"error": "invalid snowflake",
+			})
+			return
+		}
+		image, data := instance.ImageData(instance.ImageSnowflakeHash(flake), false)
+		if image.Hash == "" {
+			context.JSON(http.StatusNotFound, gin.H{
+				"error": "not found",
+			})
+			return
+		}
+		context.Data(http.StatusOK, "image/"+image.Type, data)
+	})
+
+	router.GET("/api/image/snowflake/:flake/preview", func(context *gin.Context) {
+		flake := context.Param("flake")
+		if _, err := strconv.Atoi(flake); err != nil {
+			context.JSON(http.StatusBadRequest, gin.H{
+				"error": "invalid snowflake",
+			})
+			return
+		}
+		image, data := instance.ImageData(instance.ImageSnowflakeHash(flake), true)
+		if image.Hash == "" {
+			context.JSON(http.StatusNotFound, gin.H{
+				"error": "not found",
+			})
+			return
+		}
+		context.Data(http.StatusOK, "image/jpeg", data)
+	})
+
 	router.GET("/api/image", func(context *gin.Context) {
 		info, ok := getUser(context)
 
diff --git a/store/image.go b/store/image.go
index 6ef019d203550dc7c5600329384d3605d269c830..5e57acfd27d4b68c823e133e4b5f67dafb107358 100644
--- a/store/image.go
+++ b/store/image.go
@@ -64,6 +64,9 @@ func (s *Store) Image(hash string) Image {
 func (s *Store) ImageMetadataRead(path string) Image {
 	var metadata Image
 	if payload, err := os.ReadFile(path); err != nil {
+		if os.IsNotExist(err) {
+			return Image{}
+		}
 		s.fatalClose(fmt.Sprintf("Error reading image metadata %s, %s", path, err))
 	} else {
 		if err = json.Unmarshal(payload, &metadata); err != nil {
@@ -246,6 +249,9 @@ func (s *Store) ImageSnowflakeHash(flake string) string {
 		return s.ImageMetadataRead(s.ImageSnowflakePath(flake) + "/" + infoJson).Hash
 	} else {
 		if path, err := os.ReadFile(s.ImageSnowflakePath(flake)); err != nil {
+			if os.IsNotExist(err) {
+				return ""
+			}
 			s.fatalClose(fmt.Sprintf("Error reading snowflake %s association file, %s", flake, err))
 		} else {
 			return s.ImageMetadataRead(string(path) + "/" + infoJson).Hash