Use Case Automatic Limits
You can assign a default limit configuration to a use case defintion. When configured, each time an instance is created (e.g a newuse_case_id is created in the Pay-i service for a use_case_name) a new limit will be created as well. The limit will track each request associated with the the use case instance.
The Pay-i SDK provides APIs to create, update, and delete a limit_config associated with a use_case_name . Read and refer to the limit creation docs for an in depth description of each parameter.
Create or update a limit_config
limit_configuse_cases.definitions.limit_config.create() will assign a new limit_config to a use case. The API will overwrite the currently limit_config if it one was created previously.
Parameters
| Name | Type | Required |
|---|---|---|
use_case_name | str | Yes |
max | float | Yes |
limit_type | str: "block" or "allow" | No |
properties | dict[str, Optional[str]] | No |
threshold | float | No |
$ pip install payi openai dotenvfrom payi import Payi
from dotenv import load_dotenv
load_dotenv()
payi = Payi()
# Ensure the use case exists
payi.use_cases.definitions.create(name="example_use_case", description="Example use case")
# Assign a limit_config where each use case instance will be given a $0.05 budget and a waring threshold of 80% of max
payi.use_cases.definitions.limit_config.create(
use_case_name="example_use_case",
limit_config={ "limit_type": "allow", "max": 0.05, "threshold": 0.80 }
)Delete a limit_config
limit_configuse_cases.defintions.limit_config.delete() will delete the limit_config assigned to the use_case_name. The API will succeed if nolimit_config has been assigned.
| Name | Type | Required |
|---|---|---|
use_case_name | str | Yes |
$ pip install payi openai dotenvfrom payi import Payi
from dotenv import load_dotenv
load_dotenv()
payi = Payi()
payi.use_cases.definitions.limit_config.delete(use_case_name=use_case_name)Example
The following example configures the use case teach_me with limit max = $0.05 and threshold = 0.80 ($0.04) to demonstrate the creation and state transitions of each limt. Each time the sample is run, a new use_case_id is created in the call to track_context(), and creating a new limit as a result.
$ pip install payi openai dotenvfrom payi import Payi
from payi.lib.instrument import track_context, payi_instrument
from payi.types.shared import XproxyResult
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
payi = Payi()
payi_instrument(payi=payi)
use_case_name="teach_me"
payi.use_cases.definitions.create(
name=use_case_name,
description="Example use case",
)
payi.use_cases.definitions.limit_config.create(
use_case_name=use_case_name,
limit_config={ "limit_type": "allow", "max": 0.05, "threshold": 0.80 }
)
openai = OpenAI()
with track_context(use_case_name=use_case_name):
overrun = False
while not overrun:
response = openai.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how can I use the API?"}
])
# Resilient to disabling payi or the ingestion was deferred due to network error
if hasattr(response, 'xproxy_result'):
result: XproxyResult = response.xproxy_result
cost_str = f"{result.cost.total.base}" if result.cost else "N/A"
limits_str = ", ".join([f"{k}={v.state}" for k, v in result.limits.items()]) if result.limits else "N/A"
print(f"Request: Cost: {cost_str}, Limits: {limits_str}")
# If guaranteed that limits will be associated with the request
# this check can be removed as result.limits will always be valid
if result.limits:
# key is the limit id, value is the state
for key, value in result.limits.items():
if value.state == 'exceeded':
# handle case where use case instance spend is >= threshold
...
elif value.state == 'overrun':
# handle case where use case instance spend is >= max
overrun = True
break
Run #1
In this run, the intermediate cummulative cost tracked by the budet after request 3 was cumulative cost < max * threshold and after request 4 transitioned to cumulative cost > max which is why the state of the limit transitioned from ok directly to overrun (skipping exceeded entirely).
Request: Cost: 0.012305, Limits: 12276=ok
Request: Cost: 0.012815, Limits: 12276=ok
Request: Cost: 0.010835, Limits: 12276=ok
Request: Cost: 0.017855, Limits: 12276=overrunRun #2
In this run, the intermediate cummulative cost tracked by the budet afer request 3 transitioned in the range of cumulatve cost >= max * threshold and cumulative cost < max to transition the state of the limit from ok to exceeeded and then to overrun on the final 4th request.
Request: Cost: 0.012935, Limits: 12277=ok
Request: Cost: 0.012425, Limits: 12277=ok
Request: Cost: 0.014905, Limits: 12277=exceeded
Request: Cost: 0.020195, Limits: 12277=overrun