diff --git a/src/or/control.c b/src/or/control.c
index d237f8feb1e0715ebde900a244853f70f9bcc812..fb74d7d6f3199447f3da35c76daaf9a08ef9fefe 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -6233,6 +6233,27 @@ get_desc_id_from_query(const rend_data_t *rend_data, const char *hsdir_fp)
   return desc_id;
 }
 
+/** send HS_DESC CREATED event when a local service generates a descriptor.
+ *
+ * <b>service_id</b> is the descriptor onion address.
+ * <b>desc_id_base32</b> is the descriptor ID.
+ */
+void
+control_event_hs_descriptor_created(const char *service_id,
+                                    const char *desc_id_base32)
+{
+  if (!service_id || !desc_id_base32) {
+    log_warn(LD_BUG, "Called with service_digest==%p, "
+             "desc_id_base32==%p", service_id, desc_id_base32);
+    return;
+  }
+
+  send_control_event(EVENT_HS_DESC,
+                     "650 HS_DESC CREATED %s UNKNOWN UNKNOWN %s\r\n",
+                     service_id,
+                     desc_id_base32);
+}
+
 /** send HS_DESC upload event.
  *
  * <b>service_id</b> is the descriptor onion address.
diff --git a/src/or/control.h b/src/or/control.h
index fdf7903cb8bb9c35579238bf8995ec048ecfa31c..26f7f50b881bb0dd8ff528d21b9eea628e2024ae 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -117,6 +117,8 @@ MOCK_DECL(const char *, node_describe_longname_by_id,(const char *id_digest));
 void control_event_hs_descriptor_requested(const rend_data_t *rend_query,
                                            const char *desc_id_base32,
                                            const char *hs_dir);
+void control_event_hs_descriptor_created(const char *service_id,
+                                         const char *desc_id_base32);
 void control_event_hs_descriptor_upload(const char *service_id,
                                         const char *desc_id_base32,
                                         const char *hs_dir);