> ## Documentation Index
> Fetch the complete documentation index at: https://cal.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# User booking limits

> Cap the total number of bookings a user can accept across all event types per day, week, month, or year.

User booking limits let you restrict how many bookings a user can accept across **all** their event types — both personal and team — within a given time window. This is different from [event-type booking limits](#user-limits-vs-event-type-limits), which only apply to a single event type.

> [!NOTE]
>
> The `/v2/me/booking-limits` endpoints are available to organization members only. Non-org accounts receive a `403` response.

## How it works

When a user has booking limits configured, Cal.com checks the total number of accepted bookings for that user before allowing a new one. If the user has already reached their limit for the current period, the time slots are marked as unavailable and new bookings are rejected.

Limits can be set for any combination of these intervals:

| Interval | Description |
| - | - |
| `perDay` | Maximum bookings per calendar day |
| `perWeek` | Maximum bookings per calendar week |
| `perMonth` | Maximum bookings per calendar month |
| `perYear` | Maximum bookings per calendar year |

You can set one or more intervals simultaneously. For example, you could allow up to 5 bookings per day but no more than 20 per week.

> [!NOTE]
>
> When multiple intervals are set, the stricter limit at any given moment takes precedence. A daily limit of 3 and a weekly limit of 10 means a user can never exceed 3 bookings on a single day, even if they haven't reached 10 for the week.

## Setting limits in the UI

You can configure user booking limits in **Settings > My Account > General**. Toggle the booking limits option, set your desired limits for each interval, and click **Update** to save.

## Setting limits via the API

The dedicated `/v2/me/booking-limits` endpoints let you read, update, and clear the authenticated user's global limits without round-tripping the full `/v2/me` payload. These endpoints are only available to organization members and return `403` for non-org accounts. OAuth clients need the `PROFILE_READ` scope to read and `PROFILE_WRITE` scope to update or clear.

### Read current limits

Use [`GET /v2/me/booking-limits`](https://cal.com/docs/api-reference/v2/me/get-my-booking-limits) to fetch the authenticated user's limits. Unset bounds are returned as `null`.

```bash theme={null}
curl https://api.cal.com/v2/me/booking-limits \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json theme={null}
{
  "status": "success",
  "data": {
    "perDay": 5,
    "perWeek": 20,
    "perMonth": null,
    "perYear": null
  }
}
```

User booking limits are also included in the `GET /v2/me` response under the `bookingLimits` field.

### Update limits

Use [`PATCH /v2/me/booking-limits`](https://cal.com/docs/api-reference/v2/me/update-my-booking-limits) to change one or more intervals. The endpoint has merge semantics: omit a field to leave it untouched, or set it to `null` to remove only that limit.

```bash theme={null}
curl -X PATCH https://api.cal.com/v2/me/booking-limits \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "perDay": 5,
    "perWeek": 20
  }'
```

To clear a single interval without affecting the others, pass `null` for just that field:

```bash theme={null}
curl -X PATCH https://api.cal.com/v2/me/booking-limits \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "perDay": null
  }'
```

### Clear all limits

Use [`DELETE /v2/me/booking-limits`](https://cal.com/docs/api-reference/v2/me/clear-my-booking-limits) to remove every limit in a single call. The endpoint returns `204 No Content` on success.

```bash theme={null}
curl -X DELETE https://api.cal.com/v2/me/booking-limits \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Check how much of each limit is used

Use [`POST /v2/insights/booking-limits/usage`](https://cal.com/docs/api-reference/v2/insights/get-booking-limits-usage) to see how many bookings already count against each limit in the day, week, month and year containing `date` (default today). Each limit reads `date` in its own time zone. The counts come from the same queries enforcement uses, so `remaining: 0` means that limit is full.

* `scope: "user"` reports your own limits.
* `scope: "team"` with `selectedTeamId` reports every accepted member of the team. You need `insights.read` on the team, even as a member.
* `scope: "org"` with `eventTypeId` reports every host of that event type across the organization.

Pass `eventTypeId` to add the event type's own limit, which is shared by all its hosts. `binding` is the limit with the least room left for each user. Team booking limits aren't included yet, and an admin `skipBookingLimits` override can still let a booking through when `remaining` is 0.

```bash theme={null}
curl -X POST https://api.cal.com/v2/insights/booking-limits/usage \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scope": "user", "date": "2026-10-13", "eventTypeId": 101, "offset": 0, "limit": 50 }'
```

```json theme={null}
{
  "status": "success",
  "data": {
    "date": "2026-10-13",
    "eventType": {
      "eventTypeId": 101,
      "timeZone": "Europe/London",
      "perDay": null,
      "perWeek": { "limit": 10, "used": 7, "remaining": 3, "periodStart": "2026-10-11", "periodEnd": "2026-10-17" },
      "perMonth": null,
      "perYear": null
    },
    "users": [
      {
        "userUuid": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
        "timeZone": "America/New_York",
        "user": {
          "perDay": { "limit": 4, "used": 3, "remaining": 1, "periodStart": "2026-10-13", "periodEnd": "2026-10-13" },
          "perWeek": null,
          "perMonth": null,
          "perYear": null
        },
        "binding": { "layer": "user", "limitKey": "perDay", "remaining": 1 }
      }
    ],
    "total": 1
  }
}
```

## User limits vs event-type limits

Cal.com supports two levels of booking limits:

| Level | Scope | Where to configure |
| - | - | - |
| **User booking limits** | All bookings for a user across every event type | Settings > My Account > General |
| **Event-type booking limits** | Bookings for a single event type only | Event type settings > Limits tab |

Both levels are enforced independently. If a user has a daily limit of 5 and an event type has a daily limit of 3, the event type can only receive 3 bookings per day — but the user can still accept 2 more bookings on other event types before hitting their personal cap.

## Effect on availability

When a user reaches a booking limit for a given period, all time slots within that period are marked as busy. This means:

* Slots no longer appear as available on booking pages.
* Attempts to book during that period return an error.
* The limit resets at the start of the next period (next day, week, month, or year) based on the user's timezone.

## Per-host limits with booking limit pools

A booking limit pool caps how many bookings each rotating host takes across a set of a team's round-robin event types. The cap is per host, not a shared total, and it applies alongside the limits above. Fixed hosts are never capped by a pool.

> [!NOTE]
>
> Booking limit pools are available to teams granted the per-host booking limits feature. Other teams receive a `404`.

A pool has a mode:

| Mode | A limit of 3 per week means |
| - | - |
| `SHARED` | Each host takes at most 3 bookings across all of the pool's event types. |
| `PER_EVENT` | Each host takes at most 3 bookings on each of the pool's event types. |

Each event type can be in one pool; adding one that is already in another pool returns `409`. A pool has no limit on its event types, but a create or update can send at most 10,000, since `eventTypeIds` is always the pool's whole list. Duplicating an event type into its own team adds the copy to the source's pool when the caller can update the team's event types. Reading pools requires an accepted membership of the team; every write, and listing a pool's hosts, requires permission to update the team's event types. OAuth clients need the `TEAM_EVENT_TYPE_READ` or `TEAM_EVENT_TYPE_WRITE` scope to match.

### Create a pool

```bash theme={null}
curl -X POST https://api.cal.com/v2/teams/123/booking-limit-pools \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Engineering interviews",
    "mode": "SHARED",
    "eventTypeIds": [101, 102],
    "perWeek": 3
  }'
```

`GET /v2/teams/{teamId}/booking-limit-pools` returns the team's pools and the round-robin event types that can be in one, with the pool each is in. Each pool has a read-only `archived` flag; an archived pool is skipped by enforcement until it is restored.

### Update a pool

`PATCH /v2/teams/{teamId}/booking-limit-pools/{poolId}` changes only the fields you send. Send an interval as `null` to remove it; a pool needs at least one interval. Changing the mode or the event types keeps every host's own limit.

```bash theme={null}
curl -X PATCH https://api.cal.com/v2/teams/123/booking-limit-pools/7 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "perDay": 1 }'
```

Deleting a pool with `DELETE /v2/teams/{teamId}/booking-limit-pools/{poolId}` also deletes the hosts' own limits for it.

### Give one host a different limit

`GET /v2/teams/{teamId}/booking-limit-pools/{poolId}/hosts` lists the pool's rotating hosts, 50 at a time by default (`take` up to 100). Pass `nextCursor` back as `cursor` for the next page.

```bash theme={null}
curl -X PATCH https://api.cal.com/v2/teams/123/booking-limit-pools/7/hosts/456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "hostLimit": { "perWeek": 5 } }'
```

```json theme={null}
{
  "status": "success",
  "data": {
    "userId": 456,
    "hostLimit": { "perDay": null, "perWeek": 5, "perMonth": null, "perYear": null },
    "effectiveLimit": { "perDay": null, "perWeek": 5, "perMonth": null, "perYear": null }
  }
}
```

Only intervals the pool limits can be set, and each is capped at the host's own user booking limit for the same interval. The body nests the intervals under `hostLimit`, matching the response. Send an interval as `null` to return it to the pool's limit, or call `DELETE /v2/teams/{teamId}/booking-limit-pools/{poolId}/hosts/{userId}` to return every interval.

To sync limits from another system, use `PUT /v2/teams/{teamId}/booking-limit-pools/{poolId}/hosts/{userId}` with the same body. It replaces the host's whole limit: any interval you leave out returns to the pool's limit, so sending the same body again changes nothing.

```bash theme={null}
curl -X PUT https://api.cal.com/v2/teams/123/booking-limit-pools/7/hosts/456 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "hostLimit": { "perWeek": 5 } }'
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.