diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go
index 53d10a990788f..bff10f95b7c55 100644
--- a/modules/structs/miscellaneous.go
+++ b/modules/structs/miscellaneous.go
@@ -72,6 +72,12 @@ type ServerVersion struct {
 	Version string `json:"version"`
 }
 
+// GitignoreTemplateInfo name and text of a gitignore template
+type GitignoreTemplateInfo struct {
+	Name   string `json:"name"`
+	Source string `json:"source"`
+}
+
 // LicensesListEntry is used for the API
 type LicensesTemplateListEntry struct {
 	Key  string `json:"key"`
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 0af095b2bb603..9a733b832f17d 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -719,6 +719,8 @@ func Routes(ctx gocontext.Context) *web.Route {
 		m.Post("/markup", bind(api.MarkupOption{}), misc.Markup)
 		m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
 		m.Post("/markdown/raw", misc.MarkdownRaw)
+		m.Get("/gitignore/templates", misc.ListGitignoresTemplates)
+		m.Get("/gitignore/templates/{name}", misc.GetGitignoreTemplateInfo)
 		m.Get("/licenses", misc.ListLicenseTemplates)
 		m.Get("/licenses/{name}", misc.GetLicenseTemplateInfo)
 		m.Group("/settings", func() {
diff --git a/routers/api/v1/misc/gitignore.go b/routers/api/v1/misc/gitignore.go
new file mode 100644
index 0000000000000..7c7fe4b125fa4
--- /dev/null
+++ b/routers/api/v1/misc/gitignore.go
@@ -0,0 +1,56 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package misc
+
+import (
+	"net/http"
+
+	"code.gitea.io/gitea/modules/context"
+	"code.gitea.io/gitea/modules/options"
+	repo_module "code.gitea.io/gitea/modules/repository"
+	"code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/util"
+)
+
+// Shows a list of all Gitignore templates
+func ListGitignoresTemplates(ctx *context.APIContext) {
+	// swagger:operation GET /gitignore/templates miscellaneous listGitignoresTemplates
+	// ---
+	// summary: Returns a list of all gitignore templates
+	// produces:
+	// - application/json
+	// responses:
+	//   "200":
+	//     "$ref": "#/responses/GitignoreTemplateList"
+	ctx.JSON(http.StatusOK, repo_module.Gitignores)
+}
+
+// SHows information about a gitignore template
+func GetGitignoreTemplateInfo(ctx *context.APIContext) {
+	// swagger:operation GET /gitignore/templates/{name} miscellaneous getGitignoreTemplateInfo
+	// ---
+	// summary: Returns information about a gitignore template
+	// produces:
+	// - application/json
+	// parameters:
+	// - name: name
+	//   in: path
+	//   description: name of the template
+	//   type: string
+	//   required: true
+	// responses:
+	//   "200":
+	//     "$ref": "#/responses/GitignoreTemplateInfo"
+	//   "404":
+	//     "$ref": "#/responses/notFound"
+	name := util.PathJoinRelX(ctx.Params("name"))
+
+	text, err := options.Gitignore(name)
+	if err != nil {
+		ctx.NotFound()
+		return
+	}
+
+	ctx.JSON(http.StatusOK, &structs.GitignoreTemplateInfo{Name: name, Source: string(text)})
+}
diff --git a/routers/api/v1/swagger/misc.go b/routers/api/v1/swagger/misc.go
index 322bad0c1c5e1..5778b659b52be 100644
--- a/routers/api/v1/swagger/misc.go
+++ b/routers/api/v1/swagger/misc.go
@@ -14,6 +14,20 @@ type swaggerResponseServerVersion struct {
 	Body api.ServerVersion `json:"body"`
 }
 
+// GitignoreTemplateList
+// swagger:response GitignoreTemplateList
+type swaggerResponseGitignoreTemplateList struct {
+	// in:body
+	Body []string `json:"body"`
+}
+
+// GitignoreTemplateInfo
+// swagger:response GitignoreTemplateInfo
+type swaggerResponseGitignoreTemplateInfo struct {
+	// in:body
+	Body api.GitignoreTemplateInfo `json:"body"`
+}
+
 // LicenseTemplateList
 // swagger:response LicenseTemplateList
 type swaggerResponseLicensesTemplateList struct {
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 19b5179927aad..2db950b57a706 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -883,6 +883,52 @@
         }
       }
     },
+    "/gitignore/templates": {
+      "get": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "miscellaneous"
+        ],
+        "summary": "Returns a list of all gitignore templates",
+        "operationId": "listGitignoresTemplates",
+        "responses": {
+          "200": {
+            "$ref": "#/responses/GitignoreTemplateList"
+          }
+        }
+      }
+    },
+    "/gitignore/templates/{name}": {
+      "get": {
+        "produces": [
+          "application/json"
+        ],
+        "tags": [
+          "miscellaneous"
+        ],
+        "summary": "Returns information about a gitignore template",
+        "operationId": "getGitignoreTemplateInfo",
+        "parameters": [
+          {
+            "type": "string",
+            "description": "name of the template",
+            "name": "name",
+            "in": "path",
+            "required": true
+          }
+        ],
+        "responses": {
+          "200": {
+            "$ref": "#/responses/GitignoreTemplateInfo"
+          },
+          "404": {
+            "$ref": "#/responses/notFound"
+          }
+        }
+      }
+    },
     "/licenses": {
       "get": {
         "produces": [
@@ -18342,6 +18388,21 @@
       },
       "x-go-package": "code.gitea.io/gitea/modules/structs"
     },
+    "GitignoreTemplateInfo": {
+      "description": "GitignoreTemplateInfo name and text of a gitignore template",
+      "type": "object",
+      "properties": {
+        "name": {
+          "type": "string",
+          "x-go-name": "Name"
+        },
+        "source": {
+          "type": "string",
+          "x-go-name": "Source"
+        }
+      },
+      "x-go-package": "code.gitea.io/gitea/modules/structs"
+    },
     "Hook": {
       "description": "Hook a hook is a web hook when one repository changed",
       "type": "object",
@@ -21614,6 +21675,21 @@
         "$ref": "#/definitions/GitTreeResponse"
       }
     },
+    "GitignoreTemplateInfo": {
+      "description": "GitignoreTemplateInfo",
+      "schema": {
+        "$ref": "#/definitions/GitignoreTemplateInfo"
+      }
+    },
+    "GitignoreTemplateList": {
+      "description": "GitignoreTemplateList",
+      "schema": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      }
+    },
     "Hook": {
       "description": "Hook",
       "schema": {
diff --git a/tests/integration/api_gitignore_templates_test.go b/tests/integration/api_gitignore_templates_test.go
new file mode 100644
index 0000000000000..c58f5eebfeaa7
--- /dev/null
+++ b/tests/integration/api_gitignore_templates_test.go
@@ -0,0 +1,53 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package integration
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"code.gitea.io/gitea/modules/options"
+	repo_module "code.gitea.io/gitea/modules/repository"
+	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/tests"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAPIListGitignoresTemplates(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	req := NewRequest(t, "GET", "/api/v1/gitignore/templates")
+	resp := MakeRequest(t, req, http.StatusOK)
+
+	// This tests if the API returns a list of strings
+	var gitignoreList []string
+	DecodeJSON(t, resp, &gitignoreList)
+}
+
+func TestAPIGetGitignoreTemplateInfo(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	// If Gitea has for some reason no Gitignore templates, we need to skip this test
+	if len(repo_module.Gitignores) == 0 {
+		return
+	}
+
+	// Use the first template for the test
+	templateName := repo_module.Gitignores[0]
+
+	urlStr := fmt.Sprintf("/api/v1/gitignore/templates/%s", templateName)
+	req := NewRequest(t, "GET", urlStr)
+	resp := MakeRequest(t, req, http.StatusOK)
+
+	var templateInfo api.GitignoreTemplateInfo
+	DecodeJSON(t, resp, &templateInfo)
+
+	// We get the text of the template here
+	text, _ := options.Gitignore(templateName)
+
+	assert.Equal(t, templateInfo.Name, templateName)
+	assert.Equal(t, templateInfo.Source, string(text))
+}