diff --git a/modules/structs/repo.go b/modules/structs/repo.go
index 3b43f74c7994f..94992de72ebc2 100644
--- a/modules/structs/repo.go
+++ b/modules/structs/repo.go
@@ -380,3 +380,9 @@ type NewIssuePinsAllowed struct {
 	Issues       bool `json:"issues"`
 	PullRequests bool `json:"pull_requests"`
 }
+
+// UpdateRepoAvatarUserOption options when updating the repo avatar
+type UpdateRepoAvatarOption struct {
+	// image must be base64 encoded
+	Image string `json:"image" binding:"Required"`
+}
diff --git a/modules/structs/user.go b/modules/structs/user.go
index f68b92ac069e2..0df67894b0397 100644
--- a/modules/structs/user.go
+++ b/modules/structs/user.go
@@ -102,3 +102,9 @@ type RenameUserOption struct {
 	// unique: true
 	NewName string `json:"new_username" binding:"Required"`
 }
+
+// UpdateUserAvatarUserOption options when updating the user avatar
+type UpdateUserAvatarOption struct {
+	// image must be base64 encoded
+	Image string `json:"image" binding:"Required"`
+}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 8b7f55976b0ec..0e28bde68309a 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -899,6 +899,11 @@ func Routes() *web.Route {
 					Patch(bind(api.EditHookOption{}), user.EditHook).
 					Delete(user.DeleteHook)
 			}, reqWebhooksEnabled())
+
+			m.Group("/avatar", func() {
+				m.Post("", bind(api.UpdateUserAvatarOption{}), user.UpdateAvatar)
+				m.Delete("", user.DeleteAvatar)
+			}, reqToken())
 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
 
 		// Repositories (requires repo scope, org scope)
@@ -1134,6 +1139,10 @@ func Routes() *web.Route {
 				m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages)
 				m.Get("/activities/feeds", repo.ListRepoActivityFeeds)
 				m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed)
+				m.Group("/avatar", func() {
+					m.Post("", bind(api.UpdateRepoAvatarOption{}), repo.UpdateAvatar)
+					m.Delete("", repo.DeleteAvatar)
+				}, reqAdmin(), reqToken())
 			}, repoAssignment())
 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
 
@@ -1314,6 +1323,10 @@ func Routes() *web.Route {
 					Patch(bind(api.EditHookOption{}), org.EditHook).
 					Delete(org.DeleteHook)
 			}, reqToken(), reqOrgOwnership(), reqWebhooksEnabled())
+			m.Group("/avatar", func() {
+				m.Post("", bind(api.UpdateUserAvatarOption{}), org.UpdateAvatar)
+				m.Delete("", org.DeleteAvatar)
+			}, reqToken(), reqOrgOwnership())
 			m.Get("/activities/feeds", org.ListOrgActivityFeeds)
 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true))
 		m.Group("/teams/{teamid}", func() {
diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go
new file mode 100644
index 0000000000000..b3cb0b81a6be8
--- /dev/null
+++ b/routers/api/v1/org/avatar.go
@@ -0,0 +1,74 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package org
+
+import (
+	"encoding/base64"
+	"net/http"
+
+	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/web"
+	user_service "code.gitea.io/gitea/services/user"
+)
+
+// UpdateAvatarupdates the Avatar of an Organisation
+func UpdateAvatar(ctx *context.APIContext) {
+	// swagger:operation POST /orgs/{org}/avatar organization orgUpdateAvatar
+	// ---
+	// summary: Update Avatar
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: org
+	//   in: path
+	//   description: name of the organization
+	//   type: string
+	//   required: true
+	// - name: body
+	//   in: body
+	//   schema:
+	//     "$ref": "#/definitions/UpdateUserAvatarOption"
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	form := web.GetForm(ctx).(*api.UpdateUserAvatarOption)
+
+	content, err := base64.StdEncoding.DecodeString(form.Image)
+	if err != nil {
+		ctx.Error(http.StatusBadRequest, "DecodeImage", err)
+		return
+	}
+
+	err = user_service.UploadAvatar(ctx.Org.Organization.AsUser(), content)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
+
+// DeleteAvatar deletes the Avatar of an Organisation
+func DeleteAvatar(ctx *context.APIContext) {
+	// swagger:operation DELETE /orgs/{org}/avatar organization orgDeleteAvatar
+	// ---
+	// summary: Delete Avatar
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: org
+	//   in: path
+	//   description: name of the organization
+	//   type: string
+	//   required: true
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	err := user_service.DeleteAvatar(ctx.Org.Organization.AsUser())
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go
new file mode 100644
index 0000000000000..48bd143d0c8a4
--- /dev/null
+++ b/routers/api/v1/repo/avatar.go
@@ -0,0 +1,84 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+import (
+	"encoding/base64"
+	"net/http"
+
+	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/web"
+	repo_service "code.gitea.io/gitea/services/repository"
+)
+
+// UpdateVatar updates the Avatar of an Repo
+func UpdateAvatar(ctx *context.APIContext) {
+	// swagger:operation POST /repos/{owner}/{repo}/avatar repository repoUpdateAvatar
+	// ---
+	// summary: Update avatar
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: owner
+	//   in: path
+	//   description: owner of the repo
+	//   type: string
+	//   required: true
+	// - name: repo
+	//   in: path
+	//   description: name of the repo
+	//   type: string
+	//   required: true
+	// - name: body
+	//   in: body
+	//   schema:
+	//     "$ref": "#/definitions/UpdateRepoAvatarOption"
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	form := web.GetForm(ctx).(*api.UpdateRepoAvatarOption)
+
+	content, err := base64.StdEncoding.DecodeString(form.Image)
+	if err != nil {
+		ctx.Error(http.StatusBadRequest, "DecodeImage", err)
+		return
+	}
+
+	err = repo_service.UploadAvatar(ctx, ctx.Repo.Repository, content)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
+
+// UpdateAvatar deletes the Avatar of an Repo
+func DeleteAvatar(ctx *context.APIContext) {
+	// swagger:operation DELETE /repos/{owner}/{repo}/avatar repository repoDeleteAvatar
+	// ---
+	// summary: Delete avatar
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: owner
+	//   in: path
+	//   description: owner of the repo
+	//   type: string
+	//   required: true
+	// - name: repo
+	//   in: path
+	//   description: name of the repo
+	//   type: string
+	//   required: true
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go
index 353d32e2142ee..073d9a19f7d30 100644
--- a/routers/api/v1/swagger/options.go
+++ b/routers/api/v1/swagger/options.go
@@ -181,4 +181,10 @@ type swaggerParameterBodies struct {
 
 	// in:body
 	CreatePushMirrorOption api.CreatePushMirrorOption
+
+	// in:body
+	UpdateUserAvatarOptions api.UpdateUserAvatarOption
+
+	// in:body
+	UpdateRepoAvatarOptions api.UpdateRepoAvatarOption
 }
diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go
new file mode 100644
index 0000000000000..84fa129b13abc
--- /dev/null
+++ b/routers/api/v1/user/avatar.go
@@ -0,0 +1,63 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package user
+
+import (
+	"encoding/base64"
+	"net/http"
+
+	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/web"
+	user_service "code.gitea.io/gitea/services/user"
+)
+
+// UpdateAvatar updates the Avatar of an User
+func UpdateAvatar(ctx *context.APIContext) {
+	// swagger:operation POST /user/avatar user userUpdateAvatar
+	// ---
+	// summary: Update Avatar
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: body
+	//   in: body
+	//   schema:
+	//     "$ref": "#/definitions/UpdateUserAvatarOption"
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	form := web.GetForm(ctx).(*api.UpdateUserAvatarOption)
+
+	content, err := base64.StdEncoding.DecodeString(form.Image)
+	if err != nil {
+		ctx.Error(http.StatusBadRequest, "DecodeImage", err)
+		return
+	}
+
+	err = user_service.UploadAvatar(ctx.Doer, content)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
+
+// DeleteAvatar deletes the Avatar of an User
+func DeleteAvatar(ctx *context.APIContext) {
+	// swagger:operation DELETE /user/avatar user userDeleteAvatar
+	// ---
+	// summary: Delete Avatar
+	// produces:
+	// - application/json
+	// responses:
+	//   "204":
+	//     "$ref": "#/responses/empty"
+	err := user_service.DeleteAvatar(ctx.Doer)
+	if err != nil {
+		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err)
+	}
+
+	ctx.Status(http.StatusNoContent)
+}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 11abeac77c7af..f98dc12d95cfa 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -1595,6 +1595,63 @@
         }
       }
     },
+    "/orgs/{org}/avatar": {
+      "post": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "organization"
+        ],
+        "summary": "Update Avatar",
+        "operationId": "orgUpdateAvatar",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "name of the organization",
+            "name": "org",
+            "in": "path",
+            "required": true
+          },
+          {
+            "name": "body",
+            "in": "body",
+            "schema": {
+              "$ref": "#/definitions/UpdateUserAvatarOption"
+            }
+          }
+        ],
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      },
+      "delete": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "organization"
+        ],
+        "summary": "Delete Avatar",
+        "operationId": "orgDeleteAvatar",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "name of the organization",
+            "name": "org",
+            "in": "path",
+            "required": true
+          }
+        ],
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      }
+    },
     "/orgs/{org}/hooks": {
       "get": {
         "produces": [
@@ -3174,6 +3231,77 @@
         }
       }
     },
+    "/repos/{owner}/{repo}/avatar": {
+      "post": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "repository"
+        ],
+        "summary": "Update avatar",
+        "operationId": "repoUpdateAvatar",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "owner of the repo",
+            "name": "owner",
+            "in": "path",
+            "required": true
+          },
+          {
+            "type": "string",
+            "description": "name of the repo",
+            "name": "repo",
+            "in": "path",
+            "required": true
+          },
+          {
+            "name": "body",
+            "in": "body",
+            "schema": {
+              "$ref": "#/definitions/UpdateRepoAvatarOption"
+            }
+          }
+        ],
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      },
+      "delete": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "repository"
+        ],
+        "summary": "Delete avatar",
+        "operationId": "repoDeleteAvatar",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "owner of the repo",
+            "name": "owner",
+            "in": "path",
+            "required": true
+          },
+          {
+            "type": "string",
+            "description": "name of the repo",
+            "name": "repo",
+            "in": "path",
+            "required": true
+          }
+        ],
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      }
+    },
     "/repos/{owner}/{repo}/branch_protections": {
       "get": {
         "produces": [
@@ -13787,6 +13915,47 @@
         }
       }
     },
+    "/user/avatar": {
+      "post": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "user"
+        ],
+        "summary": "Update Avatar",
+        "operationId": "userUpdateAvatar",
+        "parameters": [
+          {
+            "name": "body",
+            "in": "body",
+            "schema": {
+              "$ref": "#/definitions/UpdateUserAvatarOption"
+            }
+          }
+        ],
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      },
+      "delete": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "user"
+        ],
+        "summary": "Delete Avatar",
+        "operationId": "userDeleteAvatar",
+        "responses": {
+          "204": {
+            "$ref": "#/responses/empty"
+          }
+        }
+      }
+    },
     "/user/emails": {
       "get": {
         "produces": [
@@ -21548,6 +21717,30 @@
       },
       "x-go-package": "code.gitea.io/gitea/modules/structs"
     },
+    "UpdateRepoAvatarOption": {
+      "description": "UpdateRepoAvatarUserOption options when updating the repo avatar",
+      "type": "object",
+      "properties": {
+        "image": {
+          "description": "image must be base64 encoded",
+          "type": "string",
+          "x-go-name": "Image"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
+    "UpdateUserAvatarOption": {
+      "description": "UpdateUserAvatarUserOption options when updating the user avatar",
+      "type": "object",
+      "properties": {
+        "image": {
+          "description": "image must be base64 encoded",
+          "type": "string",
+          "x-go-name": "Image"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
     "User": {
       "description": "User represents a user",
       "type": "object",
@@ -22837,7 +23030,7 @@
     "parameterBodies": {
       "description": "parameterBodies",
       "schema": {
-        "$ref": "#/definitions/CreatePushMirrorOption"
+        "$ref": "#/definitions/UpdateRepoAvatarOption"
       }
     },
     "redirect": {
diff --git a/tests/integration/api_org_avatar_test.go b/tests/integration/api_org_avatar_test.go
new file mode 100644
index 0000000000000..e0a4150e9f359
--- /dev/null
+++ b/tests/integration/api_org_avatar_test.go
@@ -0,0 +1,72 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"encoding/base64"
+	"net/http"
+	"os"
+	"testing"
+
+	auth_model "code.gitea.io/gitea/models/auth"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAPIUpdateOrgAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	session := loginUser(t, "user1")
+
+	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
+
+	// Test what happens if you use a valid image
+	avatar, err := os.ReadFile("tests/integration/avatar.png")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open avatar.png")
+	}
+
+	opts := api.UpdateUserAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(avatar),
+	}
+
+	req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusNoContent)
+
+	// Test what happens if you don't have a valid Base64 string
+	opts = api.UpdateUserAvatarOption{
+		Image: "Invalid",
+	}
+
+	req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusBadRequest)
+
+	// Test what happens if you use a file that is not an image
+	text, err := os.ReadFile("tests/integration/README.md")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open README.md")
+	}
+
+	opts = api.UpdateUserAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(text),
+	}
+
+	req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusInternalServerError)
+}
+
+func TestAPIDeleteOrgAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	session := loginUser(t, "user1")
+
+	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
+
+	req := NewRequest(t, "DELETE", "/api/v1/orgs/user3/avatar?token="+token)
+	MakeRequest(t, req, http.StatusNoContent)
+}
diff --git a/tests/integration/api_repo_avatar_test.go b/tests/integration/api_repo_avatar_test.go
new file mode 100644
index 0000000000000..58a4fc536c87e
--- /dev/null
+++ b/tests/integration/api_repo_avatar_test.go
@@ -0,0 +1,76 @@
+// Copyright 2018 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"encoding/base64"
+	"fmt"
+	"net/http"
+	"os"
+	"testing"
+
+	auth_model "code.gitea.io/gitea/models/auth"
+	repo_model "code.gitea.io/gitea/models/repo"
+	"code.gitea.io/gitea/models/unittest"
+	user_model "code.gitea.io/gitea/models/user"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAPIUpdateRepoAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+	token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository)
+
+	// Test what happens if you use a valid image
+	avatar, err := os.ReadFile("tests/integration/avatar.png")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open avatar.png")
+	}
+
+	opts := api.UpdateRepoAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(avatar),
+	}
+
+	req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts)
+	MakeRequest(t, req, http.StatusNoContent)
+
+	// Test what happens if you don't have a valid Base64 string
+	opts = api.UpdateRepoAvatarOption{
+		Image: "Invalid",
+	}
+
+	req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts)
+	MakeRequest(t, req, http.StatusBadRequest)
+
+	// Test what happens if you use a file that is not an image
+	text, err := os.ReadFile("tests/integration/README.md")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open README.md")
+	}
+
+	opts = api.UpdateRepoAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(text),
+	}
+
+	req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts)
+	MakeRequest(t, req, http.StatusInternalServerError)
+}
+
+func TestAPIDeleteRepoAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+	token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository)
+
+	req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token))
+	MakeRequest(t, req, http.StatusNoContent)
+}
diff --git a/tests/integration/api_user_avatar_test.go b/tests/integration/api_user_avatar_test.go
new file mode 100644
index 0000000000000..807c119e2c99c
--- /dev/null
+++ b/tests/integration/api_user_avatar_test.go
@@ -0,0 +1,72 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"encoding/base64"
+	"net/http"
+	"os"
+	"testing"
+
+	auth_model "code.gitea.io/gitea/models/auth"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAPIUpdateUserAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	normalUsername := "user2"
+	session := loginUser(t, normalUsername)
+	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
+
+	// Test what happens if you use a valid image
+	avatar, err := os.ReadFile("tests/integration/avatar.png")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open avatar.png")
+	}
+
+	// Test what happens if you don't have a valid Base64 string
+	opts := api.UpdateUserAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(avatar),
+	}
+
+	req := NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusNoContent)
+
+	opts = api.UpdateUserAvatarOption{
+		Image: "Invalid",
+	}
+
+	req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusBadRequest)
+
+	// Test what happens if you use a file that is not an image
+	text, err := os.ReadFile("tests/integration/README.md")
+	assert.NoError(t, err)
+	if err != nil {
+		assert.FailNow(t, "Unable to open README.md")
+	}
+
+	opts = api.UpdateUserAvatarOption{
+		Image: base64.StdEncoding.EncodeToString(text),
+	}
+
+	req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts)
+	MakeRequest(t, req, http.StatusInternalServerError)
+}
+
+func TestAPIDeleteUserAvatar(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	normalUsername := "user2"
+	session := loginUser(t, normalUsername)
+	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
+
+	req := NewRequest(t, "DELETE", "/api/v1/user/avatar?token="+token)
+	MakeRequest(t, req, http.StatusNoContent)
+}
diff --git a/tests/integration/avatar.png b/tests/integration/avatar.png
new file mode 100644
index 0000000000000..dfd2125edc523
Binary files /dev/null and b/tests/integration/avatar.png differ