diff --git a/litellm/proxy/_lazy_openapi_snapshot.json b/litellm/proxy/_lazy_openapi_snapshot.json
index 6be003927d6..972c831073f 100644
--- a/litellm/proxy/_lazy_openapi_snapshot.json
+++ b/litellm/proxy/_lazy_openapi_snapshot.json
@@ -27417,7 +27417,7 @@
},
"/v1/tool/spend": {
"get": {
- "description": "Spend attributed to each tool over a date range, for the Cost Optimization dashboard.\n\nJoins ``LiteLLM_SpendLogToolIndex`` (which tool names ran on which request) to\n``LiteLLM_SpendLogs`` (what the request cost). A request that used multiple tools\ncounts its full spend toward each of those tools, so per-tool numbers are\nattributions. ``total_spend`` is the deduplicated spend of every request that\ncalled at least one tool in the window, so it never double counts.\n\nThe window is capped at the most recent 30 days ending at ``end_date``: a wider\nrequested range is clamped, and the response's ``start_date`` reflects the\neffective window actually served.",
+ "description": "Spend attributed to each tool over a date range, for the Cost Optimization dashboard.\n\nJoins ``LiteLLM_SpendLogToolIndex`` (which tool names ran on which request) to\n``LiteLLM_SpendLogs`` (what the request cost). A request that used multiple tools\ncounts its full spend toward each of those tools, so per-tool numbers are\nattributions. ``total_spend`` is the deduplicated spend of every request that\ncalled at least one tool in the window, so it never double counts.\n\n``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to\n31 calendar dates inclusive, the same width as the endpoint's default window):\na wider requested range is clamped, and the response's ``start_date`` reflects\nthe effective window actually served.",
"operationId": "get_tool_spend_v1_tool_spend_get",
"parameters": [
{
diff --git a/litellm/proxy/management_endpoints/tool_management_endpoints.py b/litellm/proxy/management_endpoints/tool_management_endpoints.py
index 6d9748332bc..3f528c8c489 100644
--- a/litellm/proxy/management_endpoints/tool_management_endpoints.py
+++ b/litellm/proxy/management_endpoints/tool_management_endpoints.py
@@ -211,9 +211,10 @@ async def get_tool_spend(
attributions. ``total_spend`` is the deduplicated spend of every request that
called at least one tool in the window, so it never double counts.
- The window is capped at the most recent 30 days ending at ``end_date``: a wider
- requested range is clamped, and the response's ``start_date`` reflects the
- effective window actually served.
+ ``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to
+ 31 calendar dates inclusive, the same width as the endpoint's default window):
+ a wider requested range is clamped, and the response's ``start_date`` reflects
+ the effective window actually served.
"""
from litellm.proxy.proxy_server import prisma_client
diff --git a/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py
index f420eed6a33..150499dfbf1 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py
@@ -203,7 +203,10 @@ class TestToolManagementEndpoints:
assert tuple(call.args[1:]) == expected_binds
assert resp.json()["end_date"] == "2026-07-02"
- def test_tool_spend_window_clamped_to_most_recent_30_days(self):
+ def test_tool_spend_start_clamped_to_30_days_before_end(self):
+ # Clamped floor is end_date minus 30 days, serving up to 31 calendar dates
+ # inclusive: deliberately the same width as the endpoint's default window,
+ # so the dashboard's default range never triggers the clamp.
prisma = MagicMock()
prisma.db.query_raw = AsyncMock(return_value=[])
with patch("litellm.proxy.proxy_server.prisma_client", prisma):
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
index 27c79c8a9ce..ab1cd146adc 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx
@@ -148,7 +148,7 @@ describe("UsageTab", () => {
};
const { findByText } = renderWith([day("2026-07-12", {})], toolSpend);
- expect(await findByText(/most recent 30 days of the selected range/)).toBeInTheDocument();
+ expect(await findByText(/capped at 30 days before the end of the selected range/)).toBeInTheDocument();
});
it("shows no cap note when the served window matches the request", async () => {
@@ -162,6 +162,6 @@ describe("UsageTab", () => {
const { findAllByTestId, queryByText } = renderWith([day("2026-07-12", {})], toolSpend);
await findAllByTestId("bar-chart");
- expect(queryByText(/most recent 30 days of the selected range/)).not.toBeInTheDocument();
+ expect(queryByText(/capped at 30 days before the end of the selected range/)).not.toBeInTheDocument();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx
index a069c80a201..6e2da4456d3 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx
@@ -214,7 +214,8 @@ const UsageTab: React.FC
- Tool spend is limited to the most recent 30 days of the selected range (since {toolSpend?.start_date}). + Tool spend is capped at 30 days before the end of the selected range; showing spend since{" "} + {toolSpend?.start_date}.
)} diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index e420da55e77..c1141db7852 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -17977,9 +17977,10 @@ export interface paths { * attributions. ``total_spend`` is the deduplicated spend of every request that * called at least one tool in the window, so it never double counts. * - * The window is capped at the most recent 30 days ending at ``end_date``: a wider - * requested range is clamped, and the response's ``start_date`` reflects the - * effective window actually served. + * ``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to + * 31 calendar dates inclusive, the same width as the endpoint's default window): + * a wider requested range is clamped, and the response's ``start_date`` reflects + * the effective window actually served. */ get: operations["get_tool_spend_v1_tool_spend_get"]; put?: never;