---
title: "Set or clear a tenant's meeting-recording limits"
method: PUT
path: "/v1/admin/tenants/{tenant_id}/meeting-limits"
tags: ["admin"]
---

# Set or clear a tenant's meeting-recording limits

`PUT /v1/admin/tenants/{tenant_id}/meeting-limits`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/admin/tenants/{tenant_id}/meeting-limits`
- Auth: HTTP bearer

Platform-admin only. An omitted field is left unchanged; an explicit null clears the override so the tenant inherits the fleet default again.

## Path parameters

- `tenant_id` string, uuid, required

## Request body

- AdminMeetingLimitsUpdate: PUT body: an omitted field is left alone, an explicit ``null`` CLEARS the override. The three states are the point. ``max_concurrent_bots`` is nullable in the database precisely so a tenant can inherit ``API_RECALL_MAX_CONCURRENT_BOTS_DEFAULT`` rather than be pinned to whatever it happened to equal on the day someone edited it — sending ``null`` puts a tenant back on the default and keeps it moving with future default changes. ``model_fields_set`` on the handler is what separates "omitted" from "explicitly null"; a plain ``None`` default cannot.
  - `max_concurrent_bots` integer, nullable
  - `monthly_minutes_budget` integer, nullable
  - `expected_revision` string, date-time, nullable, required: The revision this edit was based on, from GET (an offset-aware timestamp). Send null if that reported no row. A 409 means someone else changed it first: reload and re-apply.

## Response `200`

Successful Response

- AdminMeetingLimitsView: The three-layer readout: the override, the inherited default, and what the gate enforces. An operator about to change a cap needs to know whether the number on screen is this tenant's own or the fleet default it is currently inheriting, because clearing an override and setting it to the same value look identical afterwards but behave differently the next time the default moves.
  - `tenant_id` string, uuid, required
  - `max_concurrent_bots` integer, nullable, required: This tenant's override, or null when it inherits.
  - `monthly_minutes_budget` integer, nullable, required: This tenant's override, or null when it inherits.
  - `default_max_concurrent_bots` integer, required: The fleet default an override-less tenant inherits.
  - `default_monthly_minutes_budget` integer, required: The fleet default an override-less tenant inherits.
  - `effective_max_concurrent_bots` integer, required: What the pre-join gate actually enforces today.
  - `effective_monthly_minutes_budget` integer, required: What the pre-join gate actually enforces today.
  - `revision` string, date-time, nullable: Opaque token for this row's state; send it back as expected_revision to edit safely.

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: Not found
- `409`: Conflict
- `422`: Validation error

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
