Your customers’ AI, on your plans.
Give free users a taste and paying users more, without building a metering service. Send each user and their plan with the call, and Worksi enforces your limits per user.
# the request carriesX-AIW-End-User: <hash of your user id>X-AIW-End-User-Plan: free # the gateway answersHTTP/1.1 429 Too Many RequestsRetry-After: <seconds until the limit resets>{ "error": { "message": "end user \"u_…\" reached the requests per day limit of plan \"free\" (50 of 50; resets …, policy \"Plan limits for app users\")", "type": "rate_limit_error", "code": "end_user_quota_exceeded", "param": null, "aiw_request_id": "req_…", "details": { "plan": "free", "limit": "requests_per_day", "window": "day", "max": 50, "current": 50, "resets_at": "…" } }}Example response. The body format is the gateway’s.
One request, per‑user limits.
Two headers carry the user and their plan. The gateway resolves the plan from one policy and decides before your provider is called.
Your plans, as one policy.
An end_user_quota policy maps your plan names to limits. Create it in the console or with the API.
- Monitor mode first: see who would be limited, then enforce.
- Refused calls never reach your provider and don’t count toward your Worksi request quota.
- Usage per user: requests, tokens, cost, errors and last activity, by plan.
- End‑user plans are included in every Worksi plan.
{ "name": "Plan limits for app users", "type": "end_user_quota", "scope_type": "org", "enforcement": "enforce", "rules": { "plans": { "free": { "requests_per_day": 50, "tokens_per_day": 50000, "models": ["gpt-5-mini"] }, "pro": { "requests_per_day": 2000, "cost_usd_per_month": 20 } }, "default_plan": "free" }}| Rule | Meaning |
|---|---|
requests_per_day | Model calls per user per UTC day |
tokens_per_day | Input and output tokens per user per UTC day |
cost_usd_per_month | Model spend per user per calendar month |
models | The only models the plan may use; others get 403 |
default_plan | The plan for calls that name none, or an unknown one |
What watches your users’ spend.
Four of the eleven built‑in detectors, with the conditions they fire on. Refused calls are recorded, so a surge of them is visible.
| Detector | Fires when |
|---|---|
Policy violationpolicy_violation | A request or tool call was blocked by, or broke, a policy |
Cost anomalycost_anomaly | Cost per request jumps versus the agent’s 7-day baseline, or a run exceeds its cost limit |
Budget thresholdbudget_threshold | Spend crosses a budget’s alert thresholds; an incident at 100% |
Token anomalytoken_anomaly | A call uses far more tokens than the agent normally does |
Two headers on each call.
A pseudonymous user id in X-AIW-End-User, their plan in X-AIW-End-User-Plan. Any OpenAI SDK can send them.
Starter fits one app and its users: 100k gateway requests and 1M spans a month, 14‑day retention, end‑user plans. $9 / month.
SDK packages are distributed by Worksi. Request access. Any OpenAI or Anthropic SDK works with the gateway without them.
import osfrom openai import OpenAI client = OpenAI( base_url="https://gateway.worksi.ai/v1", api_key=os.environ["AIW_API_KEY"],) def answer( user_id_hash: str, user_plan: str, messages: list[dict],) -> str | None: headers = { # a pseudonymous id, not an email "X-AIW-End-User": user_id_hash, # your own plan name, e.g. "free" "X-AIW-End-User-Plan": user_plan, } res = client.chat.completions.create( model="gpt-5-mini", messages=messages, extra_headers=headers, ) return res.choices[0].message.contentimport OpenAI from "openai" const client = new OpenAI({ baseURL: "https://gateway.worksi.ai/v1", apiKey: process.env.AIW_API_KEY,}) export async function answer( userIdHash, userPlan, messages,) { const headers = { // a pseudonymous id, not an email "X-AIW-End-User": userIdHash, // your own plan name, e.g. "free" "X-AIW-End-User-Plan": userPlan, } const res = await client.chat .completions.create( { model: "gpt-5-mini", messages }, { headers }, ) return res.choices[0]?.message.content}from aiworkforce import AIW, EndUserQuotaExceededError aiw = AIW(service="acme-chat", default_end_user_plan="free")client = aiw.openai() def answer( user_id_hash: str, user_plan: str, messages: list[dict],) -> str | None: try: # every call in the run carries the user and plan with aiw.run("chat-answer", end_user=user_id_hash, end_user_plan=user_plan) as run: res = client.chat.completions.create( model="gpt-5-mini", messages=messages, ) run.outcome("question_answered") return res.choices[0].message.content except EndUserQuotaExceededError as err: # over the limit: your provider was never called return upgrade_prompt(err.plan, err.resets_at)Give your free tier a real limit.
Send the user’s id hash and plan name with each call. Over the plan’s limit, the gateway answers 429 before your provider is called.
- 3‑day trial with Pro features, no card.
Keep readingAI chat & copilotsPricingGovernance
curl https://gateway.worksi.ai/v1/chat/completions \ -H "Authorization: Bearer $AIW_API_KEY" \ -H "X-AIW-End-User: $USER_ID_HASH" \ -H "X-AIW-End-User-Plan: free" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-5-mini", "messages": [{"role": "user", "content": "Hi"}]}'