diff --git a/app/models/issue.rb b/app/models/issue.rb
index 91d4b78f7c88f2ddc9b6f418317c676426061fc9..5c91656cbc025107589dc8e5ec776eb2c6e7c154 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -135,7 +135,7 @@ def most_recent
   scope :with_prometheus_alert_events, -> { joins(:issues_prometheus_alert_events) }
   scope :with_self_managed_prometheus_alert_events, -> { joins(:issues_self_managed_prometheus_alert_events) }
   scope :with_api_entity_associations, -> {
-    preload(:timelogs, :closed_by, :assignees, :author, :labels,
+    preload(:timelogs, :closed_by, :assignees, :author, :labels, :issuable_severity,
       milestone: { project: [:route, { namespace: :route }] },
       project: [:route, { namespace: :route }])
   }
diff --git a/doc/api/issues.md b/doc/api/issues.md
index ef0727e1c135d9f3039ca2502c1960c3f9047389..e82aa8da8ede932123adf1dae8c6f6a3ccf9d2a5 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -165,6 +165,7 @@ Example response:
       "confidential": false,
       "discussion_locked": false,
       "issue_type": "issue",
+      "severity": "UNKNOWN",
       "_links":{
          "self":"http://gitlab.example.com/api/v4/projects/1/issues/76",
          "notes":"http://gitlab.example.com/api/v4/projects/1/issues/76/notes",
@@ -390,6 +391,7 @@ Example response:
       "confidential": false,
       "discussion_locked": false,
       "issue_type": "issue",
+      "severity": "UNKNOWN",
       "_links":{
          "self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
          "notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
@@ -598,6 +600,7 @@ Example response:
       "confidential": false,
       "discussion_locked": false,
       "issue_type": "issue",
+      "severity": "UNKNOWN",
       "_links":{
          "self":"http://gitlab.example.com/api/v4/projects/4/issues/41",
          "notes":"http://gitlab.example.com/api/v4/projects/4/issues/41/notes",
@@ -755,6 +758,7 @@ Example response:
   "confidential": false,
   "discussion_locked": false,
   "issue_type": "issue",
+  "severity": "UNKNOWN",
   "task_completion_status": {
     "count": 0,
     "completed_count": 0
@@ -917,6 +921,7 @@ Example response:
    "confidential": false,
    "discussion_locked": false,
    "issue_type": "issue",
+   "severity": "UNKNOWN",
    "_links": {
       "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
       "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1064,6 +1069,7 @@ Example response:
    "confidential": false,
    "discussion_locked": false,
    "issue_type": "issue",
+   "severity": "UNKNOWN",
    "_links": {
       "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
       "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1238,6 +1244,7 @@ Example response:
    "confidential": false,
    "discussion_locked": false,
    "issue_type": "issue",
+   "severity": "UNKNOWN",
    "_links": {
       "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
       "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1421,6 +1428,7 @@ Example response:
   "confidential": false,
   "discussion_locked": false,
   "issue_type": "issue",
+  "severity": "UNKNOWN",
   "_links": {
     "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
     "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1560,6 +1568,7 @@ Example response:
   "confidential":false,
   "discussion_locked":null,
   "issue_type":"issue",
+  "severity": "UNKNOWN",
   "web_url":"https://gitlab.example.com/namespace1/project2/-/issues/1",
   "time_stats":{
     "time_estimate":0,
@@ -1669,6 +1678,7 @@ Example response:
   "confidential": false,
   "discussion_locked": false,
   "issue_type": "issue",
+  "severity": "UNKNOWN",
   "_links": {
     "self": "http://gitlab.example.com/api/v4/projects/1/issues/2",
     "notes": "http://gitlab.example.com/api/v4/projects/1/issues/2/notes",
@@ -1797,6 +1807,7 @@ Example response:
   "confidential": false,
   "discussion_locked": false,
   "issue_type": "issue",
+  "severity": "UNKNOWN",
   "task_completion_status":{
      "count":0,
      "completed_count":0
@@ -1906,6 +1917,7 @@ Example response:
     "confidential": false,
     "discussion_locked": false,
     "issue_type": "issue",
+    "severity": "UNKNOWN",
     "task_completion_status":{
        "count":0,
        "completed_count":0
diff --git a/lib/api/entities/issue.rb b/lib/api/entities/issue.rb
index e2506cc596e253fc6088496630cfc94e1799d498..f87ef093cd8bab8917d3888085272d2cea9e9cd4 100644
--- a/lib/api/entities/issue.rb
+++ b/lib/api/entities/issue.rb
@@ -35,6 +35,10 @@ class Issue < IssueBasic
         issue
       end
 
+      expose :severity,
+             format_with: :upcase,
+             documentation: { type: "String", desc: "One of #{::IssuableSeverity.severities.keys.map(&:upcase)}" }
+
       # Calculating the value of subscribed field triggers Markdown
       # processing. We can't do that for multiple issues / merge
       # requests in a single API request.
diff --git a/spec/fixtures/api/schemas/public_api/v4/issue.json b/spec/fixtures/api/schemas/public_api/v4/issue.json
index 3173a8ebfb5eca11c8ccf1d15840eeda695098c4..90b368b52267b5ac64a60fb24905c69041dbe2c9 100644
--- a/spec/fixtures/api/schemas/public_api/v4/issue.json
+++ b/spec/fixtures/api/schemas/public_api/v4/issue.json
@@ -86,6 +86,7 @@
     "due_date": { "type": ["string", "null"] },
     "confidential": { "type": "boolean" },
     "web_url": { "type": "uri" },
+    "severity": { "type": "string", "enum": ["UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"] },
     "time_stats": {
       "time_estimate": { "type": "integer" },
       "total_time_spent": { "type": "integer" },
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index c5e57b5b18b0e421fd32ef98fc2affdecd71e820..1419d39981ac0157f475be49ed5916e0a7d1d76f 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -554,6 +554,27 @@
         end
       end
 
+      context 'with incident issues' do
+        let_it_be(:incident) { create(:incident, project: project) }
+
+        it 'avoids N+1 queries' do
+          get api('/issues', user) # warm up
+
+          control = ActiveRecord::QueryRecorder.new do
+            get api('/issues', user)
+          end
+
+          create(:incident, project: project)
+          create(:incident, project: project)
+
+          expect do
+            get api('/issues', user)
+          end.not_to exceed_query_limit(control)
+          # 2 pre-existed issues + 3 incidents
+          expect(json_response.count).to eq(5)
+        end
+      end
+
       context 'filter by labels or label_name param' do
         context 'N+1' do
           let(:label_b) { create(:label, title: 'foo', project: project) }