diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20261110120000_add_daily_spend_guardrail_spend/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20261110120000_add_daily_spend_guardrail_spend/migration.sql new file mode 100644 index 00000000000..c2c264325a6 --- /dev/null +++ b/litellm-proxy-extras/litellm_proxy_extras/migrations/20261110120000_add_daily_spend_guardrail_spend/migration.sql @@ -0,0 +1,22 @@ +SET LOCAL lock_timeout = '10s'; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyUserSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyTeamSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyOrganizationSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyEndUserSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyAgentSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyTagSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; + +-- AlterTable +ALTER TABLE "LiteLLM_DailyGlobalSpend" ADD COLUMN IF NOT EXISTS "guardrail_spend" DOUBLE PRECISION NOT NULL DEFAULT 0.0; diff --git a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma index 37783275d9b..5a5d56cc6e2 100644 --- a/litellm-proxy-extras/litellm_proxy_extras/schema.prisma +++ b/litellm-proxy-extras/litellm_proxy_extras/schema.prisma @@ -883,6 +883,7 @@ model LiteLLM_DailyUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -919,6 +920,7 @@ model LiteLLM_DailyGlobalSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -952,6 +954,7 @@ model LiteLLM_DailyOrganizationSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -990,6 +993,7 @@ model LiteLLM_DailyEndUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1027,6 +1031,7 @@ model LiteLLM_DailyAgentSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1064,6 +1069,7 @@ model LiteLLM_DailyTeamSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1104,6 +1110,7 @@ model LiteLLM_DailyTagSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) diff --git a/litellm/accounting/projection.py b/litellm/accounting/projection.py index dd52b49f101..9d04d39884e 100644 --- a/litellm/accounting/projection.py +++ b/litellm/accounting/projection.py @@ -133,6 +133,7 @@ def _daily_counters(row: Mapping[str, object], metadata: Mapping[str, object]) - ("prompt_caching_savings_spend", _number(savings.get("prompt_caching"))), ("gateway_injected_caching_savings_spend", _number(savings.get("gateway_injected_caching"))), ("autorouter_savings_spend", 0.0 if internal else _number(savings.get("autorouter"))), + ("guardrail_spend", _number(metadata.get("accounting_guardrail_spend"))), ("total_response_time_ms", _number(duration) if timed else 0), ("timed_requests", int(timed)), ) diff --git a/litellm/accounting/snapshot.py b/litellm/accounting/snapshot.py index ab85df08320..874b90110c1 100644 --- a/litellm/accounting/snapshot.py +++ b/litellm/accounting/snapshot.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Final from pydantic import TypeAdapter, ValidationError from litellm._logging import verbose_proxy_logger +from litellm.litellm_core_utils.llm_cost_calc.guardrail_cost import guardrail_share_of_spend from litellm.litellm_core_utils.safe_json_dumps import safe_json_structure from litellm.proxy._types import SpendLogsPayload from litellm.proxy.spend_tracking.compression_savings import extract_compression_saved_tokens @@ -73,6 +74,7 @@ def build_accounting_payload( **{key: _accounting_metadata_field(key, value) for key, value in metadata.items() if key in _METADATA_FIELDS}, "accounting_entities": entities, "accounting_savings": savings._asdict(), + "accounting_guardrail_spend": guardrail_share_of_spend(metadata, payload["spend"]), "accounting_model_access_groups": model_access_groups, "accounting_windows": windows, } diff --git a/litellm/litellm_core_utils/llm_cost_calc/guardrail_cost.py b/litellm/litellm_core_utils/llm_cost_calc/guardrail_cost.py index e4ad36f50bc..03f6794889c 100644 --- a/litellm/litellm_core_utils/llm_cost_calc/guardrail_cost.py +++ b/litellm/litellm_core_utils/llm_cost_calc/guardrail_cost.py @@ -311,6 +311,12 @@ def guardrail_information_cost(guardrail_information: object) -> float: return _validated_entry_cost(guardrail_information) +def guardrail_share_of_spend(spend_log_metadata: Mapping[str, object], spend: float) -> float: + """The part of a spend row's ``spend`` billed for its guardrails, priced the way success and failure rows add + it to spend and capped at the row's spend, since an allowance discount or a repeat job poll can charge less.""" + return min(guardrail_information_cost(spend_log_metadata.get("guardrail_information")), max(spend, 0.0)) + + def cost_breakdown_with_guardrail(cost_breakdown: CostBreakdown | None, guardrail_cost: float) -> CostBreakdown | None: if guardrail_cost <= 0.0: return cost_breakdown diff --git a/litellm/proxy/_lazy_openapi_snapshot.json b/litellm/proxy/_lazy_openapi_snapshot.json index 2cadfd6c4a3..36e2cb46e90 100644 --- a/litellm/proxy/_lazy_openapi_snapshot.json +++ b/litellm/proxy/_lazy_openapi_snapshot.json @@ -4882,6 +4882,12 @@ "title": "Gateway Injected Caching Savings Spend", "type": "number" }, + "guardrail_spend": { + "default": 0.0, + "description": "Guardrail spend in USD, already included in spend, so model spend is spend - guardrail_spend. Rows recorded before this field existed report 0 even when their spend includes guardrail cost", + "title": "Guardrail Spend", + "type": "number" + }, "prompt_caching_savings_spend": { "default": 0.0, "title": "Prompt Caching Savings Spend", diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index 228e80da4bd..736c09277f1 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -5335,6 +5335,7 @@ class BaseDailySpendTransaction(TypedDict): # missing value to zero, so requiring it here would describe a shape the aggregation # is explicitly tested against. autorouter_savings_spend: NotRequired[float] + guardrail_spend: NotRequired[float] # writable-ok: the rollup queue accumulates into this key in place # request level metrics spend: float diff --git a/litellm/proxy/db/daily_spend_bulk_upsert.py b/litellm/proxy/db/daily_spend_bulk_upsert.py index 2d1770f4c1d..38b132e7e10 100644 --- a/litellm/proxy/db/daily_spend_bulk_upsert.py +++ b/litellm/proxy/db/daily_spend_bulk_upsert.py @@ -98,6 +98,7 @@ _SPEND_COLUMNS: Final = ( "prompt_caching_savings_spend", "gateway_injected_caching_savings_spend", "autorouter_savings_spend", + "guardrail_spend", ) _CASTS: Final[Mapping[str, str]] = MappingProxyType( diff --git a/litellm/proxy/db/db_spend_update_writer.py b/litellm/proxy/db/db_spend_update_writer.py index 4a1871ff1f5..fc280dd4f73 100644 --- a/litellm/proxy/db/db_spend_update_writer.py +++ b/litellm/proxy/db/db_spend_update_writer.py @@ -39,6 +39,7 @@ from litellm.constants import ( from litellm.litellm_core_utils.batch_utils import BATCH_COST_REQUEST_ID_SUFFIX from litellm.litellm_core_utils.core_helpers import finite_cost, single_log_line from litellm.litellm_core_utils.litellm_logging import coerce_model_access_groups +from litellm.litellm_core_utils.llm_cost_calc.guardrail_cost import guardrail_share_of_spend from litellm.litellm_core_utils.safe_json_loads import safe_json_loads from litellm.proxy._types import ( DB_RETRY_SAFE_ERROR_TYPES, @@ -3164,6 +3165,10 @@ class DBSpendUpdateWriter: prompt_caching_savings_spend=savings_spend.prompt_caching, gateway_injected_caching_savings_spend=savings_spend.gateway_injected_caching, autorouter_savings_spend=0.0 if is_internal_call else savings_spend.autorouter, + guardrail_spend=guardrail_share_of_spend( + _metadata, + payload["spend"], # pyright: ignore[reportUnknownArgumentType] # legacy dict | SpendLogsPayload union + ), total_response_time_ms=timed_duration_ms or 0, timed_requests=0 if timed_duration_ms is None else 1, ) diff --git a/litellm/proxy/db/db_transaction_queue/daily_spend_update_queue.py b/litellm/proxy/db/db_transaction_queue/daily_spend_update_queue.py index 288c85c3513..70a9aaa5512 100644 --- a/litellm/proxy/db/db_transaction_queue/daily_spend_update_queue.py +++ b/litellm/proxy/db/db_transaction_queue/daily_spend_update_queue.py @@ -154,6 +154,10 @@ class DailySpendUpdateQueue(BaseUpdateQueue): payload.get("autorouter_savings_spend", 0) or 0 ) + daily_transaction.get("autorouter_savings_spend", 0) + daily_transaction["guardrail_spend"] = ( + payload.get("guardrail_spend", 0) or 0 + ) + daily_transaction.get("guardrail_spend", 0) + daily_transaction["total_response_time_ms"] = ( payload.get("total_response_time_ms", 0) or 0 ) + daily_transaction.get("total_response_time_ms", 0) diff --git a/litellm/proxy/management_endpoints/common_daily_activity.py b/litellm/proxy/management_endpoints/common_daily_activity.py index a0db1b00ec4..80d873587c3 100644 --- a/litellm/proxy/management_endpoints/common_daily_activity.py +++ b/litellm/proxy/management_endpoints/common_daily_activity.py @@ -163,6 +163,9 @@ class DailySpendRecord(Protocol): @property def autorouter_savings_spend(self) -> float: ... + @property + def guardrail_spend(self) -> float: ... + @property def api_requests(self) -> int: ... @@ -250,6 +253,7 @@ def update_metrics(existing_metrics: SpendMetrics, record: DailySpendRecord) -> existing_metrics.prompt_caching_savings_spend += record.prompt_caching_savings_spend or 0 existing_metrics.gateway_injected_caching_savings_spend += record.gateway_injected_caching_savings_spend or 0 existing_metrics.autorouter_savings_spend += record.autorouter_savings_spend or 0 + existing_metrics.guardrail_spend += record.guardrail_spend or 0 # rebind-ok: callers rely on in-place accumulation existing_metrics.api_requests += record.api_requests or 0 existing_metrics.successful_requests += record.successful_requests or 0 existing_metrics.failed_requests += record.failed_requests or 0 @@ -736,6 +740,7 @@ def sum_spend_metrics(metrics: Sequence[SpendMetrics]) -> SpendMetrics: prompt_caching_savings_spend=sum(metric.prompt_caching_savings_spend for metric in metrics), gateway_injected_caching_savings_spend=sum(metric.gateway_injected_caching_savings_spend for metric in metrics), autorouter_savings_spend=sum(metric.autorouter_savings_spend for metric in metrics), + guardrail_spend=sum(metric.guardrail_spend for metric in metrics), total_tokens=sum(metric.total_tokens for metric in metrics), successful_requests=sum(metric.successful_requests for metric in metrics), failed_requests=sum(metric.failed_requests for metric in metrics), @@ -766,6 +771,7 @@ def _record_to_spend_metrics(record: RollupMetricsRow) -> SpendMetrics: prompt_caching_savings_spend=record.prompt_caching_savings_spend or 0, gateway_injected_caching_savings_spend=record.gateway_injected_caching_savings_spend or 0, autorouter_savings_spend=record.autorouter_savings_spend or 0, + guardrail_spend=record.guardrail_spend or 0, api_requests=record.api_requests or 0, successful_requests=record.successful_requests or 0, failed_requests=record.failed_requests or 0, diff --git a/litellm/proxy/schema.prisma b/litellm/proxy/schema.prisma index 37783275d9b..5a5d56cc6e2 100644 --- a/litellm/proxy/schema.prisma +++ b/litellm/proxy/schema.prisma @@ -883,6 +883,7 @@ model LiteLLM_DailyUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -919,6 +920,7 @@ model LiteLLM_DailyGlobalSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -952,6 +954,7 @@ model LiteLLM_DailyOrganizationSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -990,6 +993,7 @@ model LiteLLM_DailyEndUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1027,6 +1031,7 @@ model LiteLLM_DailyAgentSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1064,6 +1069,7 @@ model LiteLLM_DailyTeamSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1104,6 +1110,7 @@ model LiteLLM_DailyTagSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) diff --git a/litellm/repositories/daily_activity_repository.py b/litellm/repositories/daily_activity_repository.py index 809f78e378c..9aa0950785b 100644 --- a/litellm/repositories/daily_activity_repository.py +++ b/litellm/repositories/daily_activity_repository.py @@ -132,6 +132,7 @@ class _CustomerDailyRow(BaseModel): prompt_caching_savings_spend: float gateway_injected_caching_savings_spend: float autorouter_savings_spend: float + guardrail_spend: float spend: float api_requests: int successful_requests: int diff --git a/litellm/repositories/daily_activity_sql.py b/litellm/repositories/daily_activity_sql.py index 5d1f85658ea..dc3ca19bb30 100644 --- a/litellm/repositories/daily_activity_sql.py +++ b/litellm/repositories/daily_activity_sql.py @@ -223,6 +223,7 @@ def _rollup_metric_select(table: DailyActivityTable) -> str: SUM(prompt_caching_savings_spend)::float AS prompt_caching_savings_spend, SUM(gateway_injected_caching_savings_spend)::float AS gateway_injected_caching_savings_spend, SUM(autorouter_savings_spend)::float AS autorouter_savings_spend, + SUM(guardrail_spend)::float AS guardrail_spend, SUM(api_requests)::bigint AS api_requests, SUM(successful_requests)::bigint AS successful_requests, SUM(failed_requests)::bigint AS failed_requests, diff --git a/litellm/types/proxy/management_endpoints/common_daily_activity.py b/litellm/types/proxy/management_endpoints/common_daily_activity.py index 19791b7f620..c4816e7d1ea 100644 --- a/litellm/types/proxy/management_endpoints/common_daily_activity.py +++ b/litellm/types/proxy/management_endpoints/common_daily_activity.py @@ -31,6 +31,11 @@ class SpendMetrics(LiteLLMBaseModel): prompt_caching_savings_spend: float = Field(default=0.0) gateway_injected_caching_savings_spend: float = Field(default=0.0) autorouter_savings_spend: float = Field(default=0.0) + guardrail_spend: float = Field( + default=0.0, + description="Guardrail spend in USD, already included in spend, so model spend is spend - guardrail_spend. " + "Rows recorded before this field existed report 0 even when their spend includes guardrail cost", + ) total_tokens: int = Field(default=0) successful_requests: int = Field(default=0) failed_requests: int = Field(default=0) @@ -259,6 +264,7 @@ class LiteLLM_DailyUserSpend(LiteLLMBaseModel): prompt_caching_savings_spend: float = 0.0 gateway_injected_caching_savings_spend: float = 0.0 autorouter_savings_spend: float = 0.0 + guardrail_spend: float = 0.0 spend: float = 0.0 api_requests: int = 0 successful_requests: int = 0 diff --git a/litellm/types/repositories/daily_activity.py b/litellm/types/repositories/daily_activity.py index 27e169cec5a..8d68d92a336 100644 --- a/litellm/types/repositories/daily_activity.py +++ b/litellm/types/repositories/daily_activity.py @@ -144,6 +144,7 @@ class RollupMetricsRow: prompt_caching_savings_spend: float | None gateway_injected_caching_savings_spend: float | None autorouter_savings_spend: float | None + guardrail_spend: float | None = field(default=None, kw_only=True) api_requests: int | None successful_requests: int | None failed_requests: int | None @@ -219,6 +220,7 @@ class DailyActivityRow(Protocol): prompt_caching_savings_spend: float gateway_injected_caching_savings_spend: float autorouter_savings_spend: float + guardrail_spend: float spend: float api_requests: int successful_requests: int diff --git a/schema.prisma b/schema.prisma index 37783275d9b..5a5d56cc6e2 100644 --- a/schema.prisma +++ b/schema.prisma @@ -883,6 +883,7 @@ model LiteLLM_DailyUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -919,6 +920,7 @@ model LiteLLM_DailyGlobalSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -952,6 +954,7 @@ model LiteLLM_DailyOrganizationSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -990,6 +993,7 @@ model LiteLLM_DailyEndUserSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1027,6 +1031,7 @@ model LiteLLM_DailyAgentSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1064,6 +1069,7 @@ model LiteLLM_DailyTeamSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) @@ -1104,6 +1110,7 @@ model LiteLLM_DailyTagSpend { prompt_caching_savings_spend Float @default(0.0) gateway_injected_caching_savings_spend Float @default(0.0) autorouter_savings_spend Float @default(0.0) + guardrail_spend Float @default(0.0) spend Float @default(0.0) api_requests BigInt @default(0) successful_requests BigInt @default(0) diff --git a/tests/integration/database/test_spendlogs_ledger_parity.py b/tests/integration/database/test_spendlogs_ledger_parity.py index 7a8c57d234e..3019d75a2a7 100644 --- a/tests/integration/database/test_spendlogs_ledger_parity.py +++ b/tests/integration/database/test_spendlogs_ledger_parity.py @@ -424,6 +424,7 @@ async def _assert_legacy_database_parity( "guardrail_status": "success", "guardrail_usage": {"text": 2}, "guardrail_cost_by_unit": {"text": 0.02}, + "guardrail_cost": 0.02, "guardrail_cost_in_spend": True, } ], @@ -579,6 +580,7 @@ async def _assert_legacy_database_parity( assert daily["autorouter_savings_spend"] == pytest.approx( (0 if origin == "auto_router" else 0.125) + (0.2 if correction_order else 0) ) + assert daily["guardrail_spend"] == pytest.approx(min(0.02, cost)) group_spend = {row["access_group_name"]: row["spend"] for row in results[-1]["LiteLLM_ModelAccessGroupBudgetTable"]} assert group_spend == {"group": cost + prior_spend, **({"unserved-group": prior_spend} if fallback_narrowing else {})} assert results[-1]["LiteLLM_DailyGuardrailUsageUnits"] diff --git a/tests/integration/spend/fixtures/daily_activity_team.json b/tests/integration/spend/fixtures/daily_activity_team.json index 8f4956dd7fe..cf42f7ae2dd 100644 --- a/tests/integration/spend/fixtures/daily_activity_team.json +++ b/tests/integration/spend/fixtures/daily_activity_team.json @@ -1 +1 @@ -{"results":[{"date":"2026-06-01","metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"breakdown":{"mcp_servers":{},"models":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"model_groups":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"providers":{"provider-a":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"endpoints":{"/v1/chat/completions":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"api_keys":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}},"entities":{"team-1":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{"team_alias":"Usage Team"},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}}},"guardrails":{}}}],"metadata":{"total_spend":1273.0,"total_flat_cost":0.0,"total_ptu_hours":0.0,"total_prompt_tokens":1014,"total_completion_tokens":10,"total_tokens":1024,"total_api_requests":5,"total_successful_requests":5,"total_failed_requests":0,"total_cache_read_input_tokens":6,"total_cache_creation_input_tokens":0,"total_compression_saved_tokens":0,"total_compression_savings_spend":0.0,"total_prompt_caching_savings_spend":0.0,"total_gateway_injected_caching_savings_spend":0.0,"total_autorouter_savings_spend":0.0,"total_response_time_ms":0,"total_timed_requests":0,"page":1,"total_pages":1,"has_more":false,"api_key_limit":100,"total_api_keys":5,"entity_total_api_keys":{"team-1":5}}} +{"results":[{"date":"2026-06-01","metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"breakdown":{"mcp_servers":{},"models":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"model_groups":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"providers":{"provider-a":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"endpoints":{"/v1/chat/completions":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"api_keys":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}},"entities":{"team-1":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{"team_alias":"Usage Team"},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}}},"guardrails":{}}}],"metadata":{"total_spend":1273.0,"total_flat_cost":0.0,"total_ptu_hours":0.0,"total_prompt_tokens":1014,"total_completion_tokens":10,"total_tokens":1024,"total_api_requests":5,"total_successful_requests":5,"total_failed_requests":0,"total_cache_read_input_tokens":6,"total_cache_creation_input_tokens":0,"total_compression_saved_tokens":0,"total_compression_savings_spend":0.0,"total_prompt_caching_savings_spend":0.0,"total_gateway_injected_caching_savings_spend":0.0,"total_autorouter_savings_spend":0.0,"total_response_time_ms":0,"total_timed_requests":0,"page":1,"total_pages":1,"has_more":false,"api_key_limit":100,"total_api_keys":5,"entity_total_api_keys":{"team-1":5}}} diff --git a/tests/integration/spend/fixtures/daily_activity_user.json b/tests/integration/spend/fixtures/daily_activity_user.json index 058e12a5044..53f3bfd5487 100644 --- a/tests/integration/spend/fixtures/daily_activity_user.json +++ b/tests/integration/spend/fixtures/daily_activity_user.json @@ -1 +1 @@ -{"results":[{"date":"2026-06-01","metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"breakdown":{"mcp_servers":{},"models":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"model_groups":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"providers":{"provider-a":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"endpoints":{"/v1/chat/completions":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"api_keys":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}},"entities":{"user-1":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{"user_email":"user@example.com","user_alias":null},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}}},"guardrails":{}}}],"metadata":{"total_spend":1273.0,"total_flat_cost":0.0,"total_ptu_hours":0.0,"total_prompt_tokens":1014,"total_completion_tokens":10,"total_tokens":1024,"total_api_requests":5,"total_successful_requests":5,"total_failed_requests":0,"total_cache_read_input_tokens":6,"total_cache_creation_input_tokens":0,"total_compression_saved_tokens":0,"total_compression_savings_spend":0.0,"total_prompt_caching_savings_spend":0.0,"total_gateway_injected_caching_savings_spend":0.0,"total_autorouter_savings_spend":0.0,"total_response_time_ms":0,"total_timed_requests":0,"page":1,"total_pages":1,"has_more":false,"api_key_limit":100,"total_api_keys":5,"entity_total_api_keys":{"user-1":5}}} +{"results":[{"date":"2026-06-01","metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"breakdown":{"mcp_servers":{},"models":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"model_groups":{"model-ptu":{"metrics":{"spend":1000.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":0,"completion_tokens":0,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":0,"successful_requests":0,"failed_requests":0,"api_requests":0,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{}},"model-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}},"model-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}},"model-popular":{"metrics":{"spend":270.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":9,"completion_tokens":6,"cache_read_input_tokens":3,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":15,"successful_requests":3,"failed_requests":0,"api_requests":3,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"providers":{"provider-a":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"endpoints":{"/v1/chat/completions":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{},"api_key_breakdown":{"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}}}}},"api_keys":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}},"entities":{"user-1":{"metrics":{"spend":1273.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1014,"completion_tokens":10,"cache_read_input_tokens":6,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1024,"successful_requests":5,"failed_requests":0,"api_requests":5,"total_response_time_ms":0,"timed_requests":0},"metadata":{"user_email":"user@example.com","user_alias":null},"api_key_breakdown":{"key-a":{"metrics":{"spend":100.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":2,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":4,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-a","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-b":{"metrics":{"spend":90.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":3,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":5,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-b","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-c":{"metrics":{"spend":80.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":4,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":6,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-c","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-cache":{"metrics":{"spend":2.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":1000,"completion_tokens":2,"cache_read_input_tokens":1,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":1002,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"alias-cache","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":true}},"key-target":{"metrics":{"spend":1.0,"flat_cost":0.0,"ptu_hours":0.0,"prompt_tokens":5,"completion_tokens":2,"cache_read_input_tokens":2,"cache_creation_input_tokens":0,"compression_saved_tokens":0,"compression_savings_spend":0.0,"prompt_caching_savings_spend":0.0,"gateway_injected_caching_savings_spend":0.0,"autorouter_savings_spend":0.0,"guardrail_spend":0.0,"total_tokens":7,"successful_requests":1,"failed_requests":0,"api_requests":1,"total_response_time_ms":0,"timed_requests":0},"metadata":{"key_alias":"deleted-target","team_id":"team-1","user_id":"user-1","user_email":"user@example.com","key_exists":false}}}}},"guardrails":{}}}],"metadata":{"total_spend":1273.0,"total_flat_cost":0.0,"total_ptu_hours":0.0,"total_prompt_tokens":1014,"total_completion_tokens":10,"total_tokens":1024,"total_api_requests":5,"total_successful_requests":5,"total_failed_requests":0,"total_cache_read_input_tokens":6,"total_cache_creation_input_tokens":0,"total_compression_saved_tokens":0,"total_compression_savings_spend":0.0,"total_prompt_caching_savings_spend":0.0,"total_gateway_injected_caching_savings_spend":0.0,"total_autorouter_savings_spend":0.0,"total_response_time_ms":0,"total_timed_requests":0,"page":1,"total_pages":1,"has_more":false,"api_key_limit":100,"total_api_keys":5,"entity_total_api_keys":{"user-1":5}}} diff --git a/tests/integration/spend/golden/daily_activity_team_aggregated.json b/tests/integration/spend/golden/daily_activity_team_aggregated.json index 91a5d33391b..ce8ccbcaafb 100644 --- a/tests/integration/spend/golden/daily_activity_team_aggregated.json +++ b/tests/integration/spend/golden/daily_activity_team_aggregated.json @@ -39,6 +39,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -68,6 +69,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -97,6 +99,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -126,6 +129,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -155,6 +159,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -188,6 +193,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -217,6 +223,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -246,6 +253,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -275,6 +283,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -304,6 +313,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -327,6 +337,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -360,6 +371,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -389,6 +401,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -418,6 +431,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -447,6 +461,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -476,6 +491,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -501,6 +517,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -535,6 +552,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -558,6 +576,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -589,6 +608,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -618,6 +638,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -647,6 +668,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -670,6 +692,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -694,6 +717,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -725,6 +749,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -748,6 +773,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -781,6 +807,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -804,6 +831,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -835,6 +863,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -864,6 +893,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -893,6 +923,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -916,6 +947,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -940,6 +972,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -971,6 +1004,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -994,6 +1028,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1027,6 +1062,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1056,6 +1092,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1085,6 +1122,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1114,6 +1152,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1143,6 +1182,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1166,6 +1206,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -1190,6 +1231,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, diff --git a/tests/integration/spend/golden/daily_activity_team_paginated.json b/tests/integration/spend/golden/daily_activity_team_paginated.json index 18ee30a74e6..43aee6bdfb6 100644 --- a/tests/integration/spend/golden/daily_activity_team_paginated.json +++ b/tests/integration/spend/golden/daily_activity_team_paginated.json @@ -39,6 +39,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -68,6 +69,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -97,6 +99,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -126,6 +129,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -155,6 +159,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -188,6 +193,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -217,6 +223,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -246,6 +253,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -275,6 +283,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -304,6 +313,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -327,6 +337,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -360,6 +371,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -389,6 +401,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -418,6 +431,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -447,6 +461,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -476,6 +491,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -501,6 +517,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -535,6 +552,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -558,6 +576,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -589,6 +608,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -618,6 +638,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -647,6 +668,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -670,6 +692,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -694,6 +717,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -725,6 +749,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -748,6 +773,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -781,6 +807,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -804,6 +831,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -835,6 +863,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -864,6 +893,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -893,6 +923,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -916,6 +947,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -940,6 +972,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -971,6 +1004,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -994,6 +1028,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1027,6 +1062,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1056,6 +1092,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1085,6 +1122,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1114,6 +1152,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1143,6 +1182,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1166,6 +1206,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -1190,6 +1231,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, diff --git a/tests/integration/spend/golden/daily_activity_user_aggregated.json b/tests/integration/spend/golden/daily_activity_user_aggregated.json index 3189c000035..35d7e57eba8 100644 --- a/tests/integration/spend/golden/daily_activity_user_aggregated.json +++ b/tests/integration/spend/golden/daily_activity_user_aggregated.json @@ -39,6 +39,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -68,6 +69,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -97,6 +99,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -126,6 +129,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -155,6 +159,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -188,6 +193,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -217,6 +223,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -246,6 +253,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -275,6 +283,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -304,6 +313,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -327,6 +337,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -360,6 +371,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -389,6 +401,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -418,6 +431,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -447,6 +461,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -476,6 +491,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -502,6 +518,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -536,6 +553,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -559,6 +577,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -590,6 +609,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -619,6 +639,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -648,6 +669,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -671,6 +693,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -695,6 +718,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -726,6 +750,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -749,6 +774,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -782,6 +808,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -805,6 +832,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -836,6 +864,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -865,6 +894,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -894,6 +924,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -917,6 +948,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -941,6 +973,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -972,6 +1005,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -995,6 +1029,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1028,6 +1063,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1057,6 +1093,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1086,6 +1123,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1115,6 +1153,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1144,6 +1183,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1167,6 +1207,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -1191,6 +1232,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, diff --git a/tests/integration/spend/golden/daily_activity_user_paginated.json b/tests/integration/spend/golden/daily_activity_user_paginated.json index 4f7b62b3147..9ce806e48b5 100644 --- a/tests/integration/spend/golden/daily_activity_user_paginated.json +++ b/tests/integration/spend/golden/daily_activity_user_paginated.json @@ -39,6 +39,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -68,6 +69,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -97,6 +99,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -126,6 +129,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -155,6 +159,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -188,6 +193,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -217,6 +223,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -246,6 +253,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -275,6 +283,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -304,6 +313,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -327,6 +337,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -360,6 +371,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -389,6 +401,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -418,6 +431,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -447,6 +461,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -476,6 +491,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -502,6 +518,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -536,6 +553,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -559,6 +577,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -590,6 +609,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -619,6 +639,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -648,6 +669,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -671,6 +693,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -695,6 +718,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -726,6 +750,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -749,6 +774,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -782,6 +808,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -805,6 +832,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -836,6 +864,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -865,6 +894,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -894,6 +924,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -917,6 +948,7 @@ "metrics": { "api_requests": 3, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 3, "completion_tokens": 6, @@ -941,6 +973,7 @@ "metrics": { "api_requests": 0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "completion_tokens": 0, @@ -972,6 +1005,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -995,6 +1029,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1028,6 +1063,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1057,6 +1093,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1086,6 +1123,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1115,6 +1153,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 1, "completion_tokens": 2, @@ -1144,6 +1183,7 @@ "metrics": { "api_requests": 1, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 2, "completion_tokens": 2, @@ -1167,6 +1207,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, @@ -1191,6 +1232,7 @@ "metrics": { "api_requests": 5, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 6, "completion_tokens": 10, diff --git a/tests/integration/spend/test_daily_activity_routes.py b/tests/integration/spend/test_daily_activity_routes.py index 9bfe4bb50ce..972d2d87098 100644 --- a/tests/integration/spend/test_daily_activity_routes.py +++ b/tests/integration/spend/test_daily_activity_routes.py @@ -402,6 +402,7 @@ def _daily_tag_metrics( "prompt_caching_savings_spend": 0.0, "gateway_injected_caching_savings_spend": 0.0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_tokens": prompt_tokens + completion_tokens, "successful_requests": api_requests, "failed_requests": 0, diff --git a/tests/integration/spend/test_daily_rollup_retry.py b/tests/integration/spend/test_daily_rollup_retry.py index 9ed712cdd06..47a8fb8d7bf 100644 --- a/tests/integration/spend/test_daily_rollup_retry.py +++ b/tests/integration/spend/test_daily_rollup_retry.py @@ -152,6 +152,7 @@ def test_failed_daily_user_rollup_commit_is_retried_so_spend_report_and_daily_ac "prompt_caching_savings_spend": pytest.approx(0.0), "gateway_injected_caching_savings_spend": pytest.approx(0.0), "autorouter_savings_spend": pytest.approx(0.0), + "guardrail_spend": pytest.approx(0.0), "total_tokens": 40, "successful_requests": 1, "failed_requests": 0, diff --git a/tests/unit/accounting/test_projection.py b/tests/unit/accounting/test_projection.py index c78d6bec757..e618c706fac 100644 --- a/tests/unit/accounting/test_projection.py +++ b/tests/unit/accounting/test_projection.py @@ -23,8 +23,23 @@ _FIELDS: Final = TypeAdapter(dict[str, object]) @pytest.mark.parametrize("status", ["success", "failure"]) @pytest.mark.parametrize("origin", [None, "auto_router", "billed_retry"]) @pytest.mark.parametrize("spend", [0.0, 0.25]) +@pytest.mark.parametrize( + ("guardrail_information", "billed_guardrail_cost"), + [ + (None, 0.0), + ([{"guardrail_name": "guard", "guardrail_cost": 0.1}], 0.1), + ([{"guardrail_name": "guard", "guardrail_cost": 0.5}], 0.5), + ([{"guardrail_name": "guard", "guardrail_cost": 0.1, "guardrail_cost_in_spend": False}], 0.0), + ], +) @pytest.mark.asyncio -async def test_daily_projection_matches_legacy_writer(status: str, origin: str | None, spend: float) -> None: +async def test_daily_projection_matches_legacy_writer( + status: str, + origin: str | None, + spend: float, + guardrail_information: list[dict[str, object]] | None, + billed_guardrail_cost: float, +) -> None: payload: Final = get_logging_payload( kwargs={ "model": "projection-test", @@ -43,6 +58,7 @@ async def test_daily_projection_matches_legacy_writer(status: str, origin: str | **_FIELDS.validate_json(payload["metadata"]), **({BILLED_RETRY_ATTEMPT_METADATA_KEY: True} if origin == "billed_retry" else {}), **({INTERNAL_CALL_ORIGIN_METADATA_KEY: origin} if origin not in (None, "billed_retry") else {}), + **({"guardrail_information": guardrail_information} if guardrail_information is not None else {}), } row: Final = {**payload, "spend": spend, "metadata": json.dumps(metadata), "request_duration_ms": 25} legacy: Final = await DBSpendUpdateWriter()._common_add_spend_log_transaction_to_daily_transaction( @@ -60,6 +76,7 @@ async def test_daily_projection_matches_legacy_writer(status: str, origin: str | restored: Final = _FIELDS.validate_json(json.dumps(accounting, default=str)) stored_daily: Final = next(item for item in project(restored) if item.table == "LiteLLM_DailyUserSpend") assert dict(stored_daily.increments) == {name: legacy[name] for name, _ in stored_daily.increments} + assert dict(stored_daily.increments)["guardrail_spend"] == min(billed_guardrail_cost, spend) assert dict(stored_daily.key)["date"] == legacy["date"] assert dict(stored_daily.key)["api_key"] == legacy["api_key"] assert not {"messages", "response", "proxy_server_request", "requester_ip_address"}.intersection(accounting) diff --git a/tests/unit/litellm_core_utils/llm_cost_calc/test_guardrail_cost.py b/tests/unit/litellm_core_utils/llm_cost_calc/test_guardrail_cost.py index 949f55b8a82..35813996a4f 100644 --- a/tests/unit/litellm_core_utils/llm_cost_calc/test_guardrail_cost.py +++ b/tests/unit/litellm_core_utils/llm_cost_calc/test_guardrail_cost.py @@ -13,6 +13,7 @@ from litellm.litellm_core_utils.llm_cost_calc.guardrail_cost import ( cost_breakdown_with_guardrail, guardrail_cost_total, guardrail_information_cost, + guardrail_share_of_spend, ) @@ -349,3 +350,15 @@ def test_native_trace_entry_redacts_the_pii_matches_before_they_reach_spend_logs assert entry["guardrail_status"] == "guardrail_intervened" assert "123-45-6789" not in json.dumps(entry["guardrail_response"]) assert entry["guardrail_usage"]["sensitiveInformationPolicyUnits"] == 2 + + + +@pytest.mark.parametrize(("spend", "expected"), [(1.0, 0.3), (0.2, 0.2), (-1.0, 0.0)]) +def test_guardrail_share_of_spend_is_the_billed_guardrail_cost_capped_at_the_row_spend( + spend: float, expected: float +) -> None: + information: Final = [ + {"guardrail_name": "billed", "guardrail_cost": 0.3}, + {"guardrail_name": "report-only", "guardrail_cost": 0.4, "guardrail_cost_in_spend": False}, + ] + assert guardrail_share_of_spend({"guardrail_information": information}, spend) == pytest.approx(expected) diff --git a/tests/unit/proxy/db/db_transaction_queue/test_daily_spend_update_queue.py b/tests/unit/proxy/db/db_transaction_queue/test_daily_spend_update_queue.py index 79447d0fc59..497ebd3093a 100644 --- a/tests/unit/proxy/db/db_transaction_queue/test_daily_spend_update_queue.py +++ b/tests/unit/proxy/db/db_transaction_queue/test_daily_spend_update_queue.py @@ -209,6 +209,7 @@ async def test_get_aggregated_daily_spend_update_transactions_same_key(): "prompt_caching_savings_spend": 0, "gateway_injected_caching_savings_spend": 0, "autorouter_savings_spend": 0, + "guardrail_spend": 0, "total_response_time_ms": 0, "timed_requests": 0, } @@ -263,6 +264,7 @@ async def test_flush_and_get_aggregated_daily_spend_update_transactions( "prompt_caching_savings_spend": 0, "gateway_injected_caching_savings_spend": 0, "autorouter_savings_spend": 0, + "guardrail_spend": 0, "total_response_time_ms": 0, "timed_requests": 0, } diff --git a/tests/unit/proxy/db/test_daily_spend_bulk_upsert.py b/tests/unit/proxy/db/test_daily_spend_bulk_upsert.py index 5bce9137666..1b5dd90205c 100644 --- a/tests/unit/proxy/db/test_daily_spend_bulk_upsert.py +++ b/tests/unit/proxy/db/test_daily_spend_bulk_upsert.py @@ -88,10 +88,10 @@ def test_one_statement_carries_every_row_in_the_batch(): assert sql.count("INSERT INTO") == 1 assert len(re.findall(r"ON CONFLICT", sql)) == 1 - # 25 bound columns per row plus the inlined updated_at, so the row count is what + # 26 bound columns per row plus the inlined updated_at, so the row count is what # separates one multi-row statement from a hundred single-row ones. - assert len(params) == 100 * 25 - assert "$2500::text" in sql + assert len(params) == 100 * 26 + assert "$2600::text" in sql assert sql.count("(NOW() AT TIME ZONE 'UTC')") == 100 + 1 @@ -111,6 +111,7 @@ def test_conflict_target_is_the_full_unique_constraint(): "prompt_tokens", "completion_tokens", "spend", + "guardrail_spend", "api_requests", "successful_requests", "failed_requests", diff --git a/tests/unit/proxy/management_endpoints/test_common_daily_activity.py b/tests/unit/proxy/management_endpoints/test_common_daily_activity.py index bba294b571e..d38f71ee8bc 100644 --- a/tests/unit/proxy/management_endpoints/test_common_daily_activity.py +++ b/tests/unit/proxy/management_endpoints/test_common_daily_activity.py @@ -710,6 +710,7 @@ async def test_get_daily_activity_aggregated_with_endpoint_breakdown(): "prompt_caching_savings_spend": 0.0, "gateway_injected_caching_savings_spend": 0.0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_response_time_ms": 0, "timed_requests": 0, "failed_requests": 0, @@ -1294,6 +1295,7 @@ def test_update_breakdown_metrics_includes_user_email(): prompt_caching_savings_spend=0, gateway_injected_caching_savings_spend=0, autorouter_savings_spend=0, + guardrail_spend=0, total_response_time_ms=0, timed_requests=0, total_tokens=2, @@ -1375,6 +1377,7 @@ async def test_tag_daily_activity_metadata_totals_not_zero(): mock_record_1.prompt_caching_savings_spend = 0.0 mock_record_1.gateway_injected_caching_savings_spend = 0.0 mock_record_1.autorouter_savings_spend = 0.0 + mock_record_1.guardrail_spend = 0.0 mock_record_1.total_response_time_ms = 18_000 mock_record_1.timed_requests = 9 mock_record_1.api_requests = 10 @@ -1401,6 +1404,7 @@ async def test_tag_daily_activity_metadata_totals_not_zero(): mock_record_2.prompt_caching_savings_spend = 0.0 mock_record_2.gateway_injected_caching_savings_spend = 0.0 mock_record_2.autorouter_savings_spend = 0.0 + mock_record_2.guardrail_spend = 0.0 mock_record_2.total_response_time_ms = 2_500 mock_record_2.timed_requests = 5 mock_record_2.api_requests = 5 @@ -1473,6 +1477,7 @@ async def test_aggregated_activity_preserves_metadata_for_deleted_keys(): "prompt_caching_savings_spend": 0.0, "gateway_injected_caching_savings_spend": 0.0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_response_time_ms": 0, "timed_requests": 0, "failed_requests": 0, @@ -1569,6 +1574,7 @@ async def test_aggregated_activity_flags_only_keys_that_key_info_can_still_resol "prompt_caching_savings_spend": 0.0, "gateway_injected_caching_savings_spend": 0.0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_response_time_ms": 0, "timed_requests": 0, "api_requests": 1, @@ -1618,7 +1624,7 @@ async def test_aggregated_activity_flags_only_keys_that_key_info_can_still_resol assert key_breakdown["deleted-key"].metadata.key_alias == "deleted" -def _daily_user_spend_record(*, user_id, api_key, spend, model="gpt-4", model_group="gpt-4"): +def _daily_user_spend_record(*, user_id, api_key, spend, model="gpt-4", model_group="gpt-4", guardrail_spend=0.0): """A LiteLLM_DailyUserSpend row as the per-user breakdown reads it.""" return SimpleNamespace( date="2024-01-01", @@ -1639,6 +1645,7 @@ def _daily_user_spend_record(*, user_id, api_key, spend, model="gpt-4", model_gr prompt_caching_savings_spend=0.0, gateway_injected_caching_savings_spend=0.0, autorouter_savings_spend=0.0, + guardrail_spend=guardrail_spend, total_response_time_ms=0, timed_requests=0, api_requests=1, @@ -1647,6 +1654,38 @@ def _daily_user_spend_record(*, user_id, api_key, spend, model="gpt-4", model_gr ) +@pytest.mark.asyncio +async def test_paginated_activity_separates_guardrail_spend_per_model_and_key(): + records = [ + _daily_user_spend_record(user_id="u", api_key="key", spend=0.0076916, model="guarded", guardrail_spend=0.00015), + _daily_user_spend_record(user_id="u", api_key="key", spend=0.002, model="unguarded"), + ] + mock_prisma = MagicMock() + mock_prisma.db.litellm_dailyuserspend.count = AsyncMock(return_value=len(records)) + mock_prisma.db.litellm_dailyuserspend.find_many = AsyncMock(return_value=records) + mock_prisma.db.litellm_verificationtoken.find_many = AsyncMock(return_value=[]) + + result = await get_daily_activity( + prisma_client=mock_prisma, + table_name="litellm_dailyuserspend", + entity_id_field="user_id", + entity_id=None, + entity_metadata_field=None, + start_date="2024-01-01", + end_date="2024-01-01", + model=None, + api_key=None, + page=1, + page_size=1000, + ) + + models = result.results[0].breakdown.models + guarded = models["guarded"].api_key_breakdown["key"].metrics + assert guarded.spend - guarded.guardrail_spend == pytest.approx(0.0075416) + assert models["unguarded"].api_key_breakdown["key"].metrics.guardrail_spend == 0.0 + assert result.results[0].metrics.guardrail_spend == pytest.approx(0.00015) + + @pytest.mark.asyncio async def test_get_daily_activity_applies_resolve_entity_metadata_to_breakdown(): """Regression for LIT-3889: the Spend Per User chart showed raw UUIDs. @@ -1788,6 +1827,7 @@ async def test_get_daily_activity_aggregated_empty_result_set(): "prompt_caching_savings_spend": None, "gateway_injected_caching_savings_spend": None, "autorouter_savings_spend": None, + "guardrail_spend": None, "total_response_time_ms": None, "timed_requests": None, "api_requests": None, @@ -1836,6 +1876,7 @@ def _no_spend_record(): prompt_caching_savings_spend=None, gateway_injected_caching_savings_spend=None, autorouter_savings_spend=None, + guardrail_spend=None, total_response_time_ms=None, timed_requests=None, api_requests=None, @@ -1975,6 +2016,7 @@ def _spend_record(api_key, *, model="gpt-4o-mini-ptu", spend=0.0, ptu_flat_cost= prompt_caching_savings_spend=0, gateway_injected_caching_savings_spend=0, autorouter_savings_spend=0, + guardrail_spend=0, total_response_time_ms=0, timed_requests=0, total_tokens=0, @@ -2021,6 +2063,7 @@ def _grouping_row( endpoint=None, spend=0.0, ptu_flat_cost=0.0, + guardrail_spend=None, ): return GroupingSetsRow( date="2024-01-01", @@ -2043,6 +2086,7 @@ def _grouping_row( prompt_caching_savings_spend=0.0, gateway_injected_caching_savings_spend=0.0, autorouter_savings_spend=0.0, + guardrail_spend=guardrail_spend, total_response_time_ms=0, timed_requests=0, api_requests=0, @@ -2088,6 +2132,38 @@ def test_grouping_sets_dispatcher_excludes_ptu_sentinel_from_key_breakdowns(ptu_ assert "real-key" in model_bucket.api_key_breakdown +def test_model_key_breakdown_separates_guardrail_spend_from_model_spend(): + from litellm.proxy.management_endpoints.common_daily_activity import ( + _GROUP_DATE_API_KEY, + _GROUP_DATE_MODEL, + _GROUP_DATE_MODEL_API_KEY, + _GROUP_GRAND_TOTAL, + _aggregate_grouping_sets_records_sync, + ) + + records = [ + _grouping_row(_GROUP_DATE_MODEL, model="guarded", spend=0.0076916, guardrail_spend=0.00015), + _grouping_row(_GROUP_DATE_MODEL, model="unguarded", spend=0.002), + _grouping_row( + _GROUP_DATE_MODEL_API_KEY, model="guarded", api_key="key", spend=0.0076916, guardrail_spend=0.00015 + ), + _grouping_row(_GROUP_DATE_MODEL_API_KEY, model="unguarded", api_key="key", spend=0.002), + _grouping_row(_GROUP_DATE_API_KEY, api_key="key", spend=0.0096916, guardrail_spend=0.00015), + _grouping_row(_GROUP_GRAND_TOTAL, spend=0.0096916, guardrail_spend=0.00015), + ] + + aggregated = _aggregate_grouping_sets_records_sync(records=records, api_key_metadata={}) + day = aggregated["results"][0] + + guarded = day.breakdown.models["guarded"].api_key_breakdown["key"].metrics + unguarded = day.breakdown.models["unguarded"].api_key_breakdown["key"].metrics + assert guarded.spend - guarded.guardrail_spend == pytest.approx(0.0075416) + assert unguarded.guardrail_spend == 0.0 + assert day.breakdown.models["guarded"].metrics.guardrail_spend == pytest.approx(0.00015) + assert day.breakdown.api_keys["key"].metrics.guardrail_spend == pytest.approx(0.00015) + assert aggregated["totals"].guardrail_spend == pytest.approx(0.00015) + + def test_grouping_sets_dispatcher_populates_every_breakdown_level(ptu_cost_attribution_enabled): """Every GROUPING SETS level lands in its bucket, and the flat-cost sentinel is kept out of the model_group and provider api_key sub-breakdowns too.""" @@ -2205,6 +2281,7 @@ def test_update_breakdown_metrics_covers_mcp_endpoint_and_entity(ptu_cost_attrib prompt_caching_savings_spend=0, gateway_injected_caching_savings_spend=0, autorouter_savings_spend=0, + guardrail_spend=0, total_response_time_ms=0, timed_requests=0, total_tokens=0, @@ -2560,6 +2637,7 @@ async def test_get_daily_activity_aggregated_with_entity_breakdown(): "prompt_caching_savings_spend": 0.0, "gateway_injected_caching_savings_spend": 0.0, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_response_time_ms": 0, "timed_requests": 0, "failed_requests": 0, diff --git a/tests/unit/proxy/management_endpoints/test_daily_activity_routes.py b/tests/unit/proxy/management_endpoints/test_daily_activity_routes.py index 9cd2bab07f0..23ad9efdc70 100644 --- a/tests/unit/proxy/management_endpoints/test_daily_activity_routes.py +++ b/tests/unit/proxy/management_endpoints/test_daily_activity_routes.py @@ -67,6 +67,7 @@ class _Activity: prompt_caching_savings_spend: float gateway_injected_caching_savings_spend: float autorouter_savings_spend: float + guardrail_spend: float api_requests: int successful_requests: int failed_requests: int @@ -109,6 +110,7 @@ def _activity_for_entity( prompt_caching_savings_spend=0.2, gateway_injected_caching_savings_spend=0.3, autorouter_savings_spend=0.4, + guardrail_spend=0.5, api_requests=1, successful_requests=1, failed_requests=0, @@ -165,6 +167,7 @@ def _seeded_activity() -> tuple[_Activity, ...]: prompt_caching_savings_spend=0.0, gateway_injected_caching_savings_spend=0.0, autorouter_savings_spend=0.0, + guardrail_spend=0.0, api_requests=1, successful_requests=1, failed_requests=0, @@ -188,6 +191,7 @@ def _metrics(rows: Sequence[_Activity]) -> Mapping[str, int | float]: "prompt_caching_savings_spend": sum(row.prompt_caching_savings_spend for row in rows), "gateway_injected_caching_savings_spend": sum(row.gateway_injected_caching_savings_spend for row in rows), "autorouter_savings_spend": sum(row.autorouter_savings_spend for row in rows), + "guardrail_spend": sum(row.guardrail_spend for row in rows), "api_requests": sum(row.api_requests for row in rows), "successful_requests": sum(row.successful_requests for row in rows), "failed_requests": sum(row.failed_requests for row in rows), @@ -791,6 +795,7 @@ def test_search_folds_each_entity_key_across_days( "prompt_caching_savings_spend": 0.4, "gateway_injected_caching_savings_spend": 0.6, "autorouter_savings_spend": 0.8, + "guardrail_spend": 1.0, "total_tokens": 30, "successful_requests": 2, "failed_requests": 0, diff --git a/tests/unit/proxy/management_endpoints/test_team_endpoints.py b/tests/unit/proxy/management_endpoints/test_team_endpoints.py index 83a121da21a..a79ebd307fe 100644 --- a/tests/unit/proxy/management_endpoints/test_team_endpoints.py +++ b/tests/unit/proxy/management_endpoints/test_team_endpoints.py @@ -19308,6 +19308,7 @@ def _db_with_one_ptu_hour_of_team_spend(team_id: str) -> MagicMock: prompt_caching_savings_spend=0.0, gateway_injected_caching_savings_spend=0.0, autorouter_savings_spend=0.0, + guardrail_spend=0.0, total_response_time_ms=0, timed_requests=0, api_requests=3, diff --git a/tests/unit/repositories/test_daily_activity_repository.py b/tests/unit/repositories/test_daily_activity_repository.py index b68bb948b7b..bca18c15d61 100644 --- a/tests/unit/repositories/test_daily_activity_repository.py +++ b/tests/unit/repositories/test_daily_activity_repository.py @@ -675,6 +675,7 @@ async def test_customer_team_page_returns_loaded_metrics_and_retains_count_on_em "prompt_caching_savings_spend": 0.25, "gateway_injected_caching_savings_spend": 0.125, "autorouter_savings_spend": 0.0, + "guardrail_spend": 0.0, "total_response_time_ms": 10, "timed_requests": 1, "created_at": "2026-01-01T00:00:00Z", diff --git a/tests/unit/repositories/test_daily_activity_sql.py b/tests/unit/repositories/test_daily_activity_sql.py index f8375b93dad..051db54a161 100644 --- a/tests/unit/repositories/test_daily_activity_sql.py +++ b/tests/unit/repositories/test_daily_activity_sql.py @@ -284,6 +284,7 @@ def test_aggregated_query_uses_the_caller_date_bounds(offset_minutes: int | None def test_aggregate_query_sums_all_savings_drivers_and_response_time() -> None: query = build_aggregated_sql(_scope(), api_key_limit=constants.USAGE_TOP_API_KEYS_DEFAULT) fields: Final = tuple(field for field in SpendMetrics.model_fields if field.endswith("_savings_spend")) + ( + "guardrail_spend", "total_response_time_ms", "timed_requests", ) diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CacheLeakageCard.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CacheLeakageCard.test.tsx index 95abc4e22cb..e87fbbf79d1 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CacheLeakageCard.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CacheLeakageCard.test.tsx @@ -36,6 +36,7 @@ const baseMetrics = (overrides: Partial): components["schemas"]["S prompt_caching_savings_spend: 0, gateway_injected_caching_savings_spend: 0, autorouter_savings_spend: 0, + guardrail_spend: 0, total_response_time_ms: 0, timed_requests: 0, ...overrides, diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.test.ts index 1a92f1d1bc8..3f17685f295 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.test.ts @@ -88,6 +88,26 @@ describe("client usage from request logs", () => { expect(day?.date).toBe(localDay); }); + it("should report guardrail spend inside model spend, capped at what each request was charged", () => { + const guarded = (request_id: string, spend: number, guardrail_information: unknown) => + log({ request_id, spend, metadata: { user_agent: desktopAgent, guardrail_information } }); + const result = clientUsageFromLogs( + page([ + guarded("billed", 0.0076916, [ + { guardrail_cost: 0.00015 }, + { guardrail_cost: 0.0004, guardrail_cost_in_spend: false }, + ]), + guarded("capped", 0.0001, { guardrail_cost: 0.0003 }), + guarded("malformed", 0.002, [{ guardrail_cost: "free" }]), + log(), + ]), + scope, + ); + expect(result.error).toBeNull(); + const metrics = result.data.results?.[0]?.breakdown?.models?.["provider-model"].metrics; + expect(metrics?.guardrail_spend).toBeCloseTo(0.00025, 10); + }); + it("should deduplicate request ids without double counting bare and full user-agent tags", () => { const result = clientUsageFromLogs(page([log(), log({ spend: 0.02 })]), scope); expect(result.data.metadata?.total_api_requests).toBe(1); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.ts b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.ts index 998dfd2b271..996efd06061 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/hooks/clientUsageData.ts @@ -31,11 +31,19 @@ const usageFields = { input_tokens_details: cacheDetailsSchema.nullish(), }; const usageSchema = z.object(usageFields); +const guardrailEntrySchema = z.object({ + guardrail_cost: z.number().finite().nullish().catch(null), + guardrail_cost_in_spend: z.boolean().nullish().catch(null), +}); const metadataFields = { user_agent: z.string().nullish(), status: z.string().nullish(), additional_usage_values: usageSchema.nullish(), usage_object: usageSchema.nullish(), + guardrail_information: z + .union([z.array(guardrailEntrySchema), guardrailEntrySchema]) + .nullish() + .catch(null), }; const logFields = { request_id: z.string().min(1), @@ -127,6 +135,19 @@ const cacheTokens = (row: ClientLog) => { cacheCreationTokens: additional.cacheCreationTokens ?? usage.cacheCreationTokens, }; }; +const billedGuardrailCost = (entry: z.infer) => + entry.guardrail_cost_in_spend === false ? 0 : Math.max(entry.guardrail_cost ?? 0, 0); +type GuardrailInformation = NonNullable["guardrail_information"]>; +const guardrailEntries = (information: GuardrailInformation) => + Array.isArray(information) ? information : [information]; +const guardrailSpend = (row: ClientLog) => { + const information = row.metadata?.guardrail_information; + const entries = information == null ? [] : guardrailEntries(information); + return Math.min( + entries.reduce((total, entry) => total + billedGuardrailCost(entry), 0), + Math.max(row.spend, 0), + ); +}; const sum = (rows: readonly ClientLog[], value: (row: ClientLog) => number) => rows.reduce((total, row) => total + value(row), 0); const metricsFor = (rows: readonly ClientLog[]): SpendMetrics => ({ @@ -137,6 +158,7 @@ const metricsFor = (rows: readonly ClientLog[]): SpendMetrics => ({ prompt_caching_savings_spend: 0, gateway_injected_caching_savings_spend: 0, autorouter_savings_spend: 0, + guardrail_spend: sum(rows, guardrailSpend), spend: sum(rows, (row) => row.spend), prompt_tokens: sum(rows, (row) => row.prompt_tokens), completion_tokens: sum(rows, (row) => row.completion_tokens), diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index ddf6eb21c63..bd5e87bcbdd 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -47697,6 +47697,12 @@ export interface components { * @default 0 */ gateway_injected_caching_savings_spend: number; + /** + * Guardrail Spend + * @description Guardrail spend in USD, already included in spend, so model spend is spend - guardrail_spend. Rows recorded before this field existed report 0 even when their spend includes guardrail cost + * @default 0 + */ + guardrail_spend: number; /** * Prompt Caching Savings Spend * @default 0