Skip to main content

API reference

Use these APIs from your backend to import customers, set budgets, and return usage to your product. For a complete integration, follow Track customer spend.

The management base path is /management/v1. Customer organizations, teams, and members are separate from LiteLLM's internal organizations, teams, users, and /customer end-user records.

Availability​

The management and usage routes below are on main. Check your gateway's /openapi.json and apply its customer migrations. A published release containing the complete integration has not been verified.

CapabilityRequired change
Organization, team, member, template, and usage APIsOn main; members use budget_id.
Identity headers, first-request member registration, and hierarchy budget checksOn main, including #51546.
Fresh shared customer spend countersOn main, including #51568.
Member email field and email identity headerPreview: #51617.
Customer identity fields in request logsOn main, including #51596.
Customer budget events and webhook callbackOn main, including #51579 and the recurring-period, member-event, and team-override fixes in #51645.
Native upserts and first-request organization creationUnder review in #51607; not documented as a supported contract.
Fail-open customer identity handlingUnder review in #51604; configuration and asserted-identity logging remain unverified.

Preview features require a build containing the linked change while it remains unmerged.

Free-tier support limits the customer portal to 5 organizations, 5 teams per organization, and 5 members per team without Enterprise. Check /openapi.json for /management/v1/customer_portal/limits to confirm your build includes it.

Authentication and conventions​

Send Authorization: Bearer $LITELLM_ADMIN_KEY on management requests. These routes require proxy_admin, including list, retrieve, and usage requests. Keep this key on your server and authorize the customer before returning data to your application.

Examples use LITELLM_BASE_URL for your gateway's base URL, without /v1 or /ui. They use curl from your terminal.

export LITELLM_BASE_URL="http://localhost:4000"
export END_DATE="$(date -u +%Y-%m-%d)"
export START_DATE="$END_DATE"

Usage examples query today in UTC. Set START_DATE to an earlier YYYY-MM-DD value for a longer range.

Set LITELLM_ADMIN_KEY through your secret store or existing terminal environment. Send JSON bodies with Content-Type: application/json.

Create parents before children. IDs identify records across the gateway, so use a customer prefix such as acme-support. Omit a resource ID to let LiteLLM generate one. URL-encode IDs in paths. Use IDs without commas when you query usage through comma-separated filters.

Creation returns 201. Retrieval and updates return 200 with a resource object at the top level. Deletion returns 204 with no body. Resource lists return data, meta, and links; usage reads return results and metadata.

Retry a customer import​

A repeated POST with an existing ID returns 409; it does not update the record. After a timeout or 409, retrieve that ID, compare its parent and settings with your application, then use PATCH for the required changes. Omit unchanged fields in a patch. An explicit null clears a nullable field where the resource permits it.

Budget object​

Organizations and teams accept budget. Members inherit a template through budget_id and accept budget_override for their own settings.

FieldType and defaultMeaning
max_budgetNumber or null; default nullSpend cap in USD. Must be finite and at least 0.
soft_budgetNumber or null; default nullSoft threshold in USD, finite and at least 0. This value does not block requests. Notifications require the customer budget callback.
rpm_limitInteger or null; default nullRequests per minute. Must be at least 0.
tpm_limitInteger or null; default nullTokens per minute. Must be at least 0.
allowed_modelsArray of strings or null; default nullAllowed gateway model names. A non-empty member override replaces the inherited list. An empty override list inherits the template's list.
budget_durationString or null; default nullReset interval, for example "1h", "24h", "7d", or "30d". Must resolve to a positive duration.
model_rpm_limitObject or null; default nullModel name to non-negative requests-per-minute limit.
model_tpm_limitObject or null; default nullModel name to non-negative tokens-per-minute limit.
budget_limitsArray or null; default nullExtra spend caps, each with budget_duration set to "1mo" or "12mo" and a max_budget. Each window resets on its own and blocks requests when reached.
cap_policy"pause_until_reset", "pause_allow_increase", or null; default nullWhat a member can do at its cap. null and "pause_until_reset" wait for the reset. "pause_allow_increase" lets the member request a temporary increase.

With customer identity headers, LiteLLM checks the organization, team, and member budgets before inference. A scope at or above max_budget causes a budget error; the organization takes precedence over the team and member. LiteLLM also checks each scope's model access and rate limits. Requests without these headers do not enter this hierarchy enforcement path.

Builds preceding the shared customer spend counter fix can use cached hierarchy spend until refresh. Use a build containing that change. Allow for requests already in flight and background accounting when you display balances.

The reset job updates budget_reset_at and the resource's running spend counter for a configured duration. Read the returned timestamp; use the usage APIs for historical dates. Budget resets do not erase historical daily usage.

Common response fields​

Each organization, team, and member includes these fields in addition to its resource-specific fields.

FieldTypeMeaning
aliasString or nullDisplay name.
spendNumber; initial value 0Recorded budget spend in USD. Accounting updates this value in the background.
budget_reset_atDatetime or nullNext recorded reset time.
created_at, updated_atDatetimeCreation and last-update timestamps.
created_by, updated_byStringActor recorded for each write.

Customer portal limits​

GET /management/v1/customer_portal/limits requires a proxy admin key and returns 200 with current customer portal capacity. It accepts no query parameters or request body.

curl "$LITELLM_BASE_URL/management/v1/customer_portal/limits" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY"
Response fieldTypeMeaning
limits_applyBooleantrue without a LiteLLM Enterprise license.
organization_limitIntegerFree-tier organization limit, 5.
teams_per_organization_limitIntegerFree-tier teams per organization, 5. Includes the auto-created default team.
members_per_team_limitIntegerFree-tier members per team, 5. A member counts toward every team in its parent_team_ids.
organization_countIntegerTotal registered customer organizations.
any_limit_reachedBooleantrue when limits apply and the organization count is at least 5, any organization has at least 5 teams, or any team has at least 5 members. Always false with Enterprise.
Free-tier deployment at the organization limit
{
"limits_apply": true,
"organization_limit": 5,
"teams_per_organization_limit": 5,
"members_per_team_limit": 5,
"organization_count": 5,
"any_limit_reached": true
}

Enterprise removes the limits. The numeric fields still report the free-tier thresholds when limits_apply is false. See free-tier behavior for request tracking at capacity and after a license lapses.

Customer organizations​

MethodPathResult
POST/management/v1/customer_organizations201, organization.
GET/management/v1/customer_organizations200, organization list. Supports q.
GET/management/v1/customer_organizations/{customer_org_id}200, organization.
PATCH/management/v1/customer_organizations/{customer_org_id}200, updated organization.
DELETE/management/v1/customer_organizations/{customer_org_id}204. Delete its teams first.

Request fields​

FieldCreateUpdateMeaning
customer_org_idOptional, generated when omittedNot acceptedStable organization ID.
aliasOptional, default nullOptional; null clears itDisplay name and value used by x-litellm-customer-org-alias. Use a unique alias for header lookup.
budgetOptional, default nullOptional; null removes the overall budgetOrganization budget object.
default_budgetsOptional, default []Not acceptedNamed member templates. A single template becomes the default; with several, select one by name through default_budget_template.
default_budget_templateOptional, default nullNot acceptedName from default_budgets to use for new members. Required when creating several templates.
default_budget_template_idNot acceptedOptional; null clears the defaultTemplate ID from this organization's default_budgets. Changes the default for new members.
Additional response fieldTypeMeaning
customer_org_idStringOrganization ID.
budget_idString or nullOrganization's own budget record.
budgetBudget object or nullOrganization's overall limits.
member_countIntegerRegistered members across the organization's teams.
default_budget_template_idString or nullDefault member template ID.
default_budgetsArrayMember templates, each with budget fields plus budget_id and name. Compare budget_id with default_budget_template_id to identify the default.
Create an organization with a default member template
curl --request POST \
"$LITELLM_BASE_URL/management/v1/customer_organizations" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{
"customer_org_id": "org-acme",
"alias": "Acme",
"budget": {
"max_budget": 1000,
"budget_duration": "30d"
},
"default_budgets": [
{
"name": "standard",
"max_budget": 50,
"budget_duration": "30d"
}
],
"default_budget_template": "standard"
}'

Customer teams​

MethodPathResult
POST/management/v1/customer_teams201, team.
GET/management/v1/customer_teams200, team list. Supports parent_org_id.
GET/management/v1/customer_teams/{customer_team_id}200, team.
PATCH/management/v1/customer_teams/{customer_team_id}200, updated team.
DELETE/management/v1/customer_teams/{customer_team_id}204. Delete its members first.
Request fieldCreateUpdateMeaning
customer_team_idOptional, generated when omittedNot acceptedStable team ID.
parent_org_idRequiredNot acceptedExisting customer organization ID.
aliasOptional, default nullOptional; null clears itDisplay name.
budgetOptional, default nullOptional; null removes itTeam budget object.
budget_overrideOptional, default nullOptional; null removes itTeam budget fields that override budget.
budget_override_expires_atOptional, default nullOptional; null removes expiryTimestamp with a timezone. After expiry, the team uses budget.
Additional response fieldTypeMeaning
customer_team_id, parent_org_idStringTeam ID and its customer organization ID.
budget_idString or nullTeam's own budget record.
budgetBudget object or nullTeam limits. An absent team budget does not remove organization or member limits.
budget_override_id, budget_override, budget_override_expires_atString, budget object, and datetime, each nullableStored team override and its expiry.
effective_budgetBudget objectTeam budget plus its active override.
Create a customer team
curl --request POST \
"$LITELLM_BASE_URL/management/v1/customer_teams" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{
"customer_team_id": "acme-support",
"parent_org_id": "org-acme",
"alias": "Support",
"budget": {
"max_budget": 250,
"budget_duration": "30d"
}
}'

Customer members​

MethodPathResult
POST/management/v1/customer_members201, member. One member per request.
GET/management/v1/customer_members200, member list. Supports parent_team_id.
GET/management/v1/customer_members/{customer_member_id}200, member with its effective budget.
PATCH/management/v1/customer_members/{customer_member_id}200, updated member.
DELETE/management/v1/customer_members/{customer_member_id}204. Removes its owned override budget.
Request fieldCreateUpdateMeaning
customer_member_idOptional, generated when omittedNot acceptedStable member ID.
parent_team_idsRequired, non-empty arrayNot acceptedExisting customer team IDs from one customer organization. The first team is the member's default team.
parent_org_idOptionalNot acceptedCustomer organization ID. When set, it must match the teams' organization.
emailOptional, default null; preview #51617Optional; null clears it; preview #51617String of 1–254 characters after trimming and lowercasing. Unique within the customer organization.
aliasOptional, default nullOptional; null clears itDisplay name.
budget_idOptional; omitted or null uses the organization's default templateOptional; null detaches the templateMember template ID from the same customer organization.
budget_overrideOptional, default nullOptional; null removes itMember budget fields that override the template.
budget_override_expires_atOptional, default nullOptional; null removes expiryTimestamp with a timezone. After expiry, the member uses its template's settings.

Use budget_id for the selected member template. The current API rejects the old budget_template_id field. The response's budget_override_id identifies the separate override record; it is read-only.

A member needs a selected template or budget_override. LiteLLM merges non-null override fields with the template. A non-empty allowed_models override replaces inherited models. Read effective_budget to display the settings that apply now, including override expiry.

Create a member using the organization's default template
curl --request POST \
"$LITELLM_BASE_URL/management/v1/customer_members" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{
"customer_member_id": "acme-alice",
"parent_team_ids": ["acme-support"],
"alias": "Alice"
}'
Additional response fieldTypeMeaning
customer_member_id, parent_org_idStringMember ID and its customer organization ID.
parent_team_idsArray of stringsMember's customer teams, default team first.
emailString or null; preview #51617Normalized email, when the build includes member email support.
budget_idString or nullSelected organization template.
budget_override_idString or nullOwned override record.
budget_overrideBudget object or nullStored override, including an override that has expired.
budget_override_expires_atDatetime or nullStored override expiry.
effective_budgetBudget objectTemplate plus active overrides.
Member email requires #51617

Main uses customer_member_id for member identity. Sending an email string as that ID does not look up an existing member by email. The email resource field and x-litellm-customer-member-email header require a build containing #51617. That header requires x-litellm-customer-org-alias; conflicting member ID and email identities return 403.

Member budget templates​

Templates belong to a customer organization. Updating a template changes the settings its members inherit. Changing the default template affects new members; it does not reassign existing members.

MethodPathResult
POST/management/v1/customer_organizations/{customer_org_id}/default_budgets201, organization with its updated default_budgets.
PATCH/management/v1/customer_organizations/{customer_org_id}/default_budgets/{budget_id}200, updated organization.
DELETE/management/v1/customer_organizations/{customer_org_id}/default_budgets/{budget_id}204. Template must be unused and must not be the default.

Creation accepts a budget object plus required non-empty name. Names must be unique within the organization. The first template becomes the default. Updating accepts budget fields and optional name. Template requests do not accept is_default; select the default through the organization's default_budget_template_id field.

Add a named member template
curl --request POST \
"$LITELLM_BASE_URL/management/v1/customer_organizations/org-acme/default_budgets" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{
"name": "extended",
"max_budget": 100,
"budget_duration": "30d"
}'

To make this template the default for new members, copy its budget_id from the response's default_budgets array. Replace <budget_id> below with that value:

Choose the default member template
curl --request PATCH \
"$LITELLM_BASE_URL/management/v1/customer_organizations/org-acme" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{"default_budget_template_id":"<budget_id>"}'

Changing the default does not reassign existing members. Select another default or clear it before deleting the current template; a referenced template still cannot be deleted.

Budget increase requests​

A member whose effective budget has cap_policy: "pause_allow_increase" can ask for a temporary cap. The budget error at the cap names this route. Members with any other policy get 422.

MethodPathResult
POST/management/v1/customer_budget_increase_requests201, request with status: "pending_review".
GET/management/v1/customer_budget_increase_requests200, review queue.
GET/management/v1/customer_budget_increase_requests/{request_id}200, one request.
PUT/management/v1/customer_budget_increase_requests/{request_id}/approve200. The member's override takes requested_max_budget until expires_at.
PUT/management/v1/customer_budget_increase_requests/{request_id}/reject200. The member stays paused. Accepts optional review_notes.

Creation requires customer_member_id, requested_max_budget, and a timezone-aware expires_at, and accepts an optional reason.

Request a temporary increase
curl --request POST \
"$LITELLM_BASE_URL/management/v1/customer_budget_increase_requests" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data '{
"customer_member_id": "acme-alice",
"requested_max_budget": 75,
"expires_at": "2026-12-01T00:00:00Z",
"reason": "Quarter-end workload"
}'

List pagination​

Organization, team, and member lists share these query parameters. Unknown parameters and repeated query parameters return 400.

ParameterDefaultMeaning
page1Page number, at least 1.
page_size50Requested rows, at least 1. The server caps it at 100.
q""Organization lists only. Case-insensitive substring of organization ID or alias.
parent_org_idUnsetTeam lists only. Restrict to one organization.
parent_team_idUnsetMember lists only. Restrict to members of one team.
List a customer's teams
curl --get \
"$LITELLM_BASE_URL/management/v1/customer_teams" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
--data-urlencode "parent_org_id=org-acme" \
--data-urlencode "page=1" \
--data-urlencode "page_size=100"

The response contains data (resource objects), meta.total_count, meta.page, meta.page_size, meta.total_pages, and links.self, first, prev, next, and last. prev and next are null when no such page exists. Follow links.next or stop at meta.total_pages.

Attribute inference requests​

Send these headers with the inference key you use for your application. They work on Chat Completions, Responses, and Anthropic Messages.

HeaderMeaning
x-litellm-customer-org-aliasResolve a customer organization by its alias. Alone, charges and checks the organization scope.
x-litellm-customer-member-idResolve a member, then its parent team and organization. Alone, requires an existing member.

With both headers, LiteLLM checks that the member belongs to that organization. An unknown member joins the organization's default team when the organization has a default member budget. LiteLLM generates that team's ID as {customer_org_id}:default. An unknown organization alias returns 401; a shared alias returns 400; a mismatched member and organization returns 403.

Use your existing application key across customers. Your backend chooses the organization alias and member ID from the authenticated customer session and passes them in the SDK request. See the OpenAI Responses and Deep Agents examples.

Supported inference APIRoute
OpenAI ResponsesPOST /v1/responses
Chat CompletionsPOST /v1/chat/completions
Anthropic MessagesPOST /v1/messages

Customer usage​

All four reads require a proxy admin key. Dates use inclusive UTC calendar days. Spend uses USD; tokens and requests use integer counts. Query each hierarchy level separately for its breakdown; adding organization, team, and member totals counts the same requests more than once.

MethodPathCustomer filterPagination
GET/management/v1/customer_organizations/daily/activitycustomer_org_idspage, page_size.
GET/management/v1/customer_teams/daily/activitycustomer_team_idspage, page_size.
GET/management/v1/customer_members/daily/activitycustomer_member_idspage, page_size.
GET/management/v1/customer_organizations/daily/activity/aggregatedRequired customer_org_ids, 1–100 IDsComplete range totals in one response.

Daily activity parameters​

ParameterDefaultMeaning
start_date, end_dateRequiredDates in YYYY-MM-DD format.
Customer filter from the table aboveUnset on paginated routesComma-separated IDs. Omitting it queries all customer entities visible to the proxy admin.
exclude_customer_org_ids, exclude_customer_team_ids, exclude_customer_member_idsUnsetPaginated routes only. Use the exclusion field for the route's entity type.
modelUnsetFilter by recorded model.
api_keyUnsetFilter by reporting API key ID from a usage response. Do not put a raw inference key in the URL.
page1Paginated routes only. Must be at least 1.
page_size10Paginated routes only. Must be at least 1.

Unknown query parameters and repeated parameters return 400. The aggregated route accepts at most a 400-day difference between its start and end dates. It returns complete spend, request, and token totals; its API key breakdown includes only the top key.

Complete organization totals for your product
curl --get \
"$LITELLM_BASE_URL/management/v1/customer_organizations/daily/activity/aggregated" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
--data-urlencode "customer_org_ids=org-acme" \
--data-urlencode "start_date=$START_DATE" \
--data-urlencode "end_date=$END_DATE"

Usage pagination​

Organization aggregated usage returns the complete range in one response. Team and member daily activity use page and page_size.

For another page, repeat the request with the next page number:

Second page of member usage
curl --get "$LITELLM_BASE_URL/management/v1/customer_members/daily/activity" \
-H "Authorization: Bearer $LITELLM_ADMIN_KEY" \
--data-urlencode "customer_member_ids=acme-alice" \
--data-urlencode "start_date=$START_DATE" \
--data-urlencode "end_date=$END_DATE" \
--data-urlencode "page=2" \
--data-urlencode "page_size=100"

Sum each page's totals once. Stop when metadata.has_more is false; merge matching dates when building a chart.

Usage response​

FieldMeaning
results[].dateUTC day in YYYY-MM-DD format.
results[].metricsspend, prompt_tokens, completion_tokens, total_tokens, api_requests, successful_requests, failed_requests, and additional recorded metrics.
results[].breakdownMetrics by models, model_groups, providers, endpoints, api_keys, and entities where present. Entity metadata includes its alias.
metadata.total_spend, total_tokens, total_api_requestsTotals for this response.
metadata.page, total_pages, has_morePage information. Aggregated responses use 1, 1, and false.

Paginated activity limits stored rows before grouping them by date. The same date can appear on more than one page. Sum each page's totals once and merge matching dates until metadata.has_more is false. Increment page until metadata.has_more is false.

Usage response excerpt
{
"results": [{
"date": "2026-11-13",
"metrics": {"spend": 0.14, "total_tokens": 120, "api_requests": 1}
}],
"metadata": {
"total_spend": 0.14,
"total_tokens": 120,
"total_api_requests": 1,
"page": 1,
"total_pages": 1,
"has_more": false
}
}

Accounting writes usage in the background. Check the date range and customer headers if a successful inference request has no usage yet. A zero-cost model can report tokens and requests with no spend.

Customer budget events​

Customer budget events are on main through #51579 and the customer budget alert fix, #51645, for recurring periods, member events, and team overrides. Use a build containing both changes. Register customer_budget_webhook in litellm_settings.callbacks. Configure it through top-level callback_settings.customer_budget_webhook:

SettingTypeMeaning
endpointHTTP or HTTPS URLReceiver URL. Falls back to CUSTOMER_BUDGET_WEBHOOK_URL when omitted. Required through one of these sources.
headersObject of string valuesAdditional request headers. Overrides matching values from CUSTOMER_BUDGET_WEBHOOK_HEADERS, a JSON object supplied through the environment. Defaults to Content-Type: application/json.

The callback posts the event directly as JSON. The guide provides a complete configuration and sample payload. It uses the same event object as CustomLogger.async_on_customer_budget_event(event: CustomerBudgetEvent).

Event fieldTypeMeaning
event"soft_budget_crossed" or "budget_crossed"Recorded spend is at or above the corresponding configured threshold after a positive spend update commits.
scope"customer_org", "customer_team", or "customer_member"Scope whose threshold was reached.
entity_idStringID at the event's scope.
customer_org_id, customer_org_aliasString or nullResolved customer organization.
customer_team_id, customer_team_aliasString or nullResolved team for team events; null for organization and member events.
customer_member_id, customer_member_aliasString or nullResolved member for member events; null at other scopes.
spendNumberRecorded spend in USD after accounting.
budgetNumberThreshold in USD: soft_budget or max_budget, according to event.
periodStringRecorded next reset timestamp, or "lifetime" when no reset is recorded.
timestampDatetimeTime the event was detected.

Teams and members use their effective template and active override. Member budgets cover the member across teams, so member events have no team ID or alias. One update can emit both event types at multiple scopes. Requests rejected before inference, zero-cost updates, and refunds do not trigger this detector.

The webhook accepts successful 2xx responses and has a 10-second timeout. Delivery is best effort. An event claim is keyed by (event, scope, entity_id, period) until that budget period resets and is retained even if delivery fails. Lifetime budgets use a cache claim with a 100-year TTL. Shared Redis coordinates claims across workers; an in-memory fallback can produce duplicates. The HTTP client retries a connection error once. There is no durable retry queue, backoff, or replay API for HTTP errors or timeouts. Use usage reads to reconcile missed events; do not use the callback as your only billing record.

Errors​

Management errors use problem details with type, title, status, and detail. An unknown query parameter response can include allowed, the accepted parameter names.

StatusCause and next action
400Unknown or repeated query parameter, invalid date range, or invalid pagination. Check the route's parameter table.
401Missing or invalid authentication. On inference, also check an unknown member or organization alias.
403Caller lacks proxy_admin, or the member does not belong to the supplied customer organization.
403Free-tier create limit. Type urn:litellm:error:customer-hierarchy-free-tier-limit, title Free customer portal limit reached, detail Free customer portal limit reached: up to 5 customer organizations, 5 teams per organization and 5 members per team without a LiteLLM Enterprise license. Upgrade to Enterprise to remove the limits: https://www.litellm.ai/enterprise. Upgrade to Enterprise or free capacity before retrying.
404Resource or parent does not exist. Retrieve or create the parent first.
409Duplicate ID, parent still has children, or template remains default or referenced.
422Invalid body, budget value, template selection, or missing member budget. Inference budget rejection also uses 422 with an inference error body.
429Inference request exceeds a configured rate limit.
503Management database is unavailable.
Duplicate customer ID
{
"type": "urn:litellm:error:customer-hierarchy-already-exists",
"title": "Already exists",
"status": 409,
"detail": "Customer entity ID already exists."
}