diff --git a/CHANGES b/CHANGES
index b2b740924adef63efb38792bdff8823a4fc74bce..f367f46cfea788d731a78a7a812c7293f68d3d42 100644
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,17 @@ chan_sip
    headers be retrieved from the REFER message and made accessible to the
    dialplan in the hash TRANSFER_DATA.
 
+AMI
+------------------
+ * The ContactStatus and Status fields for the manager events ContactStatus
+   and ContactStatusDetail are now set to "NonQualified" when a contact exists
+   but has not been qualified.
+
+ARI
+------------------
+ * The ContactInfo event's contact_status field is now set to "NonQualified"
+   when a contact exists but has not been qualified.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 15.1.0 to Asterisk 15.2.0 ------------
 ------------------------------------------------------------------------------
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 39c0f8cec85fa3bf15a7ab2f635053f6c4eb05e7..dd37b259df5ea1d599fe9698b5495b22396e9e59 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -31,6 +31,15 @@ app_macro:
    built.  Users should migrate to app_stack (Gosub).  A warning is logged
    the first time any Macro is used.
 
+AMI:
+ - The ContactStatus and Status fields for the manager events ContactStatus
+   and ContactStatusDetail are now set to "NonQualified" when a contact exists
+   but has not been qualified.
+
+ARI:
+ - The ContactInfo event's contact_status field is now set to "NonQualified"
+   when a contact exists but has not been qualified.
+
 New in 15.0.0:
 
 Build System:
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index e71eb98d79e74422e56a242e1025a97e6f1f541e..6c48d2e849f0955a5e50265f35cc7a4fde6e8319 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -289,9 +289,13 @@ struct ast_sip_contact {
  * \brief Status type for a contact.
  */
 enum ast_sip_contact_status_type {
+	/*! Frequency > 0, but no response from remote uri */
 	UNAVAILABLE,
+	/*! Frequency > 0, and got response from remote uri */
 	AVAILABLE,
+	/*! Default last status, and when a contact status object is not found */
 	UNKNOWN,
+	/*! Frequency == 0, has a contact, but don't know status (non-qualified) */
 	CREATED,
 	REMOVED,
 };
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index 161fdfa449f78704215a9c6d73919aeee0f8fd68..5cee22ebad5a205c87ba54bfde0ca821d0cf7397 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -82,7 +82,7 @@
 						<enum name="Unknown"/>
 						<enum name="Unreachable"/>
 						<enum name="Reachable"/>
-						<enum name="Created"/>
+						<enum name="Unqualified"/>
 						<enum name="Removed"/>
 						<enum name="Updated"/>
 					</enumlist>
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 21e43f0736e642931a7c00a6397efcf8a3dfbf40..b50ee5fc77e043faac1c7c27294652667cd4a1ab 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -2282,6 +2282,7 @@
 					<enumlist>
 						<enum name="Reachable"/>
 						<enum name="Unreachable"/>
+						<enum name="NonQualified"/>
 					</enumlist>
 				</parameter>
 				<parameter name="RoundtripUsec">
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index fbe07d53ddcad843b9e22fd7208766d8ab5414c4..f9df2f0a58c633581bd2b0288d3e5dd4aec4b259 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -41,7 +41,7 @@ static const char *status_map [] = {
 	[UNAVAILABLE] = "Unreachable",
 	[AVAILABLE] = "Reachable",
 	[UNKNOWN] = "Unknown",
-	[CREATED] = "Created",
+	[CREATED] = "NonQualified",
 	[REMOVED] = "Removed",
 };
 
@@ -49,7 +49,7 @@ static const char *short_status_map [] = {
 	[UNAVAILABLE] = "Unavail",
 	[AVAILABLE] = "Avail",
 	[UNKNOWN] = "Unknown",
-	[CREATED] = "Created",
+	[CREATED] = "NonQual",
 	[REMOVED] = "Removed",
 };
 
@@ -205,24 +205,12 @@ static void update_contact_status(const struct ast_sip_contact *contact,
 		return;
 	}
 
-	if (is_contact_refresh
-		&& status->status == CREATED) {
-		/*
-		 * The contact status hasn't been updated since creation
-		 * and we don't want to re-send a created status.
-		 */
-		if (contact->qualify_frequency
-			|| status->rtt_start.tv_sec > 0) {
-			/* Ignore, the status will change soon. */
-			return;
-		}
-
-		/*
-		 * Convert to a regular contact status update
-		 * because the status may never change.
-		 */
-		is_contact_refresh = 0;
-		value = UNKNOWN;
+	/*
+	 * If the current status is CREATED, and it's a refresh or the given value is
+	 * also CREATED then there is nothing to update as nothing needs to change.
+	 */
+	if (status->status == CREATED && (is_contact_refresh || status->status == value)) {
+		return;
 	}
 
 	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
@@ -595,7 +583,7 @@ static void qualify_and_schedule(struct ast_sip_contact *contact)
 
 		schedule_qualify(contact, contact->qualify_frequency * 1000);
 	} else {
-		update_contact_status(contact, UNKNOWN, 0);
+		update_contact_status(contact, CREATED, 0);
 	}
 }
 
@@ -1127,7 +1115,7 @@ static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
 	if (contact->qualify_frequency) {
 		schedule_qualify(contact, initial_interval);
 	} else {
-		update_contact_status(contact, UNKNOWN, 0);
+		update_contact_status(contact, CREATED, 0);
 	}
 }
 
diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json
index 9ebbac061f848fe022f64e7ada59d74a0d16b210..e1b31bb9764647992ace61d8c8f380785625db94 100644
--- a/rest-api/api-docs/events.json
+++ b/rest-api/api-docs/events.json
@@ -207,7 +207,7 @@
 							"Unreachable",
 							"Reachable",
 							"Unknown",
-							"Created",
+							"NonQualified",
 							"Removed"
 						]
 					}