This is an automated email from the ASF dual-hosted git repository.

weilee pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new bfc0f894046 Add HITLDetail.created_at (#55525)
bfc0f894046 is described below

commit bfc0f8940461eae3b85196e82818c6b9d4bbe376
Author: Wei Lee <[email protected]>
AuthorDate: Tue Sep 16 17:59:51 2025 +0800

    Add HITLDetail.created_at (#55525)
---
 airflow-core/docs/img/airflow_erd.sha256           |   2 +-
 airflow-core/docs/img/airflow_erd.svg              | 121 +++++++++++----------
 .../api_fastapi/core_api/datamodels/hitl.py        |   1 +
 .../api_fastapi/core_api/openapi/_private_ui.yaml  |   5 +
 .../core_api/openapi/v2-rest-api-generated.yaml    |  41 +++++++
 .../api_fastapi/core_api/routes/public/hitl.py     |   5 +
 .../0076_3_1_0_add_human_in_the_loop_response.py   |   2 +
 airflow-core/src/airflow/models/hitl.py            |   2 +
 .../src/airflow/ui/openapi-gen/queries/common.ts   |   8 +-
 .../ui/openapi-gen/queries/ensureQueryData.ts      |  12 +-
 .../src/airflow/ui/openapi-gen/queries/prefetch.ts |  12 +-
 .../src/airflow/ui/openapi-gen/queries/queries.ts  |  12 +-
 .../src/airflow/ui/openapi-gen/queries/suspense.ts |  12 +-
 .../airflow/ui/openapi-gen/requests/schemas.gen.ts |   7 +-
 .../ui/openapi-gen/requests/services.gen.ts        |  10 +-
 .../airflow/ui/openapi-gen/requests/types.gen.ts   |   5 +
 .../core_api/routes/public/test_hitl.py            |  34 +++++-
 .../api_fastapi/core_api/routes/ui/test_dags.py    |   1 +
 .../src/airflowctl/api/datamodels/generated.py     |   1 +
 19 files changed, 220 insertions(+), 73 deletions(-)

diff --git a/airflow-core/docs/img/airflow_erd.sha256 
b/airflow-core/docs/img/airflow_erd.sha256
index ba060d4f5ee..bf88ae1d3c4 100644
--- a/airflow-core/docs/img/airflow_erd.sha256
+++ b/airflow-core/docs/img/airflow_erd.sha256
@@ -1 +1 @@
-35e9e07930e138664fb6ff23bc299567a88946734630d84f3d7d95deacf2f4b8
\ No newline at end of file
+35b8a7f30e44075373199a53e6634693f4254287a9ecff0582d9ae926fc7aaae
\ No newline at end of file
diff --git a/airflow-core/docs/img/airflow_erd.svg 
b/airflow-core/docs/img/airflow_erd.svg
index 6fbf9c224a4..c6fc5f0ea7d 100644
--- a/airflow-core/docs/img/airflow_erd.svg
+++ b/airflow-core/docs/img/airflow_erd.svg
@@ -1437,68 +1437,73 @@
 <!-- hitl_detail -->
 <g id="node43" class="node">
 <title>hitl_detail</title>
-<polygon fill="none" stroke="black" points="2197,-2304 2197,-2332 2435,-2332 
2435,-2304 2197,-2304"/>
-<text text-anchor="start" x="2272" y="-2315.2" 
font-family="Helvetica,sans-Serif" font-weight="bold" 
font-size="16.00">hitl_detail</text>
-<polygon fill="none" stroke="black" points="2197,-2279 2197,-2304 2435,-2304 
2435,-2279 2197,-2279"/>
-<text text-anchor="start" x="2202" y="-2288.8" 
font-family="Helvetica,sans-Serif" text-decoration="underline" 
font-size="14.00">ti_id</text>
-<text text-anchor="start" x="2231" y="-2288.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2236" y="-2288.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [UUID]</text>
-<text text-anchor="start" x="2288" y="-2288.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
-<polygon fill="none" stroke="black" points="2197,-2254 2197,-2279 2435,-2279 
2435,-2254 2197,-2254"/>
-<text text-anchor="start" x="2202" y="-2263.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">assignees</text>
-<text text-anchor="start" x="2272" y="-2263.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2277" y="-2263.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<polygon fill="none" stroke="black" points="2197,-2229 2197,-2254 2435,-2254 
2435,-2229 2197,-2229"/>
-<text text-anchor="start" x="2202" y="-2238.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">body</text>
-<text text-anchor="start" x="2237" y="-2238.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2242" y="-2238.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TEXT]</text>
-<polygon fill="none" stroke="black" points="2197,-2204 2197,-2229 2435,-2229 
2435,-2204 2197,-2204"/>
-<text text-anchor="start" x="2202" y="-2213.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">chosen_options</text>
-<text text-anchor="start" x="2310" y="-2213.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2315" y="-2213.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<polygon fill="none" stroke="black" points="2197,-2179 2197,-2204 2435,-2204 
2435,-2179 2197,-2179"/>
-<text text-anchor="start" x="2202" y="-2188.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">defaults</text>
-<text text-anchor="start" x="2259" y="-2188.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2264" y="-2188.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<polygon fill="none" stroke="black" points="2197,-2154 2197,-2179 2435,-2179 
2435,-2154 2197,-2154"/>
-<text text-anchor="start" x="2202" y="-2163.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">multiple</text>
-<text text-anchor="start" x="2259" y="-2163.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2264" y="-2163.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [BOOLEAN]</text>
-<polygon fill="none" stroke="black" points="2197,-2129 2197,-2154 2435,-2154 
2435,-2129 2197,-2129"/>
-<text text-anchor="start" x="2202" y="-2138.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">options</text>
-<text text-anchor="start" x="2254" y="-2138.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2259" y="-2138.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<text text-anchor="start" x="2310" y="-2138.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
-<polygon fill="none" stroke="black" points="2197,-2104 2197,-2129 2435,-2129 
2435,-2104 2197,-2104"/>
-<text text-anchor="start" x="2202" y="-2113.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">params</text>
-<text text-anchor="start" x="2255" y="-2113.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2260" y="-2113.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<text text-anchor="start" x="2311" y="-2113.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
-<polygon fill="none" stroke="black" points="2197,-2079 2197,-2104 2435,-2104 
2435,-2079 2197,-2079"/>
-<text text-anchor="start" x="2202" y="-2088.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">params_input</text>
-<text text-anchor="start" x="2298" y="-2088.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2303" y="-2088.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<text text-anchor="start" x="2354" y="-2088.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
-<polygon fill="none" stroke="black" points="2197,-2054 2197,-2079 2435,-2079 
2435,-2054 2197,-2054"/>
-<text text-anchor="start" x="2202" y="-2063.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">responded_at</text>
-<text text-anchor="start" x="2296" y="-2063.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2301" y="-2063.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text>
-<polygon fill="none" stroke="black" points="2197,-2029 2197,-2054 2435,-2054 
2435,-2029 2197,-2029"/>
-<text text-anchor="start" x="2202" y="-2038.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">responded_by</text>
-<text text-anchor="start" x="2300" y="-2038.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2305" y="-2038.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
-<polygon fill="none" stroke="black" points="2197,-2004 2197,-2029 2435,-2029 
2435,-2004 2197,-2004"/>
-<text text-anchor="start" x="2202" y="-2013.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">subject</text>
-<text text-anchor="start" x="2253" y="-2013.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
-<text text-anchor="start" x="2258" y="-2013.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TEXT]</text>
-<text text-anchor="start" x="2308" y="-2013.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2328 2186,-2356 2446,-2356 
2446,-2328 2186,-2328"/>
+<text text-anchor="start" x="2272" y="-2339.2" 
font-family="Helvetica,sans-Serif" font-weight="bold" 
font-size="16.00">hitl_detail</text>
+<polygon fill="none" stroke="black" points="2186,-2303 2186,-2328 2446,-2328 
2446,-2303 2186,-2303"/>
+<text text-anchor="start" x="2191" y="-2312.8" 
font-family="Helvetica,sans-Serif" text-decoration="underline" 
font-size="14.00">ti_id</text>
+<text text-anchor="start" x="2220" y="-2312.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2225" y="-2312.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [UUID]</text>
+<text text-anchor="start" x="2277" y="-2312.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2278 2186,-2303 2446,-2303 
2446,-2278 2186,-2278"/>
+<text text-anchor="start" x="2191" y="-2287.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">assignees</text>
+<text text-anchor="start" x="2261" y="-2287.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2266" y="-2287.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<polygon fill="none" stroke="black" points="2186,-2253 2186,-2278 2446,-2278 
2446,-2253 2186,-2253"/>
+<text text-anchor="start" x="2191" y="-2262.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">body</text>
+<text text-anchor="start" x="2226" y="-2262.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2231" y="-2262.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TEXT]</text>
+<polygon fill="none" stroke="black" points="2186,-2228 2186,-2253 2446,-2253 
2446,-2228 2186,-2228"/>
+<text text-anchor="start" x="2191" y="-2237.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">chosen_options</text>
+<text text-anchor="start" x="2299" y="-2237.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2304" y="-2237.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<polygon fill="none" stroke="black" points="2186,-2203 2186,-2228 2446,-2228 
2446,-2203 2186,-2203"/>
+<text text-anchor="start" x="2191" y="-2212.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">created_at</text>
+<text text-anchor="start" x="2264" y="-2212.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2269" y="-2212.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text>
+<text text-anchor="start" x="2365" y="-2212.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2178 2186,-2203 2446,-2203 
2446,-2178 2186,-2178"/>
+<text text-anchor="start" x="2191" y="-2187.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">defaults</text>
+<text text-anchor="start" x="2248" y="-2187.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2253" y="-2187.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<polygon fill="none" stroke="black" points="2186,-2153 2186,-2178 2446,-2178 
2446,-2153 2186,-2153"/>
+<text text-anchor="start" x="2191" y="-2162.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">multiple</text>
+<text text-anchor="start" x="2248" y="-2162.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2253" y="-2162.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [BOOLEAN]</text>
+<polygon fill="none" stroke="black" points="2186,-2128 2186,-2153 2446,-2153 
2446,-2128 2186,-2128"/>
+<text text-anchor="start" x="2191" y="-2137.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">options</text>
+<text text-anchor="start" x="2243" y="-2137.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2248" y="-2137.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<text text-anchor="start" x="2299" y="-2137.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2103 2186,-2128 2446,-2128 
2446,-2103 2186,-2103"/>
+<text text-anchor="start" x="2191" y="-2112.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">params</text>
+<text text-anchor="start" x="2244" y="-2112.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2249" y="-2112.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<text text-anchor="start" x="2300" y="-2112.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2078 2186,-2103 2446,-2103 
2446,-2078 2186,-2078"/>
+<text text-anchor="start" x="2191" y="-2087.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">params_input</text>
+<text text-anchor="start" x="2287" y="-2087.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2292" y="-2087.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<text text-anchor="start" x="2343" y="-2087.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
+<polygon fill="none" stroke="black" points="2186,-2053 2186,-2078 2446,-2078 
2446,-2053 2186,-2053"/>
+<text text-anchor="start" x="2191" y="-2062.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">responded_at</text>
+<text text-anchor="start" x="2285" y="-2062.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2290" y="-2062.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TIMESTAMP]</text>
+<polygon fill="none" stroke="black" points="2186,-2028 2186,-2053 2446,-2053 
2446,-2028 2186,-2028"/>
+<text text-anchor="start" x="2191" y="-2037.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">responded_by</text>
+<text text-anchor="start" x="2289" y="-2037.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2294" y="-2037.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [JSON]</text>
+<polygon fill="none" stroke="black" points="2186,-2003 2186,-2028 2446,-2028 
2446,-2003 2186,-2003"/>
+<text text-anchor="start" x="2191" y="-2012.8" 
font-family="Helvetica,sans-Serif" font-size="14.00">subject</text>
+<text text-anchor="start" x="2242" y="-2012.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
+<text text-anchor="start" x="2247" y="-2012.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> [TEXT]</text>
+<text text-anchor="start" x="2297" y="-2012.8" 
font-family="Helvetica,sans-Serif" font-size="14.00"> NOT NULL</text>
 </g>
 <!-- task_instance&#45;&#45;hitl_detail -->
 <g id="edge48" class="edge">
 <title>task_instance&#45;&#45;hitl_detail</title>
-<path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" 
d="M2081.05,-1862.88C2103.53,-1907.23 2127.94,-1950.81 2154,-1991 
2164.45,-2007.12 2176.38,-2023.19 2188.91,-2038.71"/>
-<text text-anchor="start" x="2178.91" y="-2027.51" font-family="Times,serif" 
font-size="14.00">1</text>
-<text text-anchor="start" x="2081.05" y="-1851.68" font-family="Times,serif" 
font-size="14.00">1</text>
+<path fill="none" stroke="#7f7f7f" stroke-dasharray="5,2" 
d="M2081.12,-1859.57C2103.71,-1904.92 2128.13,-1949.64 2154,-1991 
2161.37,-2002.79 2169.44,-2014.6 2177.92,-2026.25"/>
+<text text-anchor="start" x="2167.92" y="-2015.05" font-family="Times,serif" 
font-size="14.00">1</text>
+<text text-anchor="start" x="2081.12" y="-1848.37" font-family="Times,serif" 
font-size="14.00">1</text>
 </g>
 <!-- task_map -->
 <g id="node44" class="node">
diff --git a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py 
b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py
index f24688c13e5..aa4f44f212b 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/datamodels/hitl.py
@@ -63,6 +63,7 @@ class HITLDetail(BaseModel):
     multiple: bool = False
     params: dict[str, Any] = Field(default_factory=dict)
     assigned_users: list[HITLUser] = Field(default_factory=list)
+    created_at: datetime
 
     # Response Content Detail
     responded_by_user: HITLUser | None = None
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml 
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
index 269f60cd4c3..ec079113922 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
+++ b/airflow-core/src/airflow/api_fastapi/core_api/openapi/_private_ui.yaml
@@ -1999,6 +1999,10 @@ components:
             $ref: '#/components/schemas/HITLUser'
           type: array
           title: Assigned Users
+        created_at:
+          type: string
+          format: date-time
+          title: Created At
         responded_by_user:
           anyOf:
           - $ref: '#/components/schemas/HITLUser'
@@ -2029,6 +2033,7 @@ components:
       - task_instance
       - options
       - subject
+      - created_at
       title: HITLDetail
       description: Schema for Human-in-the-loop detail.
     HITLUser:
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
 
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
index 01b8ced149e..95fa0fcda54 100644
--- 
a/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
+++ 
b/airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml
@@ -8264,6 +8264,42 @@ paths:
           title: Body Search
         description: "SQL LIKE expression \u2014 use `%` / `_` wildcards (e.g. 
`%customer_%`).\
           \ Regular expressions are **not** supported."
+      - name: created_at_gte
+        in: query
+        required: false
+        schema:
+          anyOf:
+          - type: string
+            format: date-time
+          - type: 'null'
+          title: Created At Gte
+      - name: created_at_gt
+        in: query
+        required: false
+        schema:
+          anyOf:
+          - type: string
+            format: date-time
+          - type: 'null'
+          title: Created At Gt
+      - name: created_at_lte
+        in: query
+        required: false
+        schema:
+          anyOf:
+          - type: string
+            format: date-time
+          - type: 'null'
+          title: Created At Lte
+      - name: created_at_lt
+        in: query
+        required: false
+        schema:
+          anyOf:
+          - type: string
+            format: date-time
+          - type: 'null'
+          title: Created At Lt
       responses:
         '200':
           description: Successful Response
@@ -10885,6 +10921,10 @@ components:
             $ref: '#/components/schemas/HITLUser'
           type: array
           title: Assigned Users
+        created_at:
+          type: string
+          format: date-time
+          title: Created At
         responded_by_user:
           anyOf:
           - $ref: '#/components/schemas/HITLUser'
@@ -10915,6 +10955,7 @@ components:
       - task_instance
       - options
       - subject
+      - created_at
       title: HITLDetail
       description: Schema for Human-in-the-loop detail.
     HITLDetailCollection:
diff --git 
a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py 
b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py
index 60d9f99fab9..f4b1e0baae2 100644
--- a/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py
+++ b/airflow-core/src/airflow/api_fastapi/core_api/routes/public/hitl.py
@@ -38,7 +38,9 @@ from airflow.api_fastapi.common.parameters import (
     QueryLimit,
     QueryOffset,
     QueryTIStateFilter,
+    RangeFilter,
     SortParam,
+    datetime_range_filter_factory,
 )
 from airflow.api_fastapi.common.router import AirflowRouter
 from airflow.api_fastapi.core_api.datamodels.hitl import (
@@ -209,6 +211,7 @@ def get_hitl_details(
                     "ti_id",
                     "subject",
                     "responded_at",
+                    "created_at",
                 ],
                 model=HITLDetailModel,
                 to_replace={
@@ -234,6 +237,7 @@ def get_hitl_details(
     responded_user_name: QueryHITLDetailRespondedUserNameFilter,
     subject_patten: QueryHITLDetailSubjectSearch,
     body_patten: QueryHITLDetailBodySearch,
+    created_at: Annotated[RangeFilter, 
Depends(datetime_range_filter_factory("created_at", HITLDetailModel))],
 ) -> HITLDetailCollection:
     """Get Human-in-the-loop details."""
     query = (
@@ -265,6 +269,7 @@ def get_hitl_details(
             responded_user_name,
             subject_patten,
             body_patten,
+            created_at,
         ],
         offset=offset,
         limit=limit,
diff --git 
a/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py
 
b/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py
index cd875711ca4..3105d453e45 100644
--- 
a/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py
+++ 
b/airflow-core/src/airflow/migrations/versions/0076_3_1_0_add_human_in_the_loop_response.py
@@ -32,6 +32,7 @@ from alembic import op
 from sqlalchemy import Boolean, Column, ForeignKeyConstraint, String, Text
 from sqlalchemy.dialects import postgresql
 
+from airflow._shared.timezones import timezone
 from airflow.settings import json
 from airflow.utils.sqlalchemy import UtcDateTime
 
@@ -60,6 +61,7 @@ def upgrade():
         Column("multiple", Boolean, unique=False, default=False),
         Column("params", sqlalchemy_jsonfield.JSONField(json=json), 
nullable=False, default={}),
         Column("assignees", sqlalchemy_jsonfield.JSONField(json=json), 
nullable=True),
+        Column("created_at", UtcDateTime(timezone=True), nullable=False, 
default=timezone.utcnow),
         Column("responded_at", UtcDateTime, nullable=True),
         Column("responded_by", sqlalchemy_jsonfield.JSONField(json=json), 
nullable=True),
         Column("chosen_options", sqlalchemy_jsonfield.JSONField(json=json), 
nullable=True),
diff --git a/airflow-core/src/airflow/models/hitl.py 
b/airflow-core/src/airflow/models/hitl.py
index f13c4a6117f..b6bbb2bc402 100644
--- a/airflow-core/src/airflow/models/hitl.py
+++ b/airflow-core/src/airflow/models/hitl.py
@@ -26,6 +26,7 @@ from sqlalchemy.ext.hybrid import hybrid_property
 from sqlalchemy.orm import relationship
 from sqlalchemy.sql.functions import FunctionElement
 
+from airflow._shared.timezones import timezone
 from airflow.models.base import Base
 from airflow.settings import json
 from airflow.utils.sqlalchemy import UtcDateTime
@@ -97,6 +98,7 @@ class HITLDetail(Base):
     multiple = Column(Boolean, unique=False, default=False)
     params = Column(sqlalchemy_jsonfield.JSONField(json=json), nullable=False, 
default={})
     assignees = Column(sqlalchemy_jsonfield.JSONField(json=json), 
nullable=True)
+    created_at = Column(UtcDateTime, default=timezone.utcnow, nullable=False)
 
     # Response Content Detail
     responded_at = Column(UtcDateTime, nullable=True)
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts 
b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
index 601239c7c72..874ff6b4264 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/common.ts
@@ -567,8 +567,12 @@ export const UseTaskInstanceServiceGetHitlDetailKeyFn = ({ 
dagId, dagRunId, mapI
 export type TaskInstanceServiceGetHitlDetailsDefaultResponse = 
Awaited<ReturnType<typeof TaskInstanceService.getHitlDetails>>;
 export type TaskInstanceServiceGetHitlDetailsQueryResult<TData = 
TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown> = 
UseQueryResult<TData, TError>;
 export const useTaskInstanceServiceGetHitlDetailsKey = 
"TaskInstanceServiceGetHitlDetails";
-export const UseTaskInstanceServiceGetHitlDetailsKeyFn = ({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }: {
+export const UseTaskInstanceServiceGetHitlDetailsKeyFn = ({ bodySearch, 
createdAtGt, createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, 
dagRunId, limit, offset, orderBy, respondedByUserId, respondedByUserName, 
responseReceived, state, subjectSearch, taskId, taskIdPattern }: {
   bodySearch?: string;
+  createdAtGt?: string;
+  createdAtGte?: string;
+  createdAtLt?: string;
+  createdAtLte?: string;
   dagId: string;
   dagIdPattern?: string;
   dagRunId: string;
@@ -582,7 +586,7 @@ export const UseTaskInstanceServiceGetHitlDetailsKeyFn = ({ 
bodySearch, dagId, d
   subjectSearch?: string;
   taskId?: string;
   taskIdPattern?: string;
-}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetHitlDetailsKey, 
...(queryKey ?? [{ bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, 
orderBy, respondedByUserId, respondedByUserName, responseReceived, state, 
subjectSearch, taskId, taskIdPattern }])];
+}, queryKey?: Array<unknown>) => [useTaskInstanceServiceGetHitlDetailsKey, 
...(queryKey ?? [{ bodySearch, createdAtGt, createdAtGte, createdAtLt, 
createdAtLte, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, 
respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, 
taskId, taskIdPattern }])];
 export type ImportErrorServiceGetImportErrorDefaultResponse = 
Awaited<ReturnType<typeof ImportErrorService.getImportError>>;
 export type ImportErrorServiceGetImportErrorQueryResult<TData = 
ImportErrorServiceGetImportErrorDefaultResponse, TError = unknown> = 
UseQueryResult<TData, TError>;
 export const useImportErrorServiceGetImportErrorKey = 
"ImportErrorServiceGetImportError";
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts 
b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
index a58b538c489..54cf0dca709 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/ensureQueryData.ts
@@ -1089,11 +1089,19 @@ export const 
ensureUseTaskInstanceServiceGetHitlDetailData = (queryClient: Query
 * @param data.respondedByUserName
 * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
 * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. 
`%customer_%`). Regular expressions are **not** supported.
+* @param data.createdAtGte
+* @param data.createdAtGt
+* @param data.createdAtLte
+* @param data.createdAtLt
 * @returns HITLDetailCollection Successful Response
 * @throws ApiError
 */
-export const ensureUseTaskInstanceServiceGetHitlDetailsData = (queryClient: 
QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, 
orderBy, respondedByUserId, respondedByUserName, responseReceived, state, 
subjectSearch, taskId, taskIdPattern }: {
+export const ensureUseTaskInstanceServiceGetHitlDetailsData = (queryClient: 
QueryClient, { bodySearch, createdAtGt, createdAtGte, createdAtLt, 
createdAtLte, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, 
respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, 
taskId, taskIdPattern }: {
   bodySearch?: string;
+  createdAtGt?: string;
+  createdAtGte?: string;
+  createdAtLt?: string;
+  createdAtLte?: string;
   dagId: string;
   dagIdPattern?: string;
   dagRunId: string;
@@ -1107,7 +1115,7 @@ export const 
ensureUseTaskInstanceServiceGetHitlDetailsData = (queryClient: Quer
   subjectSearch?: string;
   taskId?: string;
   taskIdPattern?: string;
-}) => queryClient.ensureQueryData({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ 
bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, 
respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, 
taskId, taskIdPattern }) });
+}) => queryClient.ensureQueryData({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }), queryFn: () => 
TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, 
createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, offset, orde 
[...]
 /**
 * Get Import Error
 * Get an import error.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts 
b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
index 28cbad744a8..66a08f901b3 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/prefetch.ts
@@ -1089,11 +1089,19 @@ export const 
prefetchUseTaskInstanceServiceGetHitlDetail = (queryClient: QueryCl
 * @param data.respondedByUserName
 * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
 * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. 
`%customer_%`). Regular expressions are **not** supported.
+* @param data.createdAtGte
+* @param data.createdAtGt
+* @param data.createdAtLte
+* @param data.createdAtLt
 * @returns HITLDetailCollection Successful Response
 * @throws ApiError
 */
-export const prefetchUseTaskInstanceServiceGetHitlDetails = (queryClient: 
QueryClient, { bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, 
orderBy, respondedByUserId, respondedByUserName, responseReceived, state, 
subjectSearch, taskId, taskIdPattern }: {
+export const prefetchUseTaskInstanceServiceGetHitlDetails = (queryClient: 
QueryClient, { bodySearch, createdAtGt, createdAtGte, createdAtLt, 
createdAtLte, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, 
respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, 
taskId, taskIdPattern }: {
   bodySearch?: string;
+  createdAtGt?: string;
+  createdAtGte?: string;
+  createdAtLt?: string;
+  createdAtLte?: string;
   dagId: string;
   dagIdPattern?: string;
   dagRunId: string;
@@ -1107,7 +1115,7 @@ export const prefetchUseTaskInstanceServiceGetHitlDetails 
= (queryClient: QueryC
   subjectSearch?: string;
   taskId?: string;
   taskIdPattern?: string;
-}) => queryClient.prefetchQuery({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }), queryFn: () => TaskInstanceService.getHitlDetails({ 
bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, 
respondedByUserId, respondedByUserName, responseReceived, state, subjectSearch, 
taskId, taskIdPattern }) });
+}) => queryClient.prefetchQuery({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }), queryFn: () => 
TaskInstanceService.getHitlDetails({ bodySearch, createdAtGt, createdAtGte, 
createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, offset, orderB 
[...]
 /**
 * Get Import Error
 * Get an import error.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts 
b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
index 86843abd84c..9c04bac85d4 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/queries.ts
@@ -1089,11 +1089,19 @@ export const useTaskInstanceServiceGetHitlDetail = 
<TData = Common.TaskInstanceS
 * @param data.respondedByUserName
 * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
 * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. 
`%customer_%`). Regular expressions are **not** supported.
+* @param data.createdAtGte
+* @param data.createdAtGt
+* @param data.createdAtLte
+* @param data.createdAtLt
 * @returns HITLDetailCollection Successful Response
 * @throws ApiError
 */
-export const useTaskInstanceServiceGetHitlDetails = <TData = 
Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, 
TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }: {
+export const useTaskInstanceServiceGetHitlDetails = <TData = 
Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, 
TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }: {
   bodySearch?: string;
+  createdAtGt?: string;
+  createdAtGte?: string;
+  createdAtLt?: string;
+  createdAtLte?: string;
   dagId: string;
   dagIdPattern?: string;
   dagRunId: string;
@@ -1107,7 +1115,7 @@ export const useTaskInstanceServiceGetHitlDetails = 
<TData = Common.TaskInstance
   subjectSearch?: string;
   taskId?: string;
   taskIdPattern?: string;
-}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, 
"queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ 
bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orderBy, res [...]
+}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, 
"queryKey" | "queryFn">) => useQuery<TData, TError>({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => 
TaskInstanceService.getHitlDetails({ bodySearch, crea [...]
 /**
 * Get Import Error
 * Get an import error.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts 
b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
index aaed59782df..ba7f0fc93c9 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/queries/suspense.ts
@@ -1089,11 +1089,19 @@ export const 
useTaskInstanceServiceGetHitlDetailSuspense = <TData = Common.TaskI
 * @param data.respondedByUserName
 * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
 * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards (e.g. 
`%customer_%`). Regular expressions are **not** supported.
+* @param data.createdAtGte
+* @param data.createdAtGt
+* @param data.createdAtLte
+* @param data.createdAtLt
 * @returns HITLDetailCollection Successful Response
 * @throws ApiError
 */
-export const useTaskInstanceServiceGetHitlDetailsSuspense = <TData = 
Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, 
TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }: {
+export const useTaskInstanceServiceGetHitlDetailsSuspense = <TData = 
Common.TaskInstanceServiceGetHitlDetailsDefaultResponse, TError = unknown, 
TQueryKey extends Array<unknown> = unknown[]>({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }: {
   bodySearch?: string;
+  createdAtGt?: string;
+  createdAtGte?: string;
+  createdAtLt?: string;
+  createdAtLte?: string;
   dagId: string;
   dagIdPattern?: string;
   dagRunId: string;
@@ -1107,7 +1115,7 @@ export const useTaskInstanceServiceGetHitlDetailsSuspense 
= <TData = Common.Task
   subjectSearch?: string;
   taskId?: string;
   taskIdPattern?: string;
-}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, 
"queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, dagId, 
dagIdPattern, dagRunId, limit, offset, orderBy, respondedByUserId, 
respondedByUserName, responseReceived, state, subjectSearch, taskId, 
taskIdPattern }, queryKey), queryFn: () => TaskInstanceService.getHitlDetails({ 
bodySearch, dagId, dagIdPattern, dagRunId, limit, offset, orde [...]
+}, queryKey?: TQueryKey, options?: Omit<UseQueryOptions<TData, TError>, 
"queryKey" | "queryFn">) => useSuspenseQuery<TData, TError>({ queryKey: 
Common.UseTaskInstanceServiceGetHitlDetailsKeyFn({ bodySearch, createdAtGt, 
createdAtGte, createdAtLt, createdAtLte, dagId, dagIdPattern, dagRunId, limit, 
offset, orderBy, respondedByUserId, respondedByUserName, responseReceived, 
state, subjectSearch, taskId, taskIdPattern }, queryKey), queryFn: () => 
TaskInstanceService.getHitlDetails({ bodySear [...]
 /**
 * Get Import Error
 * Get an import error.
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
index 1cf2a46b461..32dafcb90fd 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts
@@ -3578,6 +3578,11 @@ export const $HITLDetail = {
             type: 'array',
             title: 'Assigned Users'
         },
+        created_at: {
+            type: 'string',
+            format: 'date-time',
+            title: 'Created At'
+        },
         responded_by_user: {
             anyOf: [
                 {
@@ -3626,7 +3631,7 @@ export const $HITLDetail = {
         }
     },
     type: 'object',
-    required: ['task_instance', 'options', 'subject'],
+    required: ['task_instance', 'options', 'subject', 'created_at'],
     title: 'HITLDetail',
     description: 'Schema for Human-in-the-loop detail.'
 } as const;
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
index 4efc34fabda..8b4cb8c21e4 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/services.gen.ts
@@ -2798,6 +2798,10 @@ export class TaskInstanceService {
      * @param data.respondedByUserName
      * @param data.subjectSearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
      * @param data.bodySearch SQL LIKE expression — use `%` / `_` wildcards 
(e.g. `%customer_%`). Regular expressions are **not** supported.
+     * @param data.createdAtGte
+     * @param data.createdAtGt
+     * @param data.createdAtLte
+     * @param data.createdAtLt
      * @returns HITLDetailCollection Successful Response
      * @throws ApiError
      */
@@ -2821,7 +2825,11 @@ export class TaskInstanceService {
                 responded_by_user_id: data.respondedByUserId,
                 responded_by_user_name: data.respondedByUserName,
                 subject_search: data.subjectSearch,
-                body_search: data.bodySearch
+                body_search: data.bodySearch,
+                created_at_gte: data.createdAtGte,
+                created_at_gt: data.createdAtGt,
+                created_at_lte: data.createdAtLte,
+                created_at_lt: data.createdAtLt
             },
             errors: {
                 401: 'Unauthorized',
diff --git a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts 
b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
index 636c1b9b20b..256812659a8 100644
--- a/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
+++ b/airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts
@@ -941,6 +941,7 @@ export type HITLDetail = {
         [key: string]: unknown;
     };
     assigned_users?: Array<HITLUser>;
+    created_at: string;
     responded_by_user?: HITLUser | null;
     responded_at?: string | null;
     chosen_options?: Array<(string)> | null;
@@ -2857,6 +2858,10 @@ export type GetHitlDetailsData = {
      * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). 
Regular expressions are **not** supported.
      */
     bodySearch?: string | null;
+    createdAtGt?: string | null;
+    createdAtGte?: string | null;
+    createdAtLt?: string | null;
+    createdAtLte?: string | null;
     dagId: string;
     /**
      * SQL LIKE expression — use `%` / `_` wildcards (e.g. `%customer_%`). 
Regular expressions are **not** supported.
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
index 61f6488d5fc..f8ab8e1c4d9 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/public/test_hitl.py
@@ -18,7 +18,7 @@ from __future__ import annotations
 
 import json
 from collections.abc import Callable
-from datetime import datetime
+from datetime import datetime, timedelta
 from operator import itemgetter
 from typing import TYPE_CHECKING, Any
 from unittest import mock
@@ -28,12 +28,14 @@ import time_machine
 from sqlalchemy import select
 from sqlalchemy.orm import Session
 
-from airflow._shared.timezones.timezone import utcnow
+from airflow._shared.timezones.timezone import utc, utcnow
 from airflow.models.hitl import HITLDetail
 from airflow.models.log import Log
 from airflow.sdk.execution_time.hitl import HITLUser
 from airflow.utils.state import TaskInstanceState
 
+from tests_common.test_utils.format_datetime import 
from_datetime_to_zulu_without_ms
+
 if TYPE_CHECKING:
     from fastapi.testclient import TestClient
 
@@ -49,6 +51,10 @@ ANOTHER_DAG_ID = "another_hitl_dag"
 TASK_ID = "sample_task_hitl"
 
 
+DEFAULT_CREATED_AT = datetime(2025, 9, 15, 13, 0, 0, tzinfo=utc)
+ANOTHER_CREATED_AT = datetime(2025, 9, 16, 12, 0, 0, tzinfo=utc)
+
+
 @pytest.fixture
 def sample_ti(
     create_task_instance: CreateTaskInstance,
@@ -158,6 +164,7 @@ def sample_hitl_details(sample_tis: list[TaskInstance], 
session: Session) -> lis
             defaults=["Approve"],
             multiple=False,
             params={"input_1": 1},
+            created_at=DEFAULT_CREATED_AT,
         )
         for i, ti in enumerate(sample_tis[:5])
     ]
@@ -175,6 +182,7 @@ def sample_hitl_details(sample_tis: list[TaskInstance], 
session: Session) -> lis
                 chosen_options=[str(i)],
                 params_input={"input": i},
                 responded_by={"id": "test", "name": "test"},
+                created_at=ANOTHER_CREATED_AT,
             )
             for i, ti in enumerate(sample_tis[5:])
         ]
@@ -209,6 +217,7 @@ def expected_sample_hitl_detail_dict(sample_ti: 
TaskInstance) -> dict[str, Any]:
         "options": ["Approve", "Reject"],
         "params": {"input_1": 1},
         "assigned_users": [],
+        "created_at": mock.ANY,
         "params_input": {},
         "responded_at": None,
         "chosen_options": None,
@@ -542,6 +551,21 @@ class TestGetHITLDetailsEndpoint:
             ({"response_received": True}, 3),
             ({"responded_by_user_id": ["test"]}, 3),
             ({"responded_by_user_name": ["test"]}, 3),
+            (
+                {"created_at_gte": 
from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT + timedelta(days=1))},
+                0,
+            ),
+            (
+                {"created_at_lte": 
from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT - timedelta(days=1))},
+                0,
+            ),
+            (
+                {
+                    "created_at_gte": 
from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT),
+                    "created_at_lte": 
from_datetime_to_zulu_without_ms(DEFAULT_CREATED_AT),
+                },
+                5,
+            ),
         ],
         ids=[
             "dag_id_pattern_hitl_dag",
@@ -556,6 +580,9 @@ class TestGetHITLDetailsEndpoint:
             "response_received",
             "responded_user_id",
             "responded_user_name",
+            "created_at_gte",
+            "created_at_lte",
+            "created_at",
         ],
     )
     def test_should_respond_200_with_existing_response_and_query(
@@ -587,6 +614,7 @@ class TestGetHITLDetailsEndpoint:
                     "multiple": False,
                     "params": {"input_1": 1},
                     "assigned_users": [],
+                    "created_at": 
DEFAULT_CREATED_AT.isoformat().replace("+00:00", "Z"),
                     "responded_by_user": None,
                     "responded_at": None,
                     "chosen_options": None,
@@ -612,6 +640,7 @@ class TestGetHITLDetailsEndpoint:
             # htil key
             ("subject", itemgetter("subject")),
             ("responded_at", itemgetter("responded_at")),
+            ("created_at", itemgetter("created_at")),
         ],
         ids=[
             "ti_id",
@@ -622,6 +651,7 @@ class TestGetHITLDetailsEndpoint:
             "task_instance_operator",
             "subject",
             "responded_at",
+            "created_at",
         ],
     )
     def test_should_respond_200_with_existing_response_and_order_by(
diff --git 
a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py 
b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
index d58f29839b6..5ebf2221d92 100644
--- a/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
+++ b/airflow-core/tests/unit/api_fastapi/core_api/routes/ui/test_dags.py
@@ -188,6 +188,7 @@ class TestGetDagRuns(TestPublicDagEndpoint):
                         "params_input": {},
                         "response_received": False,
                         "assigned_users": [],
+                        "created_at": mock.ANY,
                     }
                     for i in range(3)
                 ],
diff --git a/airflow-ctl/src/airflowctl/api/datamodels/generated.py 
b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
index 31da4e13044..739297fd434 100644
--- a/airflow-ctl/src/airflowctl/api/datamodels/generated.py
+++ b/airflow-ctl/src/airflowctl/api/datamodels/generated.py
@@ -1837,6 +1837,7 @@ class HITLDetail(BaseModel):
     multiple: Annotated[bool | None, Field(title="Multiple")] = False
     params: Annotated[dict[str, Any] | None, Field(title="Params")] = None
     assigned_users: Annotated[list[HITLUser] | None, Field(title="Assigned 
Users")] = None
+    created_at: Annotated[datetime, Field(title="Created At")]
     responded_by_user: HITLUser | None = None
     responded_at: Annotated[datetime | None, Field(title="Responded At")] = 
None
     chosen_options: Annotated[list[str] | None, Field(title="Chosen Options")] 
= None


Reply via email to