over available TPM=0. Model TPM=0, Active keys=2'}, 'type': 'None', 'param': 'None', 'code': 429}}
+```
+
+
+## [BETA] Set Priority / Reserve Quota
+
+Reserve TPM/RPM capacity for different environments or use cases. This ensures critical production workloads always have guaranteed capacity, while development or lower-priority tasks use remaining quota.
+
+**Use Cases:**
+- Production vs Development environments
+- Real-time applications vs batch processing
+- Critical services vs experimental features
+
+:::tip
+
+Reserving TPM/RPM on keys based on priority is a premium feature. Please [get an enterprise license](./enterprise.md) for it.
+:::
+
+### How Priority Reservation Works
+
+Priority reservation allocates a percentage of your model's total TPM/RPM to specific priority levels. Keys with higher priority get guaranteed access to their reserved quota first.
+
+**Example Scenario:**
+- Model has 10 RPM total capacity
+- Priority reservation: `{"prod": 0.9, "dev": 0.1}`
+- Result: Production keys get 9 RPM guaranteed, Development keys get 1 RPM guaranteed
+
+### Configuration
+
+#### 1. Setup config.yaml
+
+```yaml showLineNumbers title="config.yaml"
+model_list:
+ - model_name: gpt-3.5-turbo
+ litellm_params:
+ model: "gpt-3.5-turbo"
+ api_key: os.environ/OPENAI_API_KEY
+ rpm: 10 # Total model capacity
+
+litellm_settings:
+ callbacks: ["dynamic_rate_limiter_v3"]
+ priority_reservation:
+ "prod": 0.9 # 90% reserved for production (9 RPM)
+ "dev": 0.1 # 10% reserved for development (1 RPM)
+ # Alternative format:
+ # "prod":
+ # type: "rpm" # Reserve based on requests per minute
+ # value: 9 # 9 RPM = 90% of 10 RPM capacity
+ # "dev":
+ # type: "tpm" # Reserve based on tokens per minute
+ # value: 100 # 100 TPM
+ priority_reservation_settings:
+ default_priority: 0 # Weight (0%) assigned to keys without explicit priority metadata
+ saturation_threshold: 0.50 # A model is saturated if it has hit 50% of its RPM limit
+
+general_settings:
+ master_key: sk-1234 # OR set `LITELLM_MASTER_KEY=".."` in your .env
+ database_url: postgres://.. # OR set `DATABASE_URL=".."` in your.env
+```
+
+**Configuration Details:**
+
+`priority_reservation`: Dict[str, Union[float, PriorityReservationDict]]
+- **Key (str)**: Priority level name (can be any string like "prod", "dev", "critical", etc.)
+- **Value**: Either a float (0.0-1.0) or dict with `type` and `value`
+ - Float: `0.9` = 90% of capacity
+ - Dict: `{"type": "rpm", "value": 9}` = 9 requests/min
+ - Supported types: `"percent"`, `"rpm"`, `"tpm"`
+
+`priority_reservation_settings`: Object (Optional)
+- **default_priority (float)**: Weight/percentage (0.0 to 1.0) assigned to API keys that have no priority metadata set (defaults to 0.5)
+- **saturation_threshold (float)**: Saturation level (0.0 to 1.0) at which strict priority enforcement begins for a model. Saturation is calculated as `max(current_rpm/max_rpm, current_tpm/max_tpm)`. Below this threshold, generous mode allows priority borrowing from unused capacity. Above this threshold, strict mode enforces normalized priority limits.
+ - Example: When model usage is low, keys can use more than their allocated share. When model usage is high, keys are strictly limited to their allocated share.
+
+**Start Proxy**
+
+```bash
+litellm --config /path/to/config.yaml
+```
+
+#### 2. Create Keys with Priority Levels
+
+**Production Key:**
+```bash
+curl -X POST 'http://0.0.0.0:4000/key/generate' \
+-H 'Authorization: Bearer sk-1234' \
+-H 'Content-Type: application/json' \
+-d '{
+ "metadata": {"priority": "prod"}
+}'
+```
+
+**Development Key:**
+```bash
+curl -X POST 'http://0.0.0.0:4000/key/generate' \
+-H 'Authorization: Bearer sk-1234' \
+-H 'Content-Type: application/json' \
+-d '{
+ "metadata": {"priority": "dev"}
+}'
+```
+
+**Key Without Priority (uses default_priority weight):**
+```bash
+curl -X POST 'http://0.0.0.0:4000/key/generate' \
+-H 'Authorization: Bearer sk-1234' \
+-H 'Content-Type: application/json' \
+-d '{}'
+```
+
+**Expected Response for both:**
+```json
+{
+ "key": "sk-...",
+ "metadata": {"priority": "prod"}, // or "dev"
+ ...
+}
+```
+
+#### 3. Test Priority Allocation
+
+**Test Production Key (should get 9 RPM):**
+```bash
+curl -X POST 'http://0.0.0.0:4000/chat/completions' \
+ -H 'Content-Type: application/json' \
+ -H 'Authorization: Bearer sk-prod-key' \
+ -d '{
+ "model": "gpt-3.5-turbo",
+ "messages": [{"role": "user", "content": "Hello from prod"}]
+ }'
+```
+
+**Test Development Key (should get 1 RPM):**
+```bash
+curl -X POST 'http://0.0.0.0:4000/chat/completions' \
+ -H 'Content-Type: application/json' \
+ -H 'Authorization: Bearer sk-dev-key' \
+ -d '{
+ "model": "gpt-3.5-turbo",
+ "messages": [{"role": "user", "content": "Hello from dev"}]
+ }'
+```
+
+### Expected Behavior
+
+With the configuration above:
+
+1. **Production keys** can make up to 9 requests per minute (90% of 10 RPM)
+2. **Development keys** can make up to 1 request per minute (10% of 10 RPM)
+3. **Keys without explicit priority** get the default_priority weight (0 = 0%), which allocates 0 requests per minute (0% of 10 RPM)
+4. Named priorities in `priority_reservation` and keys with `default_priority` operate independently
+
+**Rate Limit Error Example:**
+```json
+{
+ "error": {
+ "message": "Key=sk-dev-... over available RPM=0. Model RPM=10, Reserved RPM for priority 'dev'=1, Active keys=1",
+ "type": "rate_limit_exceeded",
+ "code": 429
+ }
+}
+```
+
+### Demo Video
+
+This video walks through setting up dynamic rate limiting with priority reservation and locust tests to validate the behavior.
+
+
+
diff --git a/docs/my-website/docs/proxy/email.md b/docs/my-website/docs/proxy/email.md
index 9cd027da7f63..1ee67e823083 100644
--- a/docs/my-website/docs/proxy/email.md
+++ b/docs/my-website/docs/proxy/email.md
@@ -141,6 +141,7 @@ LiteLLM allows you to customize various aspects of your email notifications. Bel
| Email Signature | `EMAIL_SIGNATURE` | string (HTML) | Standard LiteLLM footer | `"Best regards,
Your Team
Visit us
"` | HTML-formatted footer for all emails |
| Invitation Subject | `EMAIL_SUBJECT_INVITATION` | string | "LiteLLM: New User Invitation" | `"Welcome to Your Company!"` | Subject line for invitation emails |
| Key Creation Subject | `EMAIL_SUBJECT_KEY_CREATED` | string | "LiteLLM: API Key Created" | `"Your New API Key is Ready"` | Subject line for key creation emails |
+| Proxy Base URL | `PROXY_BASE_URL` | string | http://0.0.0.0:4000 | `"https://proxy.your-company.com"` | Base URL for the LiteLLM Proxy (used in email links) |
## HTML Support in Email Signature
@@ -180,6 +181,9 @@ EMAIL_SIGNATURE="Best regards,
Your Company Team
-
-
-```bash
-curl -L -X POST 'http://0.0.0.0:4000/team/new' \
--H 'Authorization: Bearer sk-1234' \
--H 'Content-Type: application/json' \
--d '{
- "metadata": {
- "spend_logs_metadata": {
- "hello": "world"
- }
- }
-}
-
-'
-```
-
-
-
-
-
-Set `extra_body={"metadata": { }}` to `metadata` you want to pass
-
-```python
-import openai
-client = openai.OpenAI(
- api_key="anything",
- base_url="http://0.0.0.0:4000"
-)
-
-# request sent to model set on litellm proxy, `litellm --model`
-response = client.chat.completions.create(
- model="gpt-3.5-turbo",
- messages = [
- {
- "role": "user",
- "content": "this is a test request, write a short poem"
- }
- ],
- extra_body={
- "metadata": {
- "spend_logs_metadata": {
- "hello": "world"
- }
- }
- }
-)
-
-print(response)
-```
-
-
-
-
-
-```js
-const openai = require('openai');
-
-async function runOpenAI() {
- const client = new openai.OpenAI({
- apiKey: 'sk-1234',
- baseURL: 'http://0.0.0.0:4000'
- });
-
- try {
- const response = await client.chat.completions.create({
- model: 'gpt-3.5-turbo',
- messages: [
- {
- role: 'user',
- content: "this is a test request, write a short poem"
- },
- ],
- metadata: {
- spend_logs_metadata: { // 👈 Key Change
- hello: "world"
- }
- }
- });
- console.log(response);
- } catch (error) {
- console.log("got this exception from server");
- console.error(error);
- }
-}
-
-// Call the asynchronous function
-runOpenAI();
-```
-
-
-
-
-Pass `metadata` as part of the request body
-
-```shell
-curl --location 'http://0.0.0.0:4000/chat/completions' \
- --header 'Content-Type: application/json' \
- --data '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "what llm are you"
- }
- ],
- "metadata": {
- "spend_logs_metadata": {
- "hello": "world"
- }
- }
-}'
-```
-
-
-
-```python
-from langchain.chat_models import ChatOpenAI
-from langchain.prompts.chat import (
- ChatPromptTemplate,
- HumanMessagePromptTemplate,
- SystemMessagePromptTemplate,
-)
-from langchain.schema import HumanMessage, SystemMessage
-
-chat = ChatOpenAI(
- openai_api_base="http://0.0.0.0:4000",
- model = "gpt-3.5-turbo",
- temperature=0.1,
- extra_body={
- "metadata": {
- "spend_logs_metadata": {
- "hello": "world"
- }
- }
- }
-)
-
-messages = [
- SystemMessage(
- content="You are a helpful assistant that im using to make a test request to."
- ),
- HumanMessage(
- content="test from litellm. tell me why it's amazing in 1 sentence"
- ),
-]
-response = chat(messages)
-
-print(response)
-```
-
-
-