2024-01-06 17:29:10 +08:00
datasource client {
provider = "postgresql"
url = env("DATABASE_URL")
}
2024-03-29 03:25:28 +08:00
generator client {
provider = "prisma-client-py"
2026-02-01 07:07:28 +08:00
binaryTargets = ["native", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "linux-musl", "linux-musl-openssl-3.0.x"]
2024-03-29 03:25:28 +08:00
}
2024-03-03 03:59:17 +08:00
// Budget / Rate Limits for an org
model LiteLLM_BudgetTable {
budget_id String @id @default(uuid())
max_budget Float?
2024-03-03 04:25:40 +08:00
soft_budget Float?
2024-03-03 03:59:17 +08:00
max_parallel_requests Int?
tpm_limit BigInt?
rpm_limit BigInt?
2024-03-03 06:38:42 +08:00
model_max_budget Json?
2025-06-26 13:37:45 +08:00
budget_duration String?
2024-03-03 03:59:17 +08:00
budget_reset_at DateTime?
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
updated_by String
2024-03-03 04:18:28 +08:00
organization LiteLLM_OrganizationTable[] // multiple orgs can have the same budget
2025-11-13 06:38:15 +08:00
projects LiteLLM_ProjectTable[] // multiple projects can have the same budget
2024-03-03 10:34:18 +08:00
keys LiteLLM_VerificationToken[] // multiple keys can have the same budget
2024-03-17 03:26:29 +08:00
end_users LiteLLM_EndUserTable[] // multiple end-users can have the same budget
2025-10-11 10:24:50 +08:00
tags LiteLLM_TagTable[] // multiple tags can have the same budget
2025-06-26 13:37:45 +08:00
team_membership LiteLLM_TeamMembership[] // budgets of Users within a Team
organization_membership LiteLLM_OrganizationMembership[] // budgets of Users within a Organization
2024-03-03 03:59:17 +08:00
}
2025-03-11 09:27:43 +08:00
// Models on proxy
model LiteLLM_CredentialsTable {
credential_id String @id @default(uuid())
credential_name String @unique
credential_values Json
2025-06-26 13:37:45 +08:00
credential_info Json?
2025-03-11 09:27:43 +08:00
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
updated_by String
}
2024-04-04 11:17:34 +08:00
// Models on proxy
model LiteLLM_ProxyModelTable {
model_id String @id @default(uuid())
2025-06-26 13:37:45 +08:00
model_name String
2024-04-04 11:17:34 +08:00
litellm_params Json
2025-06-26 13:37:45 +08:00
model_info Json?
2024-04-04 11:17:34 +08:00
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
2025-11-15 10:23:30 +08:00
updated_by String
}
// Agents on proxy
model LiteLLM_AgentsTable {
agent_id String @id @default(uuid())
agent_name String @unique
litellm_params Json?
agent_card_params Json
2026-03-07 15:39:08 +08:00
static_headers Json? @default("{}")
extra_headers String[] @default([])
2025-12-05 08:31:00 +08:00
agent_access_groups String[] @default([])
2026-02-26 03:44:30 +08:00
object_permission_id String?
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2026-03-08 11:12:42 +08:00
spend Float @default(0.0)
tpm_limit Int?
rpm_limit Int?
session_tpm_limit Int?
session_rpm_limit Int?
2025-11-15 10:23:30 +08:00
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
2024-04-04 11:17:34 +08:00
updated_by String
}
2024-03-03 03:59:17 +08:00
model LiteLLM_OrganizationTable {
organization_id String @id @default(uuid())
2024-03-03 04:18:28 +08:00
organization_alias String
2024-03-03 03:59:17 +08:00
budget_id String
metadata Json @default("{}")
models String[]
spend Float @default(0.0)
model_spend Json @default("{}")
2025-05-08 12:09:51 +08:00
object_permission_id String?
2024-03-03 03:59:17 +08:00
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
updated_by String
2024-03-03 04:18:28 +08:00
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
2025-06-26 13:37:45 +08:00
teams LiteLLM_TeamTable[]
2024-04-09 11:45:11 +08:00
users LiteLLM_UserTable[]
2025-02-11 11:13:32 +08:00
keys LiteLLM_VerificationToken[]
2025-01-05 09:31:24 +08:00
members LiteLLM_OrganizationMembership[] @relation("OrganizationToMembership")
2025-05-08 12:09:51 +08:00
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2024-03-03 03:59:17 +08:00
}
2024-03-07 10:55:40 +08:00
// Model info for teams, just has model aliases for now.
model LiteLLM_ModelTable {
id Int @id @default(autoincrement())
model_aliases Json? @map("aliases")
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
updated_by String
team LiteLLM_TeamTable?
}
2024-03-27 08:03:21 +08:00
2025-06-26 13:37:45 +08:00
// Assign prod keys to groups, not individuals
2024-02-15 09:20:41 +08:00
model LiteLLM_TeamTable {
2024-03-03 03:59:17 +08:00
team_id String @id @default(uuid())
2025-06-26 13:37:45 +08:00
team_alias String?
2024-03-03 03:59:17 +08:00
organization_id String?
2025-05-08 12:09:51 +08:00
object_permission_id String?
2024-02-15 09:20:41 +08:00
admins String[]
members String[]
2024-02-22 05:29:42 +08:00
members_with_roles Json @default("{}")
2024-02-15 09:20:41 +08:00
metadata Json @default("{}")
max_budget Float?
2026-02-06 06:43:48 +08:00
soft_budget Float?
2024-02-15 09:20:41 +08:00
spend Float @default(0.0)
models String[]
max_parallel_requests Int?
tpm_limit BigInt?
rpm_limit BigInt?
2025-06-26 13:37:45 +08:00
budget_duration String?
2024-02-15 09:20:41 +08:00
budget_reset_at DateTime?
2024-03-27 08:03:21 +08:00
blocked Boolean @default(false)
2024-02-15 09:20:41 +08:00
created_at DateTime @default(now()) @map("created_at")
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
2024-02-17 08:32:17 +08:00
model_spend Json @default("{}")
model_max_budget Json @default("{}")
2026-01-06 08:19:42 +08:00
router_settings Json? @default("{}")
2025-04-13 00:06:04 +08:00
team_member_permissions String[] @default([])
2026-02-13 04:30:22 +08:00
access_group_ids String[] @default([])
2026-01-24 05:16:58 +08:00
policies String[] @default([])
2024-06-09 10:03:45 +08:00
model_id Int? @unique // id for LiteLLM_ModelTable -> stores team-level model aliases
2026-02-05 11:51:20 +08:00
allow_team_guardrail_config Boolean @default(false) // if true, team admin can configure guardrails for this team
2024-03-03 04:18:28 +08:00
litellm_organization_table LiteLLM_OrganizationTable? @relation(fields: [organization_id], references: [organization_id])
2024-03-07 10:55:40 +08:00
litellm_model_table LiteLLM_ModelTable? @relation(fields: [model_id], references: [id])
2025-05-08 12:09:51 +08:00
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2025-11-13 06:38:15 +08:00
projects LiteLLM_ProjectTable[]
2026-03-18 11:34:15 +08:00
@@index([organization_id])
@@index([team_alias])
@@index([created_at])
2025-11-13 06:38:15 +08:00
}
// Projects sit between teams and keys for use-case management
model LiteLLM_ProjectTable {
project_id String @id @default(uuid())
project_alias String?
2025-11-13 06:58:38 +08:00
description String?
2025-11-13 06:38:15 +08:00
team_id String?
budget_id String?
metadata Json @default("{}")
models String[]
spend Float @default(0.0)
model_spend Json @default("{}")
2025-11-13 06:58:38 +08:00
model_rpm_limit Json @default("{}")
model_tpm_limit Json @default("{}")
2025-11-13 06:38:15 +08:00
blocked Boolean @default(false)
object_permission_id String?
created_at DateTime @default(now()) @map("created_at")
created_by String
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
updated_by String
// Relations
litellm_team_table LiteLLM_TeamTable? @relation(fields: [team_id], references: [team_id])
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
keys LiteLLM_VerificationToken[]
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2024-02-15 09:20:41 +08:00
}
2026-01-17 06:25:23 +08:00
// Audit table for deleted teams - preserves spend and team information for historical tracking
model LiteLLM_DeletedTeamTable {
id String @id @default(uuid())
team_id String // Original team_id
team_alias String?
organization_id String?
object_permission_id String?
admins String[]
members String[]
members_with_roles Json @default("{}")
metadata Json @default("{}")
max_budget Float?
2026-02-08 03:05:42 +08:00
soft_budget Float?
2026-01-17 06:25:23 +08:00
spend Float @default(0.0)
models String[]
max_parallel_requests Int?
tpm_limit BigInt?
rpm_limit BigInt?
budget_duration String?
budget_reset_at DateTime?
blocked Boolean @default(false)
model_spend Json @default("{}")
model_max_budget Json @default("{}")
router_settings Json? @default("{}")
team_member_permissions String[] @default([])
2026-02-13 04:30:22 +08:00
access_group_ids String[] @default([])
2026-01-24 05:16:58 +08:00
policies String[] @default([])
2026-01-17 06:25:23 +08:00
model_id Int? // id for LiteLLM_ModelTable -> stores team-level model aliases
2026-02-05 11:51:20 +08:00
allow_team_guardrail_config Boolean @default(false)
2026-02-15 01:49:11 +08:00
2026-01-17 06:25:23 +08:00
// Original timestamps from team creation/updates
created_at DateTime? @map("created_at")
updated_at DateTime? @map("updated_at")
// Deletion metadata
deleted_at DateTime @default(now()) @map("deleted_at")
deleted_by String? @map("deleted_by") // User who deleted the team
deleted_by_api_key String? @map("deleted_by_api_key") // API key hash that performed the deletion
litellm_changed_by String? @map("litellm_changed_by") // From litellm-changed-by header if provided
@@index([team_id])
@@index([deleted_at])
@@index([organization_id])
@@index([team_alias])
@@index([created_at])
}
2024-01-25 09:15:01 +08:00
// Track spend, rate limit, budget Users
2024-01-06 17:29:10 +08:00
model LiteLLM_UserTable {
2024-03-03 03:59:17 +08:00
user_id String @id
2025-06-26 13:37:45 +08:00
user_alias String?
2024-01-19 06:42:46 +08:00
team_id String?
2025-02-01 15:04:51 +08:00
sso_user_id String? @unique
2024-04-09 11:45:11 +08:00
organization_id String?
2025-05-08 12:09:51 +08:00
object_permission_id String?
2024-05-28 11:32:25 +08:00
password String?
2024-02-22 05:29:42 +08:00
teams String[] @default([])
2024-02-04 02:23:50 +08:00
user_role String?
2024-01-06 17:29:10 +08:00
max_budget Float?
spend Float @default(0.0)
user_email String?
2024-01-18 07:45:31 +08:00
models String[]
2024-09-24 08:49:36 +08:00
metadata Json @default("{}")
2024-01-19 09:03:18 +08:00
max_parallel_requests Int?
tpm_limit BigInt?
rpm_limit BigInt?
2025-06-26 13:37:45 +08:00
budget_duration String?
2024-01-25 06:27:13 +08:00
budget_reset_at DateTime?
2024-01-31 13:17:01 +08:00
allowed_cache_controls String[] @default([])
2026-01-24 05:16:58 +08:00
policies String[] @default([])
2024-02-17 08:32:17 +08:00
model_spend Json @default("{}")
model_max_budget Json @default("{}")
2024-12-08 11:08:37 +08:00
created_at DateTime? @default(now()) @map("created_at")
updated_at DateTime? @default(now()) @updatedAt @map("updated_at")
2024-10-09 17:48:18 +08:00
// relations
litellm_organization_table LiteLLM_OrganizationTable? @relation(fields: [organization_id], references: [organization_id])
organization_memberships LiteLLM_OrganizationMembership[]
2024-05-28 11:32:25 +08:00
invitations_created LiteLLM_InvitationLink[] @relation("CreatedBy")
invitations_updated LiteLLM_InvitationLink[] @relation("UpdatedBy")
invitations_user LiteLLM_InvitationLink[] @relation("UserId")
2025-05-08 12:09:51 +08:00
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
}
model LiteLLM_ObjectPermissionTable {
object_permission_id String @id @default(uuid())
mcp_servers String[] @default([])
2025-07-11 12:59:25 +08:00
mcp_access_groups String[] @default([])
2025-10-07 09:49:32 +08:00
mcp_tool_permissions Json? // Tool-level permissions for MCP servers. Format: {"server_id": ["tool_name_1", "tool_name_2"]}
2025-05-29 07:58:53 +08:00
vector_stores String[] @default([])
2025-12-05 08:31:00 +08:00
agents String[] @default([])
agent_access_groups String[] @default([])
2026-03-11 12:03:20 +08:00
models String[] @default([])
2026-03-04 12:22:20 +08:00
blocked_tools String[] @default([]) // Tool names blocked for any key/team/user with this permission
2025-05-08 12:09:51 +08:00
teams LiteLLM_TeamTable[]
2025-11-13 06:38:15 +08:00
projects LiteLLM_ProjectTable[]
2025-05-08 12:09:51 +08:00
verification_tokens LiteLLM_VerificationToken[]
organizations LiteLLM_OrganizationTable[]
users LiteLLM_UserTable[]
2026-02-19 10:53:59 +08:00
end_users LiteLLM_EndUserTable[]
2026-02-26 03:44:30 +08:00
agents_table LiteLLM_AgentsTable[]
2025-05-08 12:09:51 +08:00
}
2025-06-26 13:37:45 +08:00
// Holds the MCP server configuration
2025-05-08 12:09:51 +08:00
model LiteLLM_MCPServerTable {
2025-07-12 11:25:26 +08:00
server_id String @id @default(uuid())
2025-07-26 08:57:52 +08:00
server_name String?
2025-07-12 11:25:26 +08:00
alias String?
description String?
url String?
2026-03-05 08:07:05 +08:00
spec_path String?
2025-07-12 11:25:26 +08:00
transport String @default("sse")
auth_type String?
2025-11-08 11:22:49 +08:00
credentials Json? @default("{}")
2025-07-12 11:25:26 +08:00
created_at DateTime? @default(now()) @map("created_at")
created_by String?
updated_at DateTime? @default(now()) @updatedAt @map("updated_at")
updated_by String?
mcp_info Json? @default("{}")
2025-07-11 12:59:25 +08:00
mcp_access_groups String[]
2025-10-04 01:16:29 +08:00
allowed_tools String[] @default([])
2026-03-07 15:39:08 +08:00
tool_name_to_display_name Json? @default("{}")
tool_name_to_description Json? @default("{}")
2025-10-04 10:07:50 +08:00
extra_headers String[] @default([])
2025-11-04 13:06:36 +08:00
static_headers Json? @default("{}")
2025-07-30 23:10:44 +08:00
// Health check status
status String? @default("unknown")
last_health_check DateTime?
health_check_error String?
2025-07-12 11:25:26 +08:00
// Stdio-specific fields
command String?
args String[] @default([])
env Json? @default("{}")
2026-01-02 13:07:58 +08:00
authorization_url String?
token_url String?
registration_url String?
2026-01-05 14:49:09 +08:00
allow_all_keys Boolean @default(false)
2026-02-28 12:06:07 +08:00
available_on_public_internet Boolean @default(true)
2026-03-07 15:39:08 +08:00
is_byok Boolean @default(false)
byok_description String[] @default([])
byok_api_key_help_url String?
}
// Per-user BYOK credentials for MCP servers
model LiteLLM_MCPUserCredentials {
id String @id @default(uuid())
user_id String
server_id String
credential_b64 String
created_at DateTime @default(now()) @map("created_at")
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
@@unique([user_id, server_id])
2024-01-06 17:29:10 +08:00
}
2024-01-25 09:15:01 +08:00
// Generate Tokens for Proxy
2024-01-06 17:29:10 +08:00
model LiteLLM_VerificationToken {
2024-03-03 03:59:17 +08:00
token String @id
2024-01-27 12:53:03 +08:00
key_name String?
key_alias String?
2024-03-03 10:34:18 +08:00
soft_budget_cooldown Boolean @default(false) // key-level state on if budget alerts need to be cooled down
2024-01-06 17:29:10 +08:00
spend Float @default(0.0)
expires DateTime?
models String[]
aliases Json @default("{}")
config Json @default("{}")
2026-01-06 08:19:42 +08:00
router_settings Json? @default("{}")
2024-01-06 17:29:10 +08:00
user_id String?
2024-01-19 05:34:51 +08:00
team_id String?
2026-02-26 03:44:30 +08:00
agent_id String?
2025-11-13 06:38:15 +08:00
project_id String?
2024-02-16 13:29:34 +08:00
permissions Json @default("{}")
2024-01-06 17:29:10 +08:00
max_parallel_requests Int?
metadata Json @default("{}")
2024-09-21 10:40:40 +08:00
blocked Boolean?
2024-01-19 09:03:18 +08:00
tpm_limit BigInt?
rpm_limit BigInt?
2025-06-26 13:37:45 +08:00
max_budget Float?
budget_duration String?
2024-01-24 04:33:13 +08:00
budget_reset_at DateTime?
2024-01-31 13:17:01 +08:00
allowed_cache_controls String[] @default([])
2025-04-17 10:21:47 +08:00
allowed_routes String[] @default([])
2026-01-24 05:16:58 +08:00
policies String[] @default([])
2026-02-13 04:30:22 +08:00
access_group_ids String[] @default([])
2024-02-17 07:44:34 +08:00
model_spend Json @default("{}")
model_max_budget Json @default("{}")
2024-03-03 04:25:40 +08:00
budget_id String?
2025-05-27 13:03:18 +08:00
organization_id String?
2025-05-08 12:09:51 +08:00
object_permission_id String?
2024-10-25 11:19:29 +08:00
created_at DateTime? @default(now()) @map("created_at")
2025-02-28 10:12:58 +08:00
created_by String?
2024-10-25 11:19:29 +08:00
updated_at DateTime? @default(now()) @updatedAt @map("updated_at")
2025-02-28 10:12:58 +08:00
updated_by String?
2026-02-19 15:11:58 +08:00
last_active DateTime? // When this key was last used
2025-09-25 12:37:56 +08:00
rotation_count Int? @default(0) // Number of times key has been rotated
auto_rotate Boolean? @default(false) // Whether this key should be auto-rotated
rotation_interval String? // How often to rotate (e.g., "30d", "90d")
last_rotation_at DateTime? // When this key was last rotated
2025-09-27 07:24:40 +08:00
key_rotation_at DateTime? // When this key should next be rotated
2024-03-03 10:34:18 +08:00
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
2025-02-11 11:13:32 +08:00
litellm_organization_table LiteLLM_OrganizationTable? @relation(fields: [organization_id], references: [organization_id])
2025-11-13 06:38:15 +08:00
litellm_project_table LiteLLM_ProjectTable? @relation(fields: [project_id], references: [project_id])
2025-05-08 12:09:51 +08:00
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2026-03-07 15:39:08 +08:00
jwt_key_mappings LiteLLM_JWTKeyMapping[]
2026-02-01 07:07:47 +08:00
// SELECT COUNT(*) FROM (SELECT "public"."LiteLLM_VerificationToken"."token" FROM "public"."LiteLLM_VerificationToken" WHERE ("public"."LiteLLM_VerificationToken"."user_id" = $1 AND ("public"."LiteLLM_VerificationToken"."team_id" IS NULL OR "public"."LiteLLM_VerificationToken"."team_id" <> $2)) OFFSET $3 ) AS "sub"
// SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE "public"."LiteLLM_VerificationToken"."user_id" = $1 OFFSET $2
@@index([user_id, team_id])
// SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE "public"."LiteLLM_VerificationToken"."team_id" = $1 OFFSET $2
@@index([team_id])
// SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE (("public"."LiteLLM_VerificationToken"."expires" IS NULL OR "public"."LiteLLM_VerificationToken"."expires" > $1) AND "public"."LiteLLM_VerificationToken"."budget_reset_at" < $2) OFFSET $3
@@index([budget_reset_at, expires])
2024-01-06 17:29:10 +08:00
}
2026-03-07 15:39:08 +08:00
model LiteLLM_JWTKeyMapping {
id String @id @default(uuid())
jwt_claim_name String // e.g. "sub", "email"
jwt_claim_value String // The claim value to match
token String // Hashed virtual key (FK)
description String?
is_active Boolean @default(true)
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
litellm_verification_token LiteLLM_VerificationToken @relation(fields: [token], references: [token])
@@unique([jwt_claim_name, jwt_claim_value])
@@index([jwt_claim_name, jwt_claim_value, is_active])
}
2026-02-03 12:20:10 +08:00
// Deprecated keys during grace period - allows old key to work until revoke_at
model LiteLLM_DeprecatedVerificationToken {
id String @id @default(uuid())
token String // Hashed old key
active_token_id String // Current token hash in LiteLLM_VerificationToken
revoke_at DateTime // When the old key stops working
created_at DateTime @default(now()) @map("created_at")
@@unique([token])
@@index([token, revoke_at])
@@index([revoke_at])
}
2026-01-17 06:25:23 +08:00
// Audit table for deleted keys - preserves spend and key information for historical tracking
model LiteLLM_DeletedVerificationToken {
id String @id @default(uuid())
token String // Original token (hashed)
key_name String?
key_alias String?
soft_budget_cooldown Boolean @default(false)
spend Float @default(0.0)
expires DateTime?
models String[]
aliases Json @default("{}")
config Json @default("{}")
user_id String?
team_id String?
2026-02-27 12:29:43 +08:00
agent_id String?
2026-02-20 02:50:23 +08:00
project_id String?
2026-01-17 06:25:23 +08:00
permissions Json @default("{}")
max_parallel_requests Int?
metadata Json @default("{}")
blocked Boolean?
tpm_limit BigInt?
rpm_limit BigInt?
max_budget Float?
budget_duration String?
budget_reset_at DateTime?
allowed_cache_controls String[] @default([])
allowed_routes String[] @default([])
2026-01-24 05:16:58 +08:00
policies String[] @default([])
2026-02-13 04:30:22 +08:00
access_group_ids String[] @default([])
2026-01-17 06:25:23 +08:00
model_spend Json @default("{}")
model_max_budget Json @default("{}")
router_settings Json? @default("{}")
budget_id String?
organization_id String?
object_permission_id String?
created_at DateTime? // Original creation timestamp
created_by String? // Original creator
updated_at DateTime? // Last update timestamp before deletion
updated_by String? // Last user who updated before deletion
2026-02-19 15:11:58 +08:00
last_active DateTime? // When this key was last used before deletion
2026-01-17 06:25:23 +08:00
rotation_count Int? @default(0)
auto_rotate Boolean? @default(false)
rotation_interval String?
last_rotation_at DateTime?
key_rotation_at DateTime?
2026-02-15 01:49:11 +08:00
2026-01-17 06:25:23 +08:00
// Deletion metadata
deleted_at DateTime @default(now()) @map("deleted_at")
deleted_by String? @map("deleted_by") // User who deleted the key
deleted_by_api_key String? @map("deleted_by_api_key") // API key hash that performed the deletion
litellm_changed_by String? @map("litellm_changed_by") // From litellm-changed-by header if provided
@@index([token])
@@index([deleted_at])
@@index([user_id])
@@index([team_id])
@@index([organization_id])
@@index([key_alias])
@@index([created_at])
}
2024-03-17 03:26:29 +08:00
model LiteLLM_EndUserTable {
2024-03-17 05:15:01 +08:00
user_id String @id
2024-03-17 03:26:29 +08:00
alias String? // admin-facing alias
spend Float @default(0.0)
2024-05-09 09:50:36 +08:00
allowed_model_region String? // require all user requests to use models in this specific region
default_model String? // use along with 'allowed_model_region'. if no available model in region, default to this model.
2024-03-17 03:26:29 +08:00
budget_id String?
2026-02-19 10:53:59 +08:00
object_permission_id String?
2024-03-17 03:26:29 +08:00
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
2026-02-19 10:53:59 +08:00
object_permission LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
2024-03-17 03:26:29 +08:00
blocked Boolean @default(false)
}
2025-10-11 10:24:50 +08:00
// Track tags with budgets and spend
model LiteLLM_TagTable {
tag_name String @id
description String?
models String[]
model_info Json? // maps model_id to model_name
spend Float @default(0.0)
budget_id String?
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
created_at DateTime @default(now()) @map("created_at")
created_by String?
updated_at DateTime @default(now()) @updatedAt @map("updated_at")
}
2024-01-25 09:15:01 +08:00
// store proxy config.yaml
2024-01-06 17:29:10 +08:00
model LiteLLM_Config {
param_name String @id
param_value Json?
2024-01-19 02:04:34 +08:00
}
2024-01-25 09:15:01 +08:00
// View spend, model, api_key per request
2024-01-19 02:04:34 +08:00
model LiteLLM_SpendLogs {
2024-03-03 03:59:17 +08:00
request_id String @id
2024-01-19 02:04:34 +08:00
call_type String
2024-07-24 07:33:04 +08:00
api_key String @default ("") // Hashed API Token. Not the actual Virtual Key. Equivalent to 'token' column in LiteLLM_VerificationToken
2024-01-19 05:16:25 +08:00
spend Float @default(0.0)
2024-01-27 05:23:51 +08:00
total_tokens Int @default(0)
prompt_tokens Int @default(0)
completion_tokens Int @default(0)
2024-01-19 02:04:34 +08:00
startTime DateTime // Assuming start_time is a DateTime field
endTime DateTime // Assuming end_time is a DateTime field
2026-02-25 13:04:53 +08:00
request_duration_ms Int?
2024-05-23 07:43:08 +08:00
completionStartTime DateTime? // Assuming completionStartTime is a DateTime field
2024-01-19 02:04:34 +08:00
model String @default("")
2024-05-23 08:29:44 +08:00
model_id String? @default("") // the model id stored in proxy model db
model_group String? @default("") // public model_name / model_group
2024-12-08 05:40:22 +08:00
custom_llm_provider String? @default("") // litellm used custom_llm_provider
2024-07-24 07:33:04 +08:00
api_base String? @default("")
user String? @default("")
2025-11-13 06:38:15 +08:00
metadata Json? @default("{}") // project_id stored here
2024-07-24 07:33:04 +08:00
cache_hit String? @default("")
cache_key String? @default("")
request_tags Json? @default("[]")
2025-06-26 13:37:45 +08:00
team_id String?
2025-11-23 04:54:49 +08:00
organization_id String?
2024-03-01 11:21:57 +08:00
end_user String?
2024-07-09 01:16:58 +08:00
requester_ip_address String?
2025-01-18 10:53:45 +08:00
messages Json? @default("{}")
response Json? @default("{}")
2025-04-26 14:24:24 +08:00
session_id String?
2025-05-09 02:29:25 +08:00
status String?
2025-07-09 13:08:16 +08:00
mcp_namespaced_tool_name String?
2025-12-11 08:09:56 +08:00
agent_id String?
2025-04-26 14:24:24 +08:00
proxy_server_request Json? @default("{}")
2024-09-13 04:39:50 +08:00
@@index([startTime])
[Release Fix] (#22411)
* fix(lint): suppress PLR0915 for 3 complex methods that exceed 50-statement limit
- streaming_iterator.py: _process_event (84 statements)
- transformation.py: translate_messages_to_responses_input (51 statements)
- transformation.py: transform_realtime_response (54 statements)
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(mypy): resolve type errors in public_endpoints, user_api_key_auth, common_utils, transformation
- public_endpoints.py: fix _cached_endpoints type annotation
- user_api_key_auth.py: accept Optional[str] for end_user_id parameter
- common_utils.py: add NewProjectRequest/UpdateProjectRequest to Union type
- transformation.py: add ChatCompletionRedactedThinkingBlock and list[Any] to content type
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(proxy-extras): bump version to 0.4.50 and sync schema
- Bump litellm-proxy-extras from 0.4.49 to 0.4.50
- Sync schema.prisma with main proxy schema
- Includes new LiteLLM_ClaudeCodePluginTable model
- Includes new @@index([startTime, request_id]) on SpendLogs
- Update version references in requirements.txt and pyproject.toml
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(router): use string id in test_add_deployment and add defensive str() in register_model
- Change test to use string '100' instead of int 100 for model_info.id
- Add str() conversion in register_model to prevent AttributeError on non-string keys
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(security): update minimatch to 10.2.4 to fix CVE-2026-27903 and CVE-2026-27904
- Run npm audit fix in docs/my-website
- Updates minimatch from 10.2.1 to 10.2.4 (fixes HIGH severity ReDoS vulnerabilities)
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): update realtime guardrail test assertions to match actual guardrail behavior
- test_text_message_blocked_by_guardrail_no_ai_response: allow guardrail's own block
message text in response.done (previously expected empty content)
- test_voice_transcript_blocked_by_guardrail: allow guardrail to send response.cancel
+ block message + response.create flow (previously expected no response.create)
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: revert proxy-extras version in requirements.txt and pyproject.toml
The litellm-proxy-extras 0.4.50 is not published to PyPI yet, so consumer
references must stay at 0.4.49. Only the source package pyproject.toml
should be bumped to 0.4.50 for the publish_proxy_extras CI job.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: make transcript delta check optional in voice guardrail test
The guardrail sends an error event (guardrail_violation) when blocking
voice transcripts; it does not always produce transcript deltas. Remove
the assertion requiring response.audio_transcript.delta since the error
event is the primary signal that blocked content was handled.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* Add missing env keys to documentation: LITELLM_MAX_STREAMING_DURATION_SECONDS and LITELLM_USE_CHAT_COMPLETIONS_URL_FOR_ANTHROPIC_MESSAGES
These two environment variables were used in code but not documented in the
environment variables reference section of config_settings.md, causing the
test_env_keys.py CI test to fail.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* Fix 13 mypy type errors across 6 files
- in_flight_requests_middleware.py: Fix type: ignore error codes from
[union-attr] to [attr-defined], add [arg-type] for Gauge **kwargs
- transformation.py: Add [assignment] ignore for output_format reassignment,
add fallback empty string for tool use id to fix arg-type
- responses/main.py: Remove redundant type annotation on second
secret_fields assignment to fix no-redef
- streaming_iterator.py: Add [assignment] ignores for intermediate
cache token assignments
- handler.py: Add [typeddict-item] ignore for AnthropicMessagesRequest
construction from dict
- public_endpoints.py: Add [arg-type] ignore for _load_endpoints()
return type mismatch with SupportedEndpoint model
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: add auth overrides to spend tracking tests, fix realtime guardrail assertion, update UI minimatch
- Add app.dependency_overrides for user_api_key_auth in 4 spend tracking tests
that were returning 401 Unauthorized (error_code, error_message,
error_code_and_key_alias, key_hash)
- Fix realtime guardrail test to check ANY error event for guardrail_violation
instead of just the first (OpenAI may send its own errors first)
- Update ui/litellm-dashboard/package-lock.json to fix minimatch vulnerability
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* Fix failing MCP e2e and create_mcp_server UI tests
Test 1 (test_independent_clients_no_shared_session):
- Add allow_all_keys: true to MCP servers in test config. With master_key
and no DB, get_allowed_mcp_servers returned empty, causing 0 tools and
403 on tool calls. allow_all_keys bypasses per-key restrictions.
- Add asyncio.sleep(0.5) between client connections to allow MCP SDK
TaskGroup cleanup and avoid ExceptionGroup on connection close (MCP #915).
Test 2 (create_mcp_server 'auth value is provided'):
- Use userEvent.setup({ delay: null }) for instant keystrokes to avoid
timeout from default typing delay on CI.
- Increase per-test timeout to 15000ms for CI environments.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: stabilize proxy unit tests for parallel execution
- test_response_polling_handler: add xdist_group to prevent heavy import OOM
- test_db_schema_migration: use temp dir for worker isolation, sync schema.prisma index
- test_custom_tokenizer_bug: use lighter tokenizer to prevent OOM in parallel
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: add auth overrides to more spend tracking and model info tests
- Fix test_ui_view_spend_logs_pagination missing auth override (401)
- Fix test_view_spend_tags missing auth override (401)
- Fix test_view_spend_tags_no_database missing auth override (401)
- Fix test_empty_model_list.py to use app.dependency_overrides instead of patch()
for FastAPI dependency injection auth
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): use patch.object for aiohttp transport test to work in parallel execution
The @patch decorator was not intercepting the static method call in parallel
xdist workers. Using patch.object on the directly-imported class is more reliable.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(security): update minimatch from 10.2.1 to 10.2.4 in Dockerfile
The Docker image was explicitly pinning minimatch@10.2.1 which has HIGH
severity ReDoS vulnerabilities (GHSA-7r86-cg39-jmmj, GHSA-23c5-xmqv-rm74).
Update to 10.2.4 which includes fixes for both CVEs.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(ui): prevent MCP and TeamInfo test timeouts on CI
- Add userEvent.setup({ delay: null }) to all tests using userEvent in both files
- Add timeout: 15000 to tests with significant user interaction (typing, multiple clicks)
- Fixes: create_mcp_server Bearer Token test, TeamInfo cancel button test
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix: stabilize parallel test execution and aiohttp transport test
- test_aiohttp_handler: rewrite transport test to not rely on static method mock
(consistently fails in parallel xdist workers)
- test_proxy_cli: add xdist_group to prevent timeout during heavy imports
- test_swagger_chat_completions: add xdist_group to prevent timeout
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(security): add serialize-javascript override to fix GHSA-5c6j-r48x-rmvq
Add npm override for serialize-javascript>=7.0.3 in docs/my-website
to fix HIGH severity RCE vulnerability via RegExp.flags.
Also bump minimatch override to >=10.2.4.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* Fix flaky tests: remove broken Vertex model, add retries for Anthropic
- Remove vertex_ai/meta/llama-4-scout-17b-16e-instruct-maas from
test_partner_models_httpx_streaming - consistently returns 400 BadRequest
- Add @pytest.mark.flaky(retries=6, delay=10) to test_function_call_parsing
for transient Anthropic API overload errors
- Add @pytest.mark.flaky(retries=6, delay=10) to test_openai_stream_options_call
for transient Anthropic InternalServerError
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(ci): add xdist_group(proxy_heavy) to prevent OOM in parallel proxy tests
- Add pytestmark = pytest.mark.xdist_group('proxy_heavy') to test_proxy_utils.py
- Change test_db_schema_migration.py from schema_migration to proxy_heavy group
- Add @pytest.mark.xdist_group('proxy_heavy') to test_proxy_server.py::test_health
Groups heavy proxy tests to run on same worker, avoiding worker OOM crashes.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* Fix vertex AI qwen global endpoint test to mock vertexai module import
The test_vertex_ai_qwen_global_endpoint_url test was failing because the
VertexAIPartnerModels.completion() method tries to 'import vertexai' before
any of the mocked code runs. In environments without google-cloud-aiplatform
installed, this import fails with a VertexAIError(status_code=400).
Fix by:
- Adding patch.dict('sys.modules', {'vertexai': MagicMock()}) to mock the
vertexai module import
- Adding vertex_ai_location parameter to the acompletion call for completeness
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(ci): add xdist_group to health endpoint and watsonx tests for parallel stability
- test_health_liveliness_endpoint: add xdist_group('proxy_health') to prevent timeout
- test_watsonx_gpt_oss tests: add xdist_group('watsonx_heavy') to prevent mock interference
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): pre-populate WatsonX IAM token cache to prevent parallel test interference
The watsonx prompt transformation test was failing in parallel execution because
litellm.module_level_client.post mock was being interfered with by other tests.
Pre-populating the IAM token cache avoids the HTTP call entirely.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): add spend data polling with retries for e2e pass-through tests
- test_vertex_with_spend.test.js: Replace 15s fixed wait with polling loop
(up to 6 attempts, 10s apart) for spend data to appear in DB
- Increase test timeout from 25s to 90s to accommodate polling
- base_anthropic_messages_tool_search_test.py: Add flaky(retries=3) for
streaming test that depends on live Anthropic API
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(ci): reduce parallel workers from 8 to 4 for proxy tests to prevent OOM
- litellm_proxy_unit_testing_part2: -n 8 -> -n 4
- litellm_mapped_tests_proxy_part2: -n 8 -> -n 4, timeout 60 -> 120
- Worker crashes consistently caused by too many parallel proxy tests
each loading the full FastAPI app and heavy dependency tree
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(db): add migration for SpendLogs composite index (startTime, request_id)
The @@index([startTime, request_id]) was added to schema.prisma but had no
corresponding migration. This caused test_aaaasschema_migration_check to fail
because prisma migrate diff detected the missing index.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(db): add migration for MCP available_on_public_internet default change to true
The schema.prisma changed the default for available_on_public_internet from
false to true, but no migration was created. This caused the schema migration
test to detect drift.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): increase server wait time and add retry to flaky external API tests
- test_basic_python_version.py: increase server startup wait from 60s to 90s
for slower CI environments (fixes installing_litellm_on_python_3_13)
- test_a2a_agent.py: add flaky(retries=3, delay=5) for non-streaming test
that depends on live A2A agent endpoint
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): add flaky retries to all intermittent external API tests for 0-fail CI
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* fix(test): add auth overrides to file endpoint tests that return 500
The test_target_storage tests were getting 500 because the FastAPI auth
dependency wasn't overridden. Added app.dependency_overrides for proper
auth bypass in test environment.
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-03-01 01:46:35 +08:00
@@index([startTime, request_id])
2024-09-13 04:39:50 +08:00
@@index([end_user])
2025-05-11 05:28:20 +08:00
@@index([session_id])
2024-02-20 08:35:20 +08:00
}
2024-05-01 02:42:17 +08:00
// View spend, model, api_key per request
model LiteLLM_ErrorLogs {
request_id String @id @default(uuid())
2024-05-01 04:34:14 +08:00
startTime DateTime // Assuming start_time is a DateTime field
endTime DateTime // Assuming end_time is a DateTime field
2025-06-26 13:37:45 +08:00
api_base String @default("")
2024-05-01 04:11:09 +08:00
model_group String @default("") // public model_name / model_group
2024-05-01 08:31:40 +08:00
litellm_model_name String @default("") // model passed to litellm
2024-05-01 02:42:17 +08:00
model_id String @default("") // ID of model in ProxyModelTable
request_kwargs Json @default("{}")
2024-05-01 03:31:19 +08:00
exception_type String @default("")
exception_string String @default("")
status_code String @default("")
2024-05-01 02:42:17 +08:00
}
2024-02-20 08:35:20 +08:00
// Beta - allow team members to request access to a model
2024-02-20 08:53:40 +08:00
model LiteLLM_UserNotifications {
2024-03-03 03:59:17 +08:00
request_id String @id
2025-06-26 13:37:45 +08:00
user_id String
2024-02-20 08:35:20 +08:00
models String[]
justification String
2024-02-20 08:53:40 +08:00
status String // approved, disapproved, pending
2024-05-23 08:16:02 +08:00
}
model LiteLLM_TeamMembership {
// Use this table to track the Internal User's Spend within a Team + Set Budgets, rpm limits for the user within the team
user_id String
team_id String
spend Float @default(0.0)
budget_id String?
2025-06-26 13:37:45 +08:00
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
2024-05-23 08:16:02 +08:00
@@id([user_id, team_id])
}
2024-05-28 11:32:25 +08:00
2024-10-09 17:48:18 +08:00
model LiteLLM_OrganizationMembership {
// Use this table to track Internal User and Organization membership. Helps tracking a users role within an Organization
2024-10-09 17:55:27 +08:00
user_id String
organization_id String
2024-10-09 17:48:18 +08:00
user_role String?
spend Float? @default(0.0)
budget_id String?
created_at DateTime? @default(now()) @map("created_at")
updated_at DateTime? @default(now()) @updatedAt @map("updated_at")
// relations
user LiteLLM_UserTable @relation(fields: [user_id], references: [user_id])
2025-01-05 09:31:24 +08:00
organization LiteLLM_OrganizationTable @relation("OrganizationToMembership", fields: [organization_id], references: [organization_id])
2024-10-09 17:48:18 +08:00
litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
2025-06-26 13:37:45 +08:00
2025-01-05 09:31:24 +08:00
2024-10-09 17:48:18 +08:00
@@id([user_id, organization_id])
@@unique([user_id, organization_id])
}
2024-05-28 11:32:25 +08:00
model LiteLLM_InvitationLink {
// use this table to track invite links sent by admin for people to join the proxy
id String @id @default(uuid())
user_id String
is_accepted Boolean @default(false)
accepted_at DateTime? // when link is claimed (user successfully onboards via link)
expires_at DateTime // till when is link valid
created_at DateTime // when did admin create the link
created_by String // who created the link
updated_at DateTime // when was invite status updated
updated_by String // who updated the status (admin/user who accepted invite)
// Relations
liteLLM_user_table_user LiteLLM_UserTable @relation("UserId", fields: [user_id], references: [user_id])
liteLLM_user_table_created LiteLLM_UserTable @relation("CreatedBy", fields: [created_by], references: [user_id])
liteLLM_user_table_updated LiteLLM_UserTable @relation("UpdatedBy", fields: [updated_by], references: [user_id])
2024-06-06 07:19:38 +08:00
}
2024-06-06 08:50:27 +08:00
model LiteLLM_AuditLog {
2024-06-09 07:02:18 +08:00
id String @id @default(uuid())
updated_at DateTime @default(now())
changed_by String @default("") // user or system that performed the action
changed_by_api_key String @default("") // api key hash that performed the action
action String // create, update, delete
table_name String // on of LitellmTableNames.TEAM_TABLE_NAME, LitellmTableNames.USER_TABLE_NAME, LitellmTableNames.PROXY_MODEL_TABLE_NAME,
object_id String // id of the object being audited. This can be the key id, team id, user id, model id
2025-06-26 13:37:45 +08:00
before_value Json? // value of the row
2024-06-09 07:02:18 +08:00
updated_values Json? // value of the row after change
2024-07-09 01:16:58 +08:00
}
2025-03-27 07:36:36 +08:00
// Track daily user spend metrics per model and key
model LiteLLM_DailyUserSpend {
id String @id @default(uuid())
2025-06-26 13:37:45 +08:00
user_id String?
2025-03-27 07:36:36 +08:00
date String
2025-06-26 13:37:45 +08:00
api_key String
2025-07-09 13:08:16 +08:00
model String?
2025-06-26 13:37:45 +08:00
model_group String?
2025-07-09 13:08:16 +08:00
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-05-10 05:14:39 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
2025-03-27 07:36:36 +08:00
spend Float @default(0.0)
2025-05-10 05:14:39 +08:00
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
2025-03-27 07:36:36 +08:00
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([user_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-03-27 07:36:36 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([user_id, date])
2025-03-27 07:36:36 +08:00
@@index([api_key])
@@index([model])
2025-07-09 13:08:16 +08:00
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-03-27 07:36:36 +08:00
}
2025-03-28 12:10:26 +08:00
2025-11-13 10:22:26 +08:00
// Track daily organization spend metrics per model and key
model LiteLLM_DailyOrganizationSpend {
id String @id @default(uuid())
organization_id String?
date String
api_key String
model String?
model_group String?
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-11-13 10:22:26 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
spend Float @default(0.0)
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([organization_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-11-13 10:22:26 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([organization_id, date])
2025-11-13 10:22:26 +08:00
@@index([api_key])
@@index([model])
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-12-05 04:30:08 +08:00
}
// Track daily end user (customer) spend metrics per model and key
model LiteLLM_DailyEndUserSpend {
id String @id @default(uuid())
end_user_id String?
date String
api_key String
model String?
model_group String?
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-12-05 04:30:08 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
spend Float @default(0.0)
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([end_user_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-12-05 04:30:08 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([end_user_id, date])
2025-12-05 04:30:08 +08:00
@@index([api_key])
@@index([model])
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-11-13 10:22:26 +08:00
}
2025-12-11 03:50:52 +08:00
// Track daily agent spend metrics per model and key
model LiteLLM_DailyAgentSpend {
id String @id @default(uuid())
agent_id String?
date String
api_key String
model String?
model_group String?
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-12-11 03:50:52 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
spend Float @default(0.0)
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([agent_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-12-11 03:50:52 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([agent_id, date])
2025-12-11 03:50:52 +08:00
@@index([api_key])
@@index([model])
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-12-11 03:50:52 +08:00
}
2025-04-16 11:58:48 +08:00
// Track daily team spend metrics per model and key
model LiteLLM_DailyTeamSpend {
id String @id @default(uuid())
2025-05-27 13:03:18 +08:00
team_id String?
2025-04-16 11:58:48 +08:00
date String
2025-06-26 13:37:45 +08:00
api_key String
2025-07-09 13:08:16 +08:00
model String?
2025-06-26 13:37:45 +08:00
model_group String?
2025-07-09 13:08:16 +08:00
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-05-10 05:14:39 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
2025-04-16 11:58:48 +08:00
spend Float @default(0.0)
2025-05-10 05:14:39 +08:00
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
2025-04-16 11:58:48 +08:00
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([team_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-04-16 11:58:48 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([team_id, date])
2025-04-16 11:58:48 +08:00
@@index([api_key])
@@index([model])
2025-07-09 13:08:16 +08:00
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-04-16 11:58:48 +08:00
}
2025-04-17 03:26:21 +08:00
// Track daily team spend metrics per model and key
model LiteLLM_DailyTagSpend {
id String @id @default(uuid())
2025-11-12 10:53:48 +08:00
request_id String?
2025-06-26 13:37:45 +08:00
tag String?
2025-04-17 03:26:21 +08:00
date String
2025-06-26 13:37:45 +08:00
api_key String
2025-07-09 13:08:16 +08:00
model String?
2025-06-26 13:37:45 +08:00
model_group String?
2025-07-09 13:08:16 +08:00
custom_llm_provider String?
mcp_namespaced_tool_name String?
2026-01-07 07:54:03 +08:00
endpoint String?
2025-05-10 05:14:39 +08:00
prompt_tokens BigInt @default(0)
completion_tokens BigInt @default(0)
cache_read_input_tokens BigInt @default(0)
cache_creation_input_tokens BigInt @default(0)
2025-04-17 03:26:21 +08:00
spend Float @default(0.0)
2025-05-10 05:14:39 +08:00
api_requests BigInt @default(0)
successful_requests BigInt @default(0)
failed_requests BigInt @default(0)
2025-04-17 03:26:21 +08:00
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-01-07 07:54:03 +08:00
@@unique([tag, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
2025-04-17 03:26:21 +08:00
@@index([date])
2026-02-20 06:36:28 +08:00
@@index([tag, date])
2025-04-17 03:26:21 +08:00
@@index([api_key])
@@index([model])
2025-07-09 13:08:16 +08:00
@@index([mcp_namespaced_tool_name])
2026-01-07 07:54:03 +08:00
@@index([endpoint])
2025-04-17 03:26:21 +08:00
}
2025-03-28 12:10:26 +08:00
// Track the status of cron jobs running. Only allow one pod to run the job at a time
2025-03-28 14:13:01 +08:00
model LiteLLM_CronJob {
2025-03-28 13:54:46 +08:00
cronjob_id String @id @default(cuid()) // Unique ID for the record
pod_id String // Unique identifier for the pod acting as the leader
2025-03-28 12:10:26 +08:00
status JobStatus @default(INACTIVE) // Status of the cron job (active or inactive)
2025-03-28 13:54:46 +08:00
last_updated DateTime @default(now()) // Timestamp for the last update of the cron job record
2025-03-28 12:10:26 +08:00
ttl DateTime // Time when the leader's lease expires
}
enum JobStatus {
ACTIVE
INACTIVE
}
2025-04-01 13:48:43 +08:00
2025-04-12 23:24:46 +08:00
model LiteLLM_ManagedFileTable {
id String @id @default(uuid())
unified_file_id String @unique // The base64 encoded unified file ID
2025-06-26 13:37:45 +08:00
file_object Json? // Stores the OpenAIFileObject
2025-06-04 06:57:33 +08:00
model_mappings Json
2025-05-23 14:05:45 +08:00
flat_model_file_ids String[] @default([]) // Flat list of model file id's - for faster querying of model id -> unified file id
2025-12-11 17:38:17 +08:00
storage_backend String? // Storage backend name (e.g., "azure_storage", "gcs", "default")
storage_url String? // The actual storage URL where the file is stored
2025-04-12 23:24:46 +08:00
created_at DateTime @default(now())
2025-06-26 13:37:45 +08:00
created_by String?
2025-04-12 23:24:46 +08:00
updated_at DateTime @updatedAt
2025-05-23 14:05:45 +08:00
updated_by String?
2025-04-12 23:24:46 +08:00
@@index([unified_file_id])
}
2025-06-26 13:37:45 +08:00
model LiteLLM_ManagedObjectTable { // for batches or finetuning jobs which use the
2025-05-23 14:05:45 +08:00
id String @id @default(uuid())
2025-05-27 13:03:18 +08:00
unified_object_id String @unique // The base64 encoded unified file ID
2025-06-26 13:37:45 +08:00
model_object_id String @unique // the id returned by the backend API provider
2025-05-23 14:05:45 +08:00
file_object Json // Stores the OpenAIFileObject
2025-06-04 06:57:33 +08:00
file_purpose String // either 'batch' or 'fine-tune'
2025-06-26 13:37:45 +08:00
status String? // check if batch cost has been tracked
2026-02-23 20:12:32 +08:00
batch_processed Boolean @default(false) // set to true by CheckBatchCost after cost is computed
2025-05-23 14:05:45 +08:00
created_at DateTime @default(now())
created_by String?
updated_at DateTime @updatedAt
2025-06-26 13:37:45 +08:00
updated_by String?
2025-05-23 14:05:45 +08:00
@@index([unified_object_id])
@@index([model_object_id])
}
2025-05-01 12:49:59 +08:00
2026-02-15 01:49:11 +08:00
model LiteLLM_ManagedVectorStoreTable {
id String @id @default(uuid())
unified_resource_id String @unique // The base64 encoded unified vector store ID
resource_object Json? // Stores the VectorStoreCreateResponse
model_mappings Json // Maps model_id -> provider_vector_store_id
flat_model_resource_ids String[] @default([]) // Flat list of provider vector store IDs for faster querying
storage_backend String? // Storage backend name (if applicable)
storage_url String? // Storage URL (if applicable)
created_at DateTime @default(now())
created_by String?
updated_at DateTime @updatedAt
updated_by String?
@@index([unified_resource_id])
}
2025-05-01 12:49:59 +08:00
model LiteLLM_ManagedVectorStoresTable {
vector_store_id String @id
custom_llm_provider String
vector_store_name String?
vector_store_description String?
vector_store_metadata Json?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
litellm_credential_name String?
2025-07-18 23:41:18 +08:00
litellm_params Json?
2026-01-29 10:55:40 +08:00
team_id String?
user_id String?
@@index([team_id])
@@index([user_id])
2025-05-15 05:19:51 +08:00
}
// Guardrails table for storing guardrail configurations
model LiteLLM_GuardrailsTable {
guardrail_id String @id @default(uuid())
guardrail_name String @unique
litellm_params Json
guardrail_info Json?
2026-02-15 01:49:11 +08:00
team_id String?
2025-05-15 05:19:51 +08:00
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2026-03-03 14:06:49 +08:00
// Submission lifecycle. Possible values: pending_review (team-registered, awaiting approval), active (approved), rejected
status String @default("active")
submitted_at DateTime?
reviewed_at DateTime?
// submitted_by_user_id and submitted_by_email live in guardrail_info JSON
@@index([status])
2025-06-18 23:37:40 +08:00
}
2026-02-22 11:14:04 +08:00
// Daily guardrail metrics for usage dashboard (one row per guardrail per day)
model LiteLLM_DailyGuardrailMetrics {
guardrail_id String // logical id; may not FK if guardrail from config
date String // YYYY-MM-DD
requests_evaluated BigInt @default(0)
passed_count BigInt @default(0)
blocked_count BigInt @default(0)
flagged_count BigInt @default(0)
avg_score Float?
avg_latency_ms Float?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@id([guardrail_id, date])
@@index([date])
@@index([guardrail_id])
}
// Daily policy metrics for usage dashboard (one row per policy per day)
model LiteLLM_DailyPolicyMetrics {
policy_id String
date String // YYYY-MM-DD
requests_evaluated BigInt @default(0)
passed_count BigInt @default(0)
blocked_count BigInt @default(0)
flagged_count BigInt @default(0)
avg_score Float?
avg_latency_ms Float?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@id([policy_id, date])
@@index([date])
@@index([policy_id])
}
// Index for fast "last N logs for guardrail/policy" from SpendLogs
model LiteLLM_SpendLogGuardrailIndex {
request_id String
guardrail_id String
policy_id String? // set when run as part of a policy pipeline
start_time DateTime
@@id([request_id, guardrail_id])
@@index([guardrail_id, start_time])
@@index([policy_id, start_time])
}
2026-03-04 12:22:20 +08:00
// Index for fast "last N logs for tool" from SpendLogs – see how a tool is called in production
model LiteLLM_SpendLogToolIndex {
request_id String
tool_name String // matches LiteLLM_ToolTable.tool_name; join for input_policy/output_policy etc.
start_time DateTime
@@id([request_id, tool_name])
@@index([tool_name, start_time])
}
2025-08-03 13:33:37 +08:00
// Prompt table for storing prompt configurations
model LiteLLM_PromptTable {
id String @id @default(uuid())
2025-11-20 05:19:56 +08:00
prompt_id String
version Int @default(1)
2025-08-03 13:33:37 +08:00
litellm_params Json
prompt_info Json?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2025-11-20 05:19:56 +08:00
@@unique([prompt_id, version])
@@index([prompt_id])
2025-08-03 13:33:37 +08:00
}
2025-06-18 23:37:40 +08:00
model LiteLLM_HealthCheckTable {
health_check_id String @id @default(uuid())
model_name String
model_id String?
status String
healthy_count Int @default(0)
unhealthy_count Int @default(0)
error_message String?
response_time_ms Float?
details Json?
checked_by String?
checked_at DateTime @default(now())
created_at DateTime @default(now())
updated_at DateTime @updatedAt
@@index([model_name])
@@index([checked_at])
@@index([status])
2025-10-24 08:57:49 +08:00
}
// Search Tools table for storing search tool configurations
model LiteLLM_SearchToolsTable {
search_tool_id String @id @default(uuid())
search_tool_name String @unique
litellm_params Json
search_tool_info Json?
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2025-10-31 05:32:08 +08:00
}
// SSO configuration table
model LiteLLM_SSOConfig {
id String @id @default("sso_config")
sso_settings Json
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2025-11-01 08:43:59 +08:00
}
2025-11-02 04:45:32 +08:00
model LiteLLM_ManagedVectorStoreIndexTable {
2025-11-02 03:01:32 +08:00
id String @id @default(uuid())
index_name String @unique
litellm_params Json
index_info Json?
created_at DateTime @default(now())
created_by String?
updated_at DateTime @updatedAt
updated_by String?
}
2025-11-01 08:43:59 +08:00
// Cache configuration table
model LiteLLM_CacheConfig {
id String @id @default("cache_config")
cache_settings Json
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2025-12-10 03:19:53 +08:00
}
// UI Settings configuration table
model LiteLLM_UISettings {
id String @id @default("ui_settings")
ui_settings Json
created_at DateTime @default(now())
updated_at DateTime @updatedAt
2025-12-19 21:25:59 +08:00
}
2026-03-07 15:39:08 +08:00
// Generic config overrides table - one row per config_type
model LiteLLM_ConfigOverrides {
config_type String @id
config_value Json
created_at DateTime @default(now())
updated_at DateTime @updatedAt
}
2025-12-19 21:25:59 +08:00
// Skills table for storing LiteLLM-managed skills
model LiteLLM_SkillsTable {
skill_id String @id @default(uuid())
display_title String?
description String?
instructions String? // The skill instructions/prompt (from SKILL.md)
source String @default("custom") // "custom" or "anthropic"
latest_version String?
file_content Bytes? // Binary content of the skill files (zip)
file_name String? // Original filename
file_type String? // MIME type (e.g., "application/zip")
metadata Json? @default("{}")
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
2026-01-05 14:49:09 +08:00
}
2026-01-24 05:16:58 +08:00
2026-02-22 12:14:31 +08:00
// Policy table for storing guardrail policies (versioned)
2026-01-24 05:16:58 +08:00
model LiteLLM_PolicyTable {
2026-02-22 12:14:31 +08:00
policy_id String @id @default(uuid())
policy_name String // No longer @unique; use @@unique([policy_name, version_number])
version_number Int @default(1)
version_status String @default("production") // "draft" | "published" | "production"
parent_version_id String?
is_latest Boolean @default(true)
published_at DateTime?
production_at DateTime?
inherit String? // Name of parent policy to inherit from
description String?
guardrails_add String[] @default([])
guardrails_remove String[] @default([])
condition Json? @default("{}") // Policy conditions (e.g., model matching)
pipeline Json? // Optional guardrail pipeline (mode + steps[])
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
@@unique([policy_name, version_number])
@@index([policy_name, version_status])
2026-01-24 05:16:58 +08:00
}
// Policy attachment table for defining where policies apply
model LiteLLM_PolicyAttachmentTable {
attachment_id String @id @default(uuid())
policy_name String // Name of the policy to attach
scope String? // Use '*' for global scope
teams String[] @default([]) // Team aliases or patterns
keys String[] @default([]) // Key aliases or patterns
models String[] @default([]) // Model names or patterns
2026-02-11 09:50:37 +08:00
tags String[] @default([]) // Tag patterns (e.g., ["healthcare", "prod-*"])
2026-01-24 05:16:58 +08:00
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
}
2026-02-12 12:44:30 +08:00
2026-03-04 12:22:20 +08:00
// Global tool registry - auto-discovered from LLM responses; admins set input/output policies here
2026-02-26 03:44:30 +08:00
model LiteLLM_ToolTable {
2026-03-04 12:22:20 +08:00
tool_id String @id @default(uuid())
tool_name String @unique // e.g. "huggingface_remote-mcp__dynamic_space"
origin String? // MCP server name or "user_defined"
input_policy String @default("untrusted") // "trusted" | "untrusted" | "blocked"
output_policy String @default("untrusted") // "trusted" | "untrusted"
call_count Int @default(0) // cumulative number of times this tool was seen
assignments Json? @default("{}")
key_hash String? // hash of the virtual key that first called this tool
team_id String? // team that first called this tool
key_alias String? // human-readable alias of the virtual key
user_agent String? // user-agent of the first request that discovered this tool
last_used_at DateTime? // timestamp of the most recent call
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
@@index([input_policy])
@@index([output_policy])
2026-02-26 03:44:30 +08:00
@@index([team_id])
}
2026-03-07 15:39:08 +08:00
// Per-(tool, team/key) policy overrides. When present, override replaces global tool policy for that scope.
2026-02-12 12:44:30 +08:00
//Unified Access Groups table for storing unified access groups
2026-02-13 04:30:22 +08:00
model LiteLLM_AccessGroupTable {
2026-02-12 12:44:30 +08:00
access_group_id String @id @default(uuid())
access_group_name String @unique
description String?
// Resource memberships - explicit arrays per type
2026-02-14 08:44:49 +08:00
access_model_names String[] @default([])
2026-02-12 12:44:30 +08:00
access_mcp_server_ids String[] @default([])
access_agent_ids String[] @default([])
assigned_team_ids String[] @default([])
assigned_key_ids String[] @default([])
created_at DateTime @default(now())
created_by String?
updated_at DateTime @default(now()) @updatedAt
updated_by String?
2026-02-28 07:59:37 +08:00
}
// Claude Code Plugin Marketplace table
model LiteLLM_ClaudeCodePluginTable {
id String @id @default(uuid())
name String @unique
version String?
description String?
manifest_json String?
files_json String? @default("{}")
enabled Boolean @default(true)
created_at DateTime? @default(now())
updated_at DateTime? @default(now()) @updatedAt
created_by String?
@@map("LiteLLM_ClaudeCodePluginTable")
}