Admin - Usage Limits
Usage limits cap how many credits a user can spend in a week or a month. Set a default limit for everyone with a role in a tenant, and override it for individual users. Use these endpoints to list, set and remove the limits in the tenants your MSP manages.
Who Can Call These Endpoints
The API key must belong to a user on your MSP (admin.hatz.ai) account whose role includes the Manage Usage Limits permission. Among the default MSP roles, Primary Admin, Admin, Tenant Manager and Billing Manager include it; Helpdesk does not.
| Caller | Result |
|---|---|
| MSP user with Manage Usage Limits | Can manage limits in every tenant your MSP manages, or, if your MSP restricts users to their account teams, in the tenants assigned to them (others return 403) |
| MSP user without Manage Usage Limits | 403 |
| Tenant (company) user, including a tenant admin | 403 with "Insufficient permissions" |
| Any user, for a tenant that belongs to another MSP | 403 |
| Missing or invalid API key | 401 |
How Limits Work
Each limit has a period, a credit limit and an action.
- Periods are independent. A user can have a weekly limit and a monthly limit at the same time.
monthlyresets at 00:00 UTC on the first day of each month.weeklyresets every Wednesday at 12:00 America/New_York.
- Credit limit is the number of credits allowed in the period, from 0 to 1,000,000,000,000. A limit of
0is reached immediately. - Action is what happens when a user reaches the limit:
blockstops further usage until the period resets.auto_onlylets the user keep working with Auto (Hatz's automatic model selection), restricted to the modes listed inauto_llm_mode_set(lite,performance,turbo). If twoauto_onlylimits are reached at once, only the modes in both lists remain. If none remain, usage is blocked.
For each period, a user's effective limit is:
- Their user override for that period, if one exists. It applies whether it is higher or lower than the role default.
- Otherwise, the role default for their role in their tenant.
- Otherwise, no limit.
A monthly override replaces only the monthly role default. A weekly role default still applies.
Changing a limit never changes a user's role or permissions.
IDs
tenant_idis the tenant ID returned by List Tenants (GET /v1/admin/tenants), for exampletenant_abc123. A tenant UUID also works.role_idis a role HashID (role_...) from List Roles on the Admin - Roles page.- Built-in platform roles use
role_source: "default". - Custom roles use
role_source: "custom".
- Built-in platform roles use
user_idis a user HashID (user_...). Get it from Get Tenant Users (GET /v1/admin/tenants/{tenant_id}/users) on the Admin - Tenant page.
The Limit Object
List Usage Limits returns each limit in this shape:
| Field | Description |
|---|---|
credit_limit |
Credits allowed per period |
action |
block or auto_only |
auto_llm_mode_set |
Auto modes still allowed at the limit; null for block |
subject_type |
role for a role default, user for a user override |
subject_id |
The role or user HashID |
period |
monthly or weekly |
scope |
tenant for a limit set on this tenant. msp for a custom role defined across your MSP, whose limit applies in every tenant of your MSP. |
role_source |
default or custom for role rows; null for user rows |
List Usage Limits
List the role defaults and user overrides that apply to a tenant.
Endpoint
GET /v1/admin/tenants/{tenant_id}/usage-limits
Path Parameters
tenant_id(required): Tenant ID (e.g., "tenant_abc123")
Query Parameters
limit(optional): Rows per page (1-1000, default: 100)offset(optional): Rows to skip (default: 0)
Pagination
total_count is the number of rows before limit and offset are applied. Increase offset by limit, and stop when the next offset would be equal to or greater than total_count. For example, with total_count 150 and limit 100, request offsets 0 and 100, then stop. An offset beyond total_count returns 400, not an empty page.
Example Query
curl 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/usage-limits' \
-H "X-API-Key: $HATZ_API_KEY"
Response
{
"limits": [
{
"credit_limit": 750.0,
"action": "auto_only",
"auto_llm_mode_set": ["lite"],
"subject_type": "role",
"subject_id": "role_O8oZwaNGyJoDVCeKAL8N84wx5W",
"period": "monthly",
"scope": "tenant",
"role_source": "default"
},
{
"credit_limit": 200.0,
"action": "auto_only",
"auto_llm_mode_set": ["lite", "performance"],
"subject_type": "role",
"subject_id": "role_aEyZ6Vr5zOW8JH28MJzmEVp2an",
"period": "weekly",
"scope": "msp",
"role_source": "custom"
},
{
"credit_limit": 50.0,
"action": "block",
"auto_llm_mode_set": null,
"subject_type": "user",
"subject_id": "user_ExxypMkWV0PLDUAyLpdJlOEJ69",
"period": "monthly",
"scope": "tenant",
"role_source": null
}
],
"total_count": 3
}
Set Role Usage Limit
Create or replace the default limit for one role and period. It applies to everyone with that role in the tenant who has no user override for the same period.
For a custom role defined across your MSP, the limit is stored once and applies in every tenant of your MSP. It appears with scope: "msp" when you list any of those tenants.
Endpoint
PUT /v1/admin/tenants/{tenant_id}/usage-limits/roles/{role_id}
Path Parameters
tenant_id(required): Tenant IDrole_id(required): Role HashID
Request Body
role_source(required):defaultfor a built-in platform role,customfor a custom role. It must match the role; a mismatch returns404.period(required):monthlyorweeklycredit_limit(required): Credits allowed per period (0 to 1,000,000,000,000)action(required):blockorauto_onlyauto_llm_mode_set(required withauto_only, not allowed withblock): One or more oflite,performance,turbo
Unknown fields are rejected with 422.
Example Request
curl -X PUT 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/usage-limits/roles/role_O8oZwaNGyJoDVCeKAL8N84wx5W' \
-H "X-API-Key: $HATZ_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"role_source": "default",
"period": "monthly",
"credit_limit": 750,
"action": "auto_only",
"auto_llm_mode_set": ["lite"]
}'
Response
previous is the limit before the change, or null if there was none. previous and current hold only credit_limit, action and auto_llm_mode_set; call List Usage Limits for the full rows.
{
"previous": {
"credit_limit": 500.0,
"action": "block",
"auto_llm_mode_set": null
},
"current": {
"credit_limit": 750.0,
"action": "auto_only",
"auto_llm_mode_set": ["lite"]
}
}
Delete Role Usage Limit
Remove a role's default limit for one period.
Endpoint
DELETE /v1/admin/tenants/{tenant_id}/usage-limits/roles/{role_id}?period={period}&role_source={role_source}
Query Parameters
period(required):monthlyorweeklyrole_source(required):defaultorcustom, matching the role
Example Request
curl -X DELETE 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/usage-limits/roles/role_O8oZwaNGyJoDVCeKAL8N84wx5W?period=monthly&role_source=default' \
-H "X-API-Key: $HATZ_API_KEY"
Response
{
"deleted": true,
"previous": {
"credit_limit": 750.0,
"action": "auto_only",
"auto_llm_mode_set": ["lite"]
}
}
Deleting a limit that doesn't exist is not an error: it returns 200 with "deleted": false and "previous": null.
Set User Usage Limit
Create or replace a user's override for one period. The user must belong to the tenant.
Endpoint
PUT /v1/admin/tenants/{tenant_id}/usage-limits/users/{user_id}
Path Parameters
tenant_id(required): Tenant IDuser_id(required): User HashID
Request Body
period(required):monthlyorweeklycredit_limit(required): Credits allowed per period (0 to 1,000,000,000,000)action(required):blockorauto_onlyauto_llm_mode_set(required withauto_only, not allowed withblock): One or more oflite,performance,turbo
role_source is not accepted here; sending it returns 422.
Example Request
curl -X PUT 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/usage-limits/users/user_ExxypMkWV0PLDUAyLpdJlOEJ69' \
-H "X-API-Key: $HATZ_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"period": "monthly",
"credit_limit": 50,
"action": "block"
}'
Response
{
"previous": null,
"current": {
"credit_limit": 50.0,
"action": "block",
"auto_llm_mode_set": null
}
}
A user who is not in the tenant gets 400 with the generic message "Database request failed". A user ID that matches no user returns 404.
Delete User Usage Limit
Remove a user's override for one period. Their role default applies again.
Endpoint
DELETE /v1/admin/tenants/{tenant_id}/usage-limits/users/{user_id}?period={period}
Query Parameters
period(required):monthlyorweekly
Example Request
curl -X DELETE 'https://ai.hatz.ai/v1/admin/tenants/tenant_abc123/usage-limits/users/user_ExxypMkWV0PLDUAyLpdJlOEJ69?period=monthly' \
-H "X-API-Key: $HATZ_API_KEY"
Response
{
"deleted": true,
"previous": {
"credit_limit": 50.0,
"action": "block",
"auto_llm_mode_set": null
}
}
As with role limits, deleting an override that doesn't exist returns 200 with "deleted": false.
Error Responses
Errors use the standard envelope:
{
"error": {
"type": "HTTPException",
"message": "Custom role not found",
"details": {},
"path": "/v1/admin/tenants/tenant_abc123/usage-limits/roles/role_O8oZwaNGyJoDVCeKAL8N84wx5W"
}
}
| Status | When |
|---|---|
400 |
A malformed tenant, role or user ID, or a tenant HashID that matches no tenant ("Invalid tenant ID format…"). Also a user override for a user outside the tenant, or an offset beyond total_count, both with "Database request failed". |
401 |
Missing or invalid API key |
403 |
The caller is not allowed to manage limits in this tenant (see Who Can Call These Endpoints) |
404 |
A tenant UUID that matches no tenant, a user ID that matches no user, or a role_source that does not match the role ("Custom role not found", "platform role not found") |
422 |
Invalid body or query: missing fields, unknown fields, block with modes, auto_only without modes, a limit outside 0 to 1,000,000,000,000, or a period other than monthly/weekly (type is RequestValidationError) |